@lzwme/m3u8-dl
Version:
Batch download of m3u8 files and convert to mp4
56 lines (55 loc) • 3.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.m3u8Convert = m3u8Convert;
const node_fs_1 = require("node:fs");
const node_path_1 = require("node:path");
const fe_utils_1 = require("@lzwme/fe-utils");
const console_log_colors_1 = require("console-log-colors");
const utils_1 = require("./utils");
async function m3u8Convert(options, data) {
let ffmpegSupport = (0, utils_1.isSupportFfmpeg)();
let filepath = (0, node_path_1.resolve)(options.saveDir, options.filename);
if (!ffmpegSupport)
filepath = filepath.replace(/\.mp4$/, '.ts');
if ((!options.force && (0, node_fs_1.existsSync)(filepath)) || !data.length)
return filepath;
utils_1.logger.info(`Starting ${ffmpegSupport ? 'convert to mp4' : 'merge into ts'} file:`, (0, console_log_colors_1.greenBright)(filepath));
(0, fe_utils_1.mkdirp)((0, node_path_1.dirname)(filepath));
if (ffmpegSupport) {
const ffconcatFile = (0, node_path_1.resolve)((0, node_path_1.dirname)(data[0].tsOut), 'ffconcat.txt');
let filesAllArr = data.filter(d => (0, node_fs_1.existsSync)(d.tsOut)).map(d => `file '${d.tsOut}'\nduration ${d.duration}`);
if (process.platform === 'win32')
filesAllArr = filesAllArr.map(d => d.replaceAll('\\', '/'));
(0, node_fs_1.writeFileSync)(ffconcatFile, `ffconcat version 1.0\n${filesAllArr.join('\n')}`);
let headersString = '';
if (options.headers) {
for (const [key, value] of Object.entries(options.headers)) {
headersString += `-headers "${key}: ${String(value)}" `;
}
}
// ffmpeg -i nz.ts -c copy -map 0:v -map 0:a -bsf:a aac_adtstoasc nz.mp4
// const cmd = `ffmpeg -async 1 -y -f concat -safe 0 -i "${ffconcatFile}" -acodec copy -vcodec copy -bsf:a aac_adtstoasc ${headersString} "${filepath}"`;
const cmd = `ffmpeg -async 1 -y -f concat -safe 0 -i "${ffconcatFile}" -c:v copy -c:a copy -movflags +faststart -fflags +genpts -bsf:a aac_adtstoasc ${headersString} "${filepath}"`;
utils_1.logger.debug('[convert to mp4]cmd:', (0, console_log_colors_1.cyan)(cmd));
const r = (0, fe_utils_1.execSync)(cmd);
ffmpegSupport = !r.error;
if (r.error)
utils_1.logger.error('Conversion to mp4 failed. Please confirm that `ffmpeg` is installed!', r.stderr);
else
(0, node_fs_1.unlinkSync)(ffconcatFile);
}
if (!ffmpegSupport) {
filepath = filepath.replace(/\.mp4$/, '.ts');
const filteWriteStream = (0, node_fs_1.createWriteStream)(filepath);
for (const d of data) {
const err = await new Promise(rs => filteWriteStream.write((0, node_fs_1.readFileSync)(d.tsOut), e => rs(e)));
if (err)
utils_1.logger.error(`Write file failed: ${d.tsOut}`, err);
}
filteWriteStream.end();
}
if (!(0, node_fs_1.existsSync)(filepath))
return '';
utils_1.logger.info(`File saved[${(0, console_log_colors_1.magentaBright)((0, fe_utils_1.formatByteSize)((0, node_fs_1.statSync)(filepath).size))}]:`, (0, console_log_colors_1.greenBright)(filepath));
return filepath;
}