Skip to content

Instantly share code, notes, and snippets.

@ipid
Last active August 13, 2023 09:06
Show Gist options
  • Save ipid/411c1238e5beb1fd77025ac482b2b66c to your computer and use it in GitHub Desktop.
Save ipid/411c1238e5beb1fd77025ac482b2b66c to your computer and use it in GitHub Desktop.
一个生成 eplus 下载列表和 M3U8 的帮助脚本。
/*
使用如下的 aria2 命令行来下载 list.txt 即可:
aria2c --all-proxy http://127.0.0.1:7890 --header="cookie: CloudFront-Key-Pair-Id=OVUEIDT7LTF98UIWPOEZ; CloudFront-Policy=A3JTdGF0TcxffroJKiuiuhoyJnbvT9BYU90juitdfjNibVCf5t678ominh89X19XX9; CloudFront-Signature=Uvoe9cjwf9vn00239n8c83398rfn89w8vne048hgn0revm09e4thg8nvmrp0_; MEMBER_ID=2efce3471928379323r2cew3rfdz; TODOFUKEN_CODE=114514" --input-file=list.txt --max-concurrent-downloads=16 --max-connection-per-server=16 --keep-unfinished-download-result=false --auto-file-renaming=false
然后使用如下的 ffmpeg 命令行来合并 .ts 分片:
ffmpeg -i list.m3u8 -c copy -movflags +faststart out.mp4
*/
import fs from 'node:fs/promises'
// 把分片所属的直播活动 id 号(就是 /v1/ 和 /xxx.ts 之间的部分)更新到这里就可以了
const URL_TEMPLATE = 'https://stream.live.eplus.jp/out/v1/dc7e8d83a50e4173b04466c0696d8227/index_3_{INDEX}.ts?m=1685113453'
// 修改这里设置下载的范围
const DOWNLOAD_LIST_START = 1, DOWNLOAD_LIST_END = 5800
// 修改这里可以设置 m3u8 的分片范围(用于限定彩排的位置等)
// const M3U8_START = DOWNLOAD_LIST_START, M3U8_END = DOWNLOAD_LIST_END
const M3U8_START = 1, M3U8_END = 2331
// const M3U8_START = DOWNLOAD_LIST_START, M3U8_END = DOWNLOAD_LIST_END
function getFileTemplate() {
return URL_TEMPLATE.match(/\/([^/?]+)(\?.*)?$/)[1]
}
function checkTemplate() {
if (!URL_TEMPLATE.includes('{INDEX}')) {
throw new Error('URL_TEMPLATE 里没有加入 {INDEX}')
}
}
async function writeM3U8() {
const file = await fs.open('list.m3u8', 'w')
await file.writeFile('#EXTM3U\n#EXT-X-VERSION:3\n#EXT-X-TARGETDURATION:6\n')
const fileTemplate = getFileTemplate()
for (let i = M3U8_START; i <= M3U8_END; i++) {
const url = fileTemplate.replace('{INDEX}', `${i}`)
await file.writeFile(`#EXTINF:5.0,\n${url}\n`)
}
await file.writeFile('#EXT-X-ENDLIST')
await file.close()
}
async function isFileExist(path) {
try {
const stat = await fs.stat(path)
return stat.size > 0
} catch (e) {
return false
}
}
async function writeDownloadList() {
const file = await fs.open('list.txt', 'w')
const fileTemplate = getFileTemplate()
for (let i = DOWNLOAD_LIST_START; i <= DOWNLOAD_LIST_END; i++) {
// 检测当前要输出的文件是否存在于硬盘上
const fileName = fileTemplate.replace('{INDEX}', `${i}`)
if (await isFileExist(fileName)) {
// 如果文件已经存在,就不往下载列表里输出
continue
}
const url = URL_TEMPLATE.replace('{INDEX}', `${i}`)
await file.writeFile(`${url}\n`)
}
await file.close()
}
checkTemplate()
writeM3U8()
writeDownloadList()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment