Skip to content

Instantly share code, notes, and snippets.

@Lordfirespeed
Created November 16, 2023 13:39
Show Gist options
  • Save Lordfirespeed/41ff41bb5a6cab47c78514852f0abf6e to your computer and use it in GitHub Desktop.
Save Lordfirespeed/41ff41bb5a6cab47c78514852f0abf6e to your computer and use it in GitHub Desktop.
YouTube PiP Shortcut JS
let url = args.shortcutParameter
let videoWebView = new WebView()
await videoWebView.loadHTML(getHTML())
let videoHandle = videoWebView.present()
let videoId = parseVideoId(url)
let videoBlobUrl = await getVideoBlobURL(videoId)
await videoWebView.evaluateJavaScript(getInjectVideoTag(videoBlobUrl))
await videoWebView.evaluateJavaScript(getPlayJS(), true)
await videoHandle
videoWebView.loadHTML("")
Script.complete()
async function getVideoBlobURL(videoId) {
let webView = new WebView()
let urlToOpen = new URL(`https://youtube.com/embed/${videoId}`)
urlToOpen.searchParams.append("vq", "hd1080")
await webView.loadURL(urlToOpen.toString())
let html = await webView.getHTML()
return html.match("<video(?:.*?)src=\"(.*?)\"(?:.*?)</video>")[1]
}
function parseVideoId(youtubeURL) {
let parsedYoutubeUrl = new URL(youtubeURL)
// https://www.youtube.com/watch?v=[id]
let searchParamId = parsedYoutubeUrl.searchParams.get("v");
if (searchParamId) {
return searchParamId;
}
// https://www.youtube.com/watch/[id]
let pathnameIdMatch = parsedYoutubeUrl.pathname.match("\/video\/(.*)$");
if (pathnameIdMatch) {
return pathnameIdMatch[1];
}
throw new Error("Couldn't parse URL for youtube video ID");
}
function getPlayJS() {
return `
let video = document.getElementsByTagName("video")[0]
video.onplay = function() {
video.webkitSetPresentationMode("picture-in-picture")
completion(null)
}
null // Scriptable needs a simple type at end of function
`
}
function getInjectVideoTag(videoURL) {
return `
document.getElementById("container").innerHTML = "<video controls='controls' class='video-stream' x-webkit-airplay='allow' autoplay playsinline=true src='${videoURL}'></video>"
`
}
function getHTML() {
return `
<html>
<style>
body {
background-color: #000;
}
.container {
align-items: center;
display: flex;
justify-content: center;
height: 100%;
width: 100%;
}
h1 {
font-family: -apple-system;
color: white;
text-align: center;
}
video {
width: 100% !important;
height: auto !important;
}
</style>
<body>
<div class="container" id="container">
<h1>Loading your video. Stay tuned...</h1>
</div>
</body>
</html>
`
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment