UNPKG

@lzwme/m3u8-dl

Version:

Batch download of m3u8 files and convert to mp4

56 lines (55 loc) 3.2 kB
"use strict"; 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; }