node 下载保存M3U8 格式视频
应用到的技术
例如:
- node v16.16.0
- fluent-ffmpeg 2.1.2
- single-line-log 1.1.2
- ffmpeg-installer/ffmpeg 1.1.0
过程
- 安装依赖
npm i fluent-ffmpeg single-line-log @ffmpeg-installer/ffmpeg -S
2.新建文件
m3u8ToMp4.js
/**
* 功能: 下载 M3U8 地址的视频并保存成 MP4 格式
* 说明: 本模块修改自NPM模块 m3u8-to-mp4 , 原模块地址: https://www.npmjs.com/package/m3u8-to-mp4
*
*/
const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
const ffmpeg = require('fluent-ffmpeg');
ffmpeg.setFfmpegPath(ffmpegPath);
// let log = require('single-line-log').stdout;
/**
* A class to convert M3U8 to MP4
* @class
*/
class m3u8ToMp4Converter {
/**
* Sets the input file
* @param {String} filename M3U8 file path. You can use remote URL
* @returns {Function}
*/
setInputFile(filename) {
if (!filename) throw new Error("您必须指定M3U8文件地址");
this.M3U8_FILE = filename;
return this;
}
/**
* Sets the output file
* @param {String} filename Output file path. Has to be local :)
* @returns {Function}
*/
setOutputFile(filename) {
if (!filename) throw new Error("您必须指定文件路径和名称");
this.OUTPUT_FILE = filename;
return this;
}
/**
* Starts the process
*/
start() {
return new Promise((resolve, reject) => {
if (!this.M3U8_FILE || !this.OUTPUT_FILE) {
reject(new Error("您必须指定输入和输出文件"));
return;
}
console.log('=========================');
console.log(this.OUTPUT_FILE,'文件名')
ffmpeg(this.M3U8_FILE)
.on("error", error => {
reject(new Error(error));
})
.on('progress', function(progress) {
console.log(progress,'progress')
console.log('下载进度: 已完成 ' + progress.timemark + '%。');
})
.on("end", () => {
console.log('下载进度: 已完成 100%。\n');
console.log('=========================');
resolve();
})
.outputOptions("-c copy")
.outputOptions("-bsf:a aac_adtstoasc")
.output(this.OUTPUT_FILE)
.run();
});
}
}
module.exports = m3u8ToMp4Converter;
dlMovie.js
const fs = require("fs");
const path = require("path");
const m3u8ToMp4 = require("./m3u8ToMp4.js"); // 引入核心模块,注意路径
const converter = new m3u8ToMp4();
// 具体参数可自行修改
downloadMedia('video');
function downloadMedia (opt, callback) {
// 测试视频,如果链接失效的话就自己找一个
let url = opt.url || "https://9.thehanju.com/file/taiju01/pics/2023/6/19/uQINGJ93/playlista.m3u8";
let output = opt.output || 'video';
let filename = 'video.mp4' || 'video.mp4';
let title = opt.title || '测试视频';
if (!fs.existsSync(output)) {
fs.mkdirSync(output, {
recursive: true,
});
}
(async function() {
try {
console.log("准备下载...");
await converter
.setInputFile(url)
.setOutputFile(path.join(output, filename))
.start();
console.log("下载完成!");
if ( typeof callback === 'function' ) callback();
} catch (error) {
throw new Error("哎呀,出错啦! 检查一下参数传对了没喔。", error);
}
})();
}
3.运行命令 node dlMovie.js