@lzwme/m3u8-dl
Version:
Batch download of m3u8 files and convert to mp4
82 lines (81 loc) • 3.06 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseM3U8 = parseM3U8;
const node_fs_1 = require("node:fs");
const node_path_1 = require("node:path");
const m3u8_parser_1 = require("m3u8-parser");
const utils_1 = require("./utils");
async function parseM3U8(content, url = process.cwd(), cacheDir = './cache') {
if (!content && url) {
if (!url.startsWith('http') && (0, node_fs_1.existsSync)(url)) {
url = (0, node_path_1.resolve)(process.cwd(), url);
content = await node_fs_1.promises.readFile(url, 'utf8');
}
else {
content = (await (0, utils_1.getRetry)(url)).data;
}
}
if (!content) {
utils_1.logger.error('获取播放列表为空!', url);
}
utils_1.logger.debug('starting parsing m3u8 file:', url);
let parser = new m3u8_parser_1.Parser();
parser.push(content);
parser.end();
utils_1.logger.debug('parser.manifest', parser.manifest);
if (parser.manifest.playlists?.length > 0) {
url = new URL(parser.manifest.playlists[0].uri, url).toString();
content = (await (0, utils_1.getRetry)(url)).data;
parser = new m3u8_parser_1.Parser();
parser.push(content);
parser.end();
}
const tsList = parser.manifest.segments || [];
const result = {
manifest: parser.manifest,
/** ts 文件数量 */
tsCount: tsList.length,
/** 总时长 */
durationSecond: 0,
data: [],
/** 加密相关信息 */
crypto: {
method: 'AES-128',
iv: new Uint8Array(16),
key: '',
uri: '',
},
};
if (!result.tsCount) {
utils_1.logger.error('m3u8 file error!\n', url, content);
return result;
}
const tsKeyInfo = tsList[0].key;
if (tsKeyInfo?.uri) {
if (tsKeyInfo.method)
result.crypto.method = tsKeyInfo.method.toUpperCase();
if (tsKeyInfo.iv) {
result.crypto.iv = typeof tsKeyInfo.iv === 'string' ? new Uint8Array(Buffer.from(tsKeyInfo.iv)) : tsKeyInfo.iv;
}
result.crypto.uri = tsKeyInfo.uri.includes('://') ? tsKeyInfo.uri : new URL(tsKeyInfo.uri, url).toString();
}
if (result.crypto.uri !== '') {
const r = await (0, utils_1.getRetry)(result.crypto.uri);
result.crypto.key = r.buffer;
}
for (let i = 0; i < result.tsCount; i++) {
if (!tsList[i].uri.startsWith('http'))
tsList[i].uri = new URL(tsList[i].uri, url).toString();
result.data.push({
index: i,
duration: tsList[i].duration,
timeline: tsList[i].timeline,
uri: tsList[i].uri,
tsOut: `${cacheDir}/${i}-${(0, node_path_1.basename)(tsList[i].uri).replace(/\.ts\?.+/, '.ts')}`,
});
result.durationSecond += tsList[i].duration;
}
result.durationSecond = +Number(result.durationSecond).toFixed(2);
return result;
}
// parseM3U8('', 't.m3u8').then(d => console.log(d));
;