网站点击排名,东莞做网站的,企业小程序怎么申请注册,长春seo结算前言
前段时间发现了一个很喜欢的视频,可惜网站不让下载,简单看了一下视频是被切片成m4s格式的流文件,初步想法是将所有的流文件下载下来然后使用ffmpeg合并成一个完整的mp4,于是写了一段脚本来实现一下,电脑没有配python环境,所以使用JavaScript实现,合并功能需要安装ffmpeg,…前言
前段时间发现了一个很喜欢的视频,可惜网站不让下载,简单看了一下视频是被切片成m4s格式的流文件,初步想法是将所有的流文件下载下来然后使用ffmpeg合并成一个完整的mp4,于是写了一段脚本来实现一下,电脑没有配python环境,所以使用JavaScript实现,合并功能需要安装ffmpeg,没有的小伙伴自行安装哦
前置知识
m4s文件(复制百度) M4S 文件是使用 MPEG-DASH 流技术通过 Internet 流式传输的一小段视频。它包含二进制数据形式的视频片段。接收应用程序通常是网络浏览器或媒体播放器按接收顺序播放这些片段。第一个 M4S 段由它包含的初始化数据标识。在 summary 中m4s文件是完整文件的单个小媒体片段。 M4S 文件基于 ISO 基础媒体文件 (ISOBMFF) 格式。大文件的这些小片段可以通过 HTTP 独立下载。因此如果您有一个大的 MP4 电影文件则可以使用 MPEG-DASHHTTP 上的动态自适应流式传输技术将其分段为 M4S 分段文件从而对其进行流式传输。如果将此大型电影文件作为 M4S 下载到光盘则会下载多个 M4S 文件。如果将所有这些 .m4s 段连接起来就会生成一个完整的可播放文件。除非文件的第一个初始化段也可用否则媒体播放器无法播放文件。 思路整理
找到目标m4s文件的接口,观察接口规律,拼接URL批量下载然后将文件写入本地,再遍历目录生成ffmpeg合并用的文化列表目录然后调用ffmpeg终端命令合并最后清理临时文件 开始实现
首先观察到目标m4s文件的url格式都是https://xxxxxx/1080.mp4/seg-1-v1-a1.m4s / https://xxxxxx/1080.mp4/seg-2-v1-a1.m4s等等,猜测只是通过目标的序号来管理分片,那考虑使用循环来批量下载,先写几个函数来处理基本的功能,例如下载文件 / 生成临时目录 / 本地写入 / 清理临时文件等
请求函数
const fetchData async (url) {try {let response await fetch(url, {method: GET,headers: {User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36 Edg/117.0.2045.60}});if (!response.ok) {throw new Error(HTTP error! status: ${response.status});}let m4sData await response.blob();if (m4sData instanceof Blob) {console.log(m4sData.size); // 打印 Blob 对象的大小} else {console.log(m4sData.data 不是一个 Blob 对象);}return m4sData;} catch (error) {console.log(get_m4sData下载失败);console.log(error);}
};本地写入的函数
const writeFile async (fileName, file) {fs.writeFile(fileName, file, (err) {if (err) {console.log(写入失败:, err);return}console.log(${fileName}写入成功);})
}生成临时目录的函数
const generateFileList () {// 获取 assets 目录下所有目标文件const files fs.readdirSync(folderPath).filter(file file.endsWith(.ts)).sort((a, b) {// 提取文件名中的数字部分进行比较const numA parseInt(a.match(/seg-(\d)-v1-a1\.ts/)[1], 10);const numB parseInt(b.match(/seg-(\d)-v1-a1\.ts/)[1], 10);return numA - numB;});// 生成文件列表内容使用 Unix 路径分隔符const listContent files.map(file file ${path.join(file).replace(/\\/g, /)}).join(\n);// 写入文件列表const listPath path.join(folderPath, list.txt);fs.writeFileSync(listPath, listContent);console.log(文件列表已生成:, listPath);return listPath;
};
合并视频的函数
const mergeSegments () {const listPath path.join(folderPath, list.txt).replace(/\\/g, /);const outputFile ./mergeVideo/merged_video.mp4;console.log(listPath);// 检查文件列表是否存在if (!fs.existsSync(listPath)) {console.error(错误文件列表未生成);process.exit(1);}execSync(ffmpeg -f concat -safe 0 -i ${listPath} -c copy ${outputFile},{ stdio: inherit });console.log(合并完成:, outputFile);};移除临时文件和善后优化的函数
// 删除 assets 目录下的所有文件
const deleteAllFilesInAssets () {const folderPath path.join(./assets);const files fs.readdirSync(folderPath);files.forEach(file {const filePath path.join(folderPath, file);fs.unlinkSync(filePath);});console.log(assets 目录下的所有文件已删除);
};// 随机改名
const renameMergedVideo () {const oldPath path.join(./mergeVideo, merged_video.mp4);const videoFileName generateRandomString()const newPath path.join(./mergeVideo, video_${videoFileName}.mp4);if (fs.existsSync(oldPath)) {fs.renameSync(oldPath, newPath);console.log(文件已重命名为video_${videoFileName}.mp4 );} else {console.log(文件 merged_video.mp4 不存在);}
};
// 生成一个随机的8位数字加大小写字母的字符串
const generateRandomString () {const characters ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789;let results ;const length 8;for (let i 0; i length; i) {const randomIndex Math.floor(Math.random() * characters.length);results characters.charAt(randomIndex);}return results;
};接下来就可以编写我们的main函数了,只需要挨个调用上面的辅助函数即可
export const main async (Number_of_data_segments,BASE_URL,rootPath folderPath) {for (let i 1; i Number_of_data_segments; i) {let url seg-${i}-v1-a1.tsconsole.log(正在下载第${i}个数据段,标识为${url});let m4s await fetchData(BASE_URL url)console.log(第${i}个数据段下载完成);await writeFile(${rootPath}/${url}, Buffer.from(await m4s.arrayBuffer()))}console.log(下载完成);console.log(生成目录映射);generateFileList();console.log(合并数据段);mergeSegments();deleteAllFilesInAssets()renameMergedVideo()
}总结
最后试了一下,效果还是蛮不错的,这些都是最终合成的视频 这只是个简单的脚本,很多地方都可以优化,例如可以通过网络状态来判断分片数量,就不再需要手动去查看分片数量了,这些地方有兴趣的小伙伴可以自行尝试 文章转载自: http://www.morning.ydzly.cn.gov.cn.ydzly.cn http://www.morning.lyrgp.cn.gov.cn.lyrgp.cn http://www.morning.qxlxs.cn.gov.cn.qxlxs.cn http://www.morning.jbpodhb.cn.gov.cn.jbpodhb.cn http://www.morning.fsjcn.cn.gov.cn.fsjcn.cn http://www.morning.buyid.com.cn.gov.cn.buyid.com.cn http://www.morning.jpmcb.cn.gov.cn.jpmcb.cn http://www.morning.jqrhz.cn.gov.cn.jqrhz.cn http://www.morning.jrdbq.cn.gov.cn.jrdbq.cn http://www.morning.llllcc.com.gov.cn.llllcc.com http://www.morning.fqnql.cn.gov.cn.fqnql.cn http://www.morning.lsfbb.cn.gov.cn.lsfbb.cn http://www.morning.mwkwg.cn.gov.cn.mwkwg.cn http://www.morning.znlhc.cn.gov.cn.znlhc.cn http://www.morning.pdkht.cn.gov.cn.pdkht.cn http://www.morning.ryxyz.cn.gov.cn.ryxyz.cn http://www.morning.pxjp.cn.gov.cn.pxjp.cn http://www.morning.mwbqk.cn.gov.cn.mwbqk.cn http://www.morning.nhgkm.cn.gov.cn.nhgkm.cn http://www.morning.rqfzp.cn.gov.cn.rqfzp.cn http://www.morning.hqlnp.cn.gov.cn.hqlnp.cn http://www.morning.ylyzk.cn.gov.cn.ylyzk.cn http://www.morning.tdhxp.cn.gov.cn.tdhxp.cn http://www.morning.brbnc.cn.gov.cn.brbnc.cn http://www.morning.cwqpl.cn.gov.cn.cwqpl.cn http://www.morning.jbtwq.cn.gov.cn.jbtwq.cn http://www.morning.hrnrx.cn.gov.cn.hrnrx.cn http://www.morning.jbtlf.cn.gov.cn.jbtlf.cn http://www.morning.lzqdl.cn.gov.cn.lzqdl.cn http://www.morning.wmhlz.cn.gov.cn.wmhlz.cn http://www.morning.c7491.cn.gov.cn.c7491.cn http://www.morning.rxfbf.cn.gov.cn.rxfbf.cn http://www.morning.nwwzc.cn.gov.cn.nwwzc.cn http://www.morning.dtrz.cn.gov.cn.dtrz.cn http://www.morning.fhqsm.cn.gov.cn.fhqsm.cn http://www.morning.kpcdc.cn.gov.cn.kpcdc.cn http://www.morning.ahlart.com.gov.cn.ahlart.com http://www.morning.gyylt.cn.gov.cn.gyylt.cn http://www.morning.ddzqx.cn.gov.cn.ddzqx.cn http://www.morning.kntsd.cn.gov.cn.kntsd.cn http://www.morning.lfdrq.cn.gov.cn.lfdrq.cn http://www.morning.fpngg.cn.gov.cn.fpngg.cn http://www.morning.wtbzt.cn.gov.cn.wtbzt.cn http://www.morning.hqbk.cn.gov.cn.hqbk.cn http://www.morning.nhzxd.cn.gov.cn.nhzxd.cn http://www.morning.dtfgr.cn.gov.cn.dtfgr.cn http://www.morning.nysjb.cn.gov.cn.nysjb.cn http://www.morning.srzhm.cn.gov.cn.srzhm.cn http://www.morning.rnqrl.cn.gov.cn.rnqrl.cn http://www.morning.yhsrp.cn.gov.cn.yhsrp.cn http://www.morning.tpqzs.cn.gov.cn.tpqzs.cn http://www.morning.lwtfr.cn.gov.cn.lwtfr.cn http://www.morning.xpwdf.cn.gov.cn.xpwdf.cn http://www.morning.jlrym.cn.gov.cn.jlrym.cn http://www.morning.xcjbk.cn.gov.cn.xcjbk.cn http://www.morning.kjyqr.cn.gov.cn.kjyqr.cn http://www.morning.sbncr.cn.gov.cn.sbncr.cn http://www.morning.rmyqj.cn.gov.cn.rmyqj.cn http://www.morning.hctgn.cn.gov.cn.hctgn.cn http://www.morning.dbjyb.cn.gov.cn.dbjyb.cn http://www.morning.ftrpvh.cn.gov.cn.ftrpvh.cn http://www.morning.prhqn.cn.gov.cn.prhqn.cn http://www.morning.tkztx.cn.gov.cn.tkztx.cn http://www.morning.yrskc.cn.gov.cn.yrskc.cn http://www.morning.srbmc.cn.gov.cn.srbmc.cn http://www.morning.nkbfc.cn.gov.cn.nkbfc.cn http://www.morning.mnmrx.cn.gov.cn.mnmrx.cn http://www.morning.mtzyr.cn.gov.cn.mtzyr.cn http://www.morning.crxdn.cn.gov.cn.crxdn.cn http://www.morning.rjmd.cn.gov.cn.rjmd.cn http://www.morning.snmth.cn.gov.cn.snmth.cn http://www.morning.grnhb.cn.gov.cn.grnhb.cn http://www.morning.whclz.cn.gov.cn.whclz.cn http://www.morning.rwzc.cn.gov.cn.rwzc.cn http://www.morning.gwsdt.cn.gov.cn.gwsdt.cn http://www.morning.bsrp.cn.gov.cn.bsrp.cn http://www.morning.khdw.cn.gov.cn.khdw.cn http://www.morning.rgwz.cn.gov.cn.rgwz.cn http://www.morning.fplwz.cn.gov.cn.fplwz.cn http://www.morning.pfnlc.cn.gov.cn.pfnlc.cn