如何为HLS视频分段设置起始时间?基于FFmpeg muxing.c示例的咨询
调整FFmpeg muxing.c示例输出TS文件的起始时间
嘿,我对FFmpeg的封装流程摸得挺熟,这就给你讲清楚怎么修改muxing.c代码,让输出的TS文件起始时间不再是0.000000~
核心思路:设置输出流的start_time并同步数据包时间戳
TS容器的起始时间本质由输出流的start_time参数决定,同时要确保所有输出数据包的PTS/DTS和这个起始时间对齐,避免FFmpeg自动修正回0。
具体代码修改步骤
- 设置输出流的起始时间
在muxing.c中,当你创建好输出流(调用avformat_new_stream之后),直接给流的start_time赋值。注意必须用FFmpeg的时间基转换工具,避免时间戳单位不匹配:
// 假设你想要的起始时间是10秒(可自行修改) int64_t desired_start_sec = 10; // 将秒转换为FFmpeg内部微秒时间单位 int64_t start_time_us = desired_start_sec * AV_TIME_BASE; // 转换为输出流的时间基(TS流通常是1/90000) out_stream->start_time = av_rescale_q(start_time_us, AV_TIME_BASE_Q, out_stream->time_base);
- 同步数据包的时间戳(针对从输入流复制的场景)
如果你的muxing流程是从输入流复制数据包,需要调整每个数据包的PTS/DTS,让它们基于新的起始时间:
// 在处理输入数据包的逻辑中(比如read_frame之后) // 先将输入数据包的时间戳转换为输出流的时间基 packet.pts = av_rescale_q(packet.pts, in_stream->time_base, out_stream->time_base); packet.dts = av_rescale_q(packet.dts, in_stream->time_base, out_stream->time_base); // 计算时间偏移量:让第一个数据包的PTS对齐我们设置的start_time static int64_t time_offset = -1; if (time_offset == -1) { time_offset = out_stream->start_time - packet.pts; } // 给所有数据包的时间戳加上偏移 packet.pts += time_offset; packet.dts += time_offset; // 别忘了调整数据包的duration packet.duration = av_rescale_q(packet.duration, in_stream->time_base, out_stream->time_base);
- 自定义生成数据包的场景
如果是自己生成视频/音频帧(比如合成测试流),直接从设置的起始时间开始计算PTS/DTS即可:
// 假设每帧的时长是frame_duration(输出流时间基下的单位) int64_t current_pts = out_stream->start_time; for (...) { // 给当前帧设置PTS/DTS frame->pts = current_pts; // 编码后写入数据包 // ... // 累加时长 current_pts += frame_duration; }
验证是否生效
修改完代码编译后,用ffprobe命令检查输出TS文件的起始时间:
ffprobe -show_format -show_streams your_output.ts
在输出结果中,你会看到start_time字段变成了你设置的数值(注意TS容器的时间戳单位通常是微秒或1/90000秒,需要转换验证)。
内容的提问来源于stack exchange,提问作者Yuriy Pryyma
相关产品推荐
相关产品推荐

