Created
July 14, 2024 02:37
-
-
Save wlib/0874b8bfe2efefe6edcfeb7cfd70e925 to your computer and use it in GitHub Desktop.
From an m3u8 video stream link, download a zip file that contains the ts stream chunks and a index.txt that can be used with ffmpeg
This file contains 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
const sourceUrl = "https://m3u8-0.c-spanvideo.org/clip/clip.5081597.576.tsc.m3u8" | |
const source = await fetch(sourceUrl) | |
.then(res => res.ok ? res.text() : undefined) | |
if (!source) | |
throw new Error("it's over") | |
const tsBlobs = await Promise.all( | |
source | |
.split("\n") | |
.flatMap(line => { | |
const trimmed = line.trim() | |
if (trimmed.startsWith("#")) | |
return [] | |
try { | |
return [new URL(trimmed, sourceUrl)] | |
} | |
catch { | |
return [] | |
} | |
}) | |
.filter(url => url.pathname.endsWith(".ts")) | |
.map(url => | |
fetch(url).then(res => { | |
if (!res.ok) | |
throw new Error("Failed to download", url) | |
return res.blob() | |
}) | |
) | |
) | |
const tsByteArrays = await Promise.all( | |
tsBlobs.map(async blob => new Uint8Array(await blob.arrayBuffer())) | |
) | |
const { zip } = await import("https://esm.sh/[email protected]") | |
const indexFile = tsBlobs.map((blob, i) => `file 'chunks/${i}.ts'`).join("\n") | |
const zipFile = await new Promise(async (resolve, reject) => { | |
zip( | |
{ | |
"index.txt": new TextEncoder().encode(indexFile), | |
chunks: Object.fromEntries( | |
tsByteArrays.map((byteArray, i) => [`${i}.ts`, byteArray]) | |
) | |
}, | |
{ level: 0 }, | |
(error, data) => { | |
if (error) | |
reject(error) | |
else | |
resolve(data) | |
} | |
) | |
}) | |
const downloadLink = document.createElement("a") | |
downloadLink.href = URL.createObjectURL( | |
new Blob([zipFile], { type: "application/zip" }) | |
) | |
downloadLink.download = "video-source.zip" | |
downloadLink.click() | |
console.log("cd Downloads/video-source") | |
console.log("ffmpeg -f concat -i index.txt -c copy video.mp4") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment