Created
July 12, 2022 01:36
vids.io download helper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name vids.io download helper | |
| // @match https://vids.io/videos/* | |
| // @match https://*.vids.io/videos/* | |
| // @grant none | |
| // @version 1.0 | |
| // ==/UserScript== | |
| //this userscript will do most of the work when you want to dl a video from vids.io | |
| //all you have to do is download the m3u8 data through something like ffmpeg (youtube-dl didn't work for me), e.g. using the command shown below the DL button | |
| async function main(){ | |
| const videoIframe = document.querySelector(".sproutvideo-player"); | |
| if(!videoIframe) | |
| return; | |
| const videoIframeHtml = await (await fetch(videoIframe.src)).text(); | |
| const videoIframeDoc = new DOMParser().parseFromString(videoIframeHtml, "text/html"); | |
| const videoDataElement = [...videoIframeDoc.head.childNodes].find(e => e.innerText?.startsWith("var dat = 'ey")); | |
| const videoDataBase64 = videoDataElement.innerText.match(/var dat = '([a-zA-Z0-9\+\/\=]+)';/)[1]; | |
| const videoData = JSON.parse(atob(videoDataBase64)); | |
| const indexM3u8 = `https://hls2.videos.sproutvideo.com/${videoData.s3_user_hash}/${videoData.s3_video_hash}/video/index.m3u8?Policy=${videoData.signatures.m["CloudFront-Policy"]}&Signature=${videoData.signatures.m["CloudFront-Signature"]}&Key-Pair-Id=${videoData.signatures.m["CloudFront-Key-Pair-Id"]}&sessionID=${videoData.sessionID}`; | |
| const qualities = (await (await fetch(indexM3u8)).text()).match(/[0-9]+.m3u8/g); | |
| const bestQuality = qualities[qualities.length - 1]; | |
| const videoM3u8 = `https://hls2.videos.sproutvideo.com/${videoData.s3_user_hash}/${videoData.s3_video_hash}/video/${bestQuality}?Policy=${videoData.signatures.m["CloudFront-Policy"]}&Signature=${videoData.signatures.m["CloudFront-Signature"]}&Key-Pair-Id=${videoData.signatures.m["CloudFront-Key-Pair-Id"]}&sessionID=${videoData.sessionID}`; | |
| let videoM3u8Data = (await (await fetch(videoM3u8)).text()); | |
| //replace key with full url | |
| videoM3u8Data = videoM3u8Data.replace(/URI=\"[0-9]+.key\"/, `URI=\"https://hls2.videos.sproutvideo.com/${videoData.s3_user_hash}/${videoData.s3_video_hash}/video/${bestQuality.replace(".m3u8", ".key")}?Policy=${videoData.signatures.k["CloudFront-Policy"]}&Signature=${videoData.signatures.k["CloudFront-Signature"]}&Key-Pair-Id=${videoData.signatures.k["CloudFront-Key-Pair-Id"]}&sessionID=${videoData.sessionID}\"`); | |
| //replace .ts files with full url | |
| videoM3u8Data = videoM3u8Data.replace(/[0-9]+_[0-9]+.ts/g, `https://hls2.videos.sproutvideo.com/${videoData.s3_user_hash}/${videoData.s3_video_hash}/video/$&?Policy=${videoData.signatures.t["CloudFront-Policy"]}&Signature=${videoData.signatures.t["CloudFront-Signature"]}&Key-Pair-Id=${videoData.signatures.t["CloudFront-Key-Pair-Id"]}&sessionID=${videoData.sessionID}`); | |
| const filename = document.querySelector(".video-title h1").innerText.replace(/[^a-z0-9]/gi, "_"); | |
| const dlElement = document.createElement("a"); | |
| dlElement.href = window.URL.createObjectURL(new Blob([videoM3u8Data], {type: "application/x-mpegURL"})); | |
| dlElement.download = `${filename}.m3u8`; | |
| dlElement.innerText = "Click to download"; | |
| dlElement.style = "display: flex;justify-content: center;height: 40px;font-weight: bold;background: #9234f0;width: 200px;color: white;align-items: center;margin: auto;margin-bottom: 20px;"; | |
| document.querySelector(".video-info").appendChild(dlElement); | |
| const infoElement = document.createElement("div"); | |
| infoElement.style = "display: flex;justify-content: center;"; | |
| const infoTextElement = document.createElement("span"); | |
| infoTextElement.innerHTML = "What to do next:<br><br>" + | |
| "DL m3u8 using ffmpeg:<br>" + | |
| `<b style=\"font-weight: bold;\">ffmpeg -protocol_whitelist file,http,https,tcp,tls,crypto -i "${filename}.m3u8" "${filename}.mp4"<b>`; | |
| infoElement.appendChild(infoTextElement); | |
| document.querySelector(".video-info").appendChild(infoElement); | |
| } | |
| main(); |
Update to fix recent changes:
// ==UserScript==
// @name vids.io download helper
// @match https://vids.io/videos/*
// @match https://*.vids.io/videos/*
// @grant none
// @version 1.0
// ==/UserScript==
//this userscript will do most of the work when you want to dl a video from vids.io
//all you have to do is download the m3u8 data through something like ffmpeg (youtube-dl didn't work for me), e.g. using the command shown below the DL button
async function main(){
const videoIframe = document.querySelector(".sproutvideo-player");
if(!videoIframe) { return }
const videoIframeHtml = await (await fetch(videoIframe.src)).text();
const videoIframeDoc = new DOMParser().parseFromString(videoIframeHtml, "text/html");
const videoDataElement = [...videoIframeDoc.head.childNodes].find(e => e.innerText?.startsWith("const videoInfo ="));
const videoDataBase64 = videoDataElement.innerText.match(/const videoInfo = '([a-zA-Z0-9\+\/\=]+)';/)[1];
const videoData = JSON.parse(atob(videoDataBase64));
const indexM3u8 = `https://hls2.videos.sproutvideo.com/${videoData.s3_user_hash}/${videoData.s3_video_hash}/video/index.m3u8?Policy=${videoData.signatures.m["CloudFront-Policy"]}&Signature=${videoData.signatures.m["CloudFront-Signature"]}&Key-Pair-Id=${videoData.signatures.m["CloudFront-Key-Pair-Id"]}&sessionID=${videoData.sessionID}`;
const qualities = (await (await fetch(indexM3u8)).text()).match(/[0-9]+.m3u8/g);
const bestQuality = qualities[qualities.length - 1];
const videoM3u8 = `https://hls2.videos.sproutvideo.com/${videoData.s3_user_hash}/${videoData.s3_video_hash}/video/${bestQuality}?Policy=${videoData.signatures.m["CloudFront-Policy"]}&Signature=${videoData.signatures.m["CloudFront-Signature"]}&Key-Pair-Id=${videoData.signatures.m["CloudFront-Key-Pair-Id"]}&sessionID=${videoData.sessionID}`;
let videoM3u8Data = (await (await fetch(videoM3u8)).text());
//replace key with full url
videoM3u8Data = videoM3u8Data.replace(/URI=\"[0-9]+.key\"/, `URI=\"https://hls2.videos.sproutvideo.com/${videoData.s3_user_hash}/${videoData.s3_video_hash}/video/${bestQuality.replace(".m3u8", ".key")}?Policy=${videoData.signatures.k["CloudFront-Policy"]}&Signature=${videoData.signatures.k["CloudFront-Signature"]}&Key-Pair-Id=${videoData.signatures.k["CloudFront-Key-Pair-Id"]}&sessionID=${videoData.sessionID}\"`);
//replace .ts files with full url
videoM3u8Data = videoM3u8Data.replace(/[0-9]+_[0-9]+.ts/g, `https://hls2.videos.sproutvideo.com/${videoData.s3_user_hash}/${videoData.s3_video_hash}/video/$&?Policy=${videoData.signatures.t["CloudFront-Policy"]}&Signature=${videoData.signatures.t["CloudFront-Signature"]}&Key-Pair-Id=${videoData.signatures.t["CloudFront-Key-Pair-Id"]}&sessionID=${videoData.sessionID}`);
const filename = document.querySelector(".video-title h2").innerText.replace(/[^a-z0-9]/gi, "_");
const dlElement = document.createElement("a");
dlElement.href = window.URL.createObjectURL(new Blob([videoM3u8Data], {type: "application/x-mpegURL"}));
dlElement.download = `${filename}.m3u8`;
dlElement.innerText = "Click to download";
dlElement.style = "display: flex;justify-content: center;height: 40px;font-weight: bold;background: #9234f0;width: 200px;color: white;align-items: center;margin: auto;margin-bottom: 20px;";
document.querySelector(".video-info").appendChild(dlElement);
const infoElement = document.createElement("div");
infoElement.style = "display: flex;justify-content: center;";
const infoTextElement = document.createElement("span");
infoTextElement.innerHTML = "What to do next:<br><br>" +
"DL m3u8 using ffmpeg:<br>" +
`<b style=\"font-weight: bold;\">ffmpeg -protocol_whitelist file,http,https,tcp,tls,crypto -i "${filename}.m3u8" "${filename}.mp4"<b>`;
infoElement.appendChild(infoTextElement);
document.querySelector(".video-info").appendChild(infoElement);
}
main();
It worked for a while and now it stopped. Any update?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
How to use it ?