FFmpeg转码HLS时分段文件名无法递增的解决咨询
解决FFmpeg HLS分段文件名无法递增的问题
核心问题排查与解决方案
你的问题大概率不是%d/%03d占位符本身的问题,而是目录未预创建、参数顺序错误或多流输出的参数绑定逻辑没搞对,以下是具体解决步骤:
1. 必须提前创建目标目录
FFmpeg不会自动生成输出目录,如果v0/v1/v2/v3文件夹不存在,FFmpeg无法写入分段文件,会直接报错(看起来像是文件名不递增的问题,但本质是路径不可写)。
用Node.js提前创建目录(以同步创建为例):
const fs = require('fs'); const path = require('path'); // 批量创建v0-v3目录 ['v0', 'v1', 'v2', 'v3'].forEach(dir => { const dirPath = path.resolve(__dirname, dir); if (!fs.existsSync(dirPath)) { fs.mkdirSync(dirPath, { recursive: true }); } });
2. 修正FFmpeg参数结构
多分辨率HLS输出需要用-filter_complex拆分流,并且每个输出的HLS参数必须紧跟在该输出的映射规则之后、输出路径之前,否则参数会被错误绑定到其他流,导致分段文件名失效。
正确的spawn参数示例:
const { spawn } = require('child_process'); const inputPath = './input.mp4'; // 你的输入视频路径 const ffmpegArgs = [ '-i', inputPath, // 拆分视频流并缩放为4种分辨率 '-filter_complex', `[0:v]split=4[v0][v1][v2][v3];` + `[v0]scale=480:270[v0out];` + // 480p `[v1]scale=720:405[v1out];` + // 720p `[v2]scale=1280:720[v2out];` + // 1080p `[v3]scale=1920:1080[v3out]`, // 输出v0(480p)的HLS流 '-map', '[v0out]', '-map', '0:a', '-c:v', 'libx264', '-c:a', 'aac', '-hls_segment_filename', 'v0/fileSequence%03d.ts', '-hls_playlist_type', 'vod', 'v0/prog_index.m3u8', // 输出v1(720p)的HLS流 '-map', '[v1out]', '-map', '0:a', '-c:v', 'libx264', '-c:a', 'aac', '-hls_segment_filename', 'v1/fileSequence%03d.ts', '-hls_playlist_type', 'vod', 'v1/prog_index.m3u8', // 输出v2(1080p)的HLS流 '-map', '[v2out]', '-map', '0:a', '-c:v', 'libx264', '-c:a', 'aac', '-hls_segment_filename', 'v2/fileSequence%03d.ts', '-hls_playlist_type', 'vod', 'v2/prog_index.m3u8', // 输出v3(4K)的HLS流 '-map', '[v3out]', '-map', '0:a', '-c:v', 'libx264', '-c:a', 'aac', '-hls_segment_filename', 'v3/fileSequence%03d.ts', '-hls_playlist_type', 'vod', 'v3/prog_index.m3u8', // 生成主播放列表master.m3u8 '-master_pl_name', 'master.m3u8', '-var_stream_map', 'v:0,a:0 v:1,a:1 v:2,a:2 v:3,a:3' ]; // 启动FFmpeg进程 const ffmpegProcess = spawn('ffmpeg', ffmpegArgs); // 捕获错误输出(关键!用来排查问题) ffmpegProcess.stderr.on('data', (data) => { console.error(`FFmpeg错误信息: ${data.toString()}`); }); ffmpegProcess.on('close', (code) => { console.log(`转码完成,退出码: ${code}`); });
3. 关键注意事项
- 参数顺序绝对不能乱:
-hls_segment_filename必须放在对应输出的-map之后、输出路径(比如v0/prog_index.m3u8)之前,FFmpeg会按顺序将参数绑定到最近的输出。 - 占位符格式正确:
%03d会生成三位数的递增序号(比如fileSequence001.ts、fileSequence002.ts),%d则是无补零的序号,两种格式都是有效的,只要路径正确就会正常生成。 - 检查权限:确保Node.js进程对当前目录有读写权限,避免因权限不足导致无法写入文件。
- 查看错误日志:如果还是失败,一定要打印FFmpeg的
stderr输出,里面会明确说明错误原因(比如"No such file or directory"就是目录没创建)。
内容的提问来源于stack exchange,提问作者Rakesh L
相关产品推荐
相关产品推荐

