Last active
April 1, 2024 13:13
-
-
Save Maxim-Mazurok/b33271b3b72b60ff0f900c67033ff74e to your computer and use it in GitHub Desktop.
Private Vimeo / Akamai CDN long video downloader
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
// NOTE: you might have to run it a few times if it doesn't download the full video from the first try, I guess it needs to be cached or something.. | |
const { appendFileSync, writeFileSync } = require("fs"); | |
const https = require("https"); | |
// find that URL in devtools, search for akamai, there's also manifest with different names based on quality (remove &range from it) | |
const URL = `https://xxxxx-adaptive.akamaized.net/exp=0000000000~xxx=xxxxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxxxxxxxx~xxxx=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/parcel/video/xxxxxxxx.mp4?r=xxxxxxxxxxxxxxxxxx`; | |
const rangeWidth = 1000000000; // using smaller range will be slower, but might result in more stable/reliable download success | |
let foundEnd = false; | |
let currentStart = 0; | |
let gotData = 0; | |
const fileName = "video.mp4"; | |
currentStart === 0 && writeFileSync(fileName, ""); | |
let data = []; | |
const getNextChunk = () => { | |
const currentUrl = `${URL}&range=${currentStart}-${currentStart + rangeWidth}`; | |
console.log(currentUrl); | |
const request = https.get(currentUrl, (response) => { | |
data = []; | |
if (response.statusCode !== 200) { | |
console.log({ statusCode: response.statusCode }); | |
foundEnd = true; | |
process.exit(); | |
} | |
response.on("data", (chunk) => { | |
gotData++; | |
gotData % 1000 === 1 && console.log("got data", chunk); | |
data.push(chunk); | |
}); | |
response.on("end", () => { | |
console.log("end of chunk"); | |
for (const datum of data) { | |
appendFileSync(fileName, datum); | |
} | |
if (!foundEnd) { | |
currentStart += rangeWidth + 1; | |
getNextChunk(); | |
} | |
}); | |
response.on("close", (x) => console.log("close", x)); | |
response.on("error", (x) => console.log("error", x)); | |
response.on("pause", (x) => console.log("pause", x)); | |
}); | |
request.on("error", (error) => { | |
console.error("found error/end", error); | |
foundEnd = true; | |
}); | |
}; | |
getNextChunk(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Also if it fails with connection reset - see last URL in log and change
currentStart
to the starting range from the last URL that was unsuccessful.