为了在视频列表循环播放时实现无缝切换,需要确保FFmpeg处理时间戳连续并避免断流。以下是修改后的代码和解决方案:
步骤说明:
- 生成连续的时间戳:通过添加
-fflags +genpts
生成新的演示时间戳,确保每个视频的起始时间戳连续。 - 避免负时间戳:使用
-avoid_negative_ts make_zero
防止负时间戳导致的问题。 - 同步参数:添加
-vsync 1
确保视频帧率同步,减少时间戳跳跃的可能性。 - 优化输入缓冲:调整
-analyzeduration
和-probesize
以快速处理输入文件,减少潜在的延迟。
修改后的代码:
import os import re import subprocess import time push_url = "rtmp://hs.direct.huya.com/huyalive/1421062948-1421062948-7186153431630092275-3334728798-10057-A-1673156737-1?seq=1746109518777&type=simple" video_dir = "/mnt/samba/kplayer/video" def natural_sort_key(s): """自然排序函数用于文件名排序""" numbers = [int(text) for text in re.findall(r'\d+', s)] return numbers[0] if numbers else float('inf') def generate_playlist(): """生成最新的播放列表并返回文件列表""" video_list = sorted(os.listdir(video_dir), key=natural_sort_key) with open("playlist.txt", "w") as f: for video in video_list: video_path = os.path.join(video_dir, video) f.write(f"file '{video_path}'\n") return video_list def main(): while True: video_list = generate_playlist() if not video_list: print("未找到视频文件,等待重试...") time.sleep(5) continue # 构建优化的FFmpeg命令 cmd = [ "ffmpeg", "-re", "-stream_loop", "-1", "-f", "concat", "-safe", "0", "-fflags", "+genpts", # 生成连续的时间戳 "-avoid_negative_ts", "make_zero", # 处理负时间戳 "-vsync", "1", # 同步视频帧率 "-analyzeduration", "2147483647", "-probesize", "2147483647", # 确保快速解析输入 "-i", "playlist.txt", "-vcodec", "copy", "-acodec", "aac", "-b:a", "128k", "-ar", "44100", "-ac", "2", "-f", "flv", push_url ] try: process = subprocess.Popen( cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True ) # 实时输出日志并监控关键错误 while True: output = process.stdout.readline() if output == '' and process.poll() is not None: break if output: print(output.strip()) # 检测到时间戳重置时主动重启 if "Non-monotonic DTS" in output: print("检测到时间戳异常,主动重启...") process.terminate() break print("FFmpeg进程终止,准备重启...") time.sleep(1) except Exception as e: print(f"发生错误: {str(e)}") time.sleep(5) if __name__ == "__main__": main()
关键修改说明:
- 时间戳处理:通过
-fflags +genpts
和-avoid_negative_ts
确保时间戳连续,防止播放器因时间戳跳跃断开连接。 - 同步与缓冲优化:调整参数以减少解析延迟,避免切换时的缓冲不足。
- 主动错误监控:检测到关键错误(如时间戳异常)时主动重启FFmpeg,提高稳定性。
注意事项:
- 视频格式统一:确保所有视频的分辨率、编码格式、帧率等参数完全一致,避免因格式不匹配导致的问题。
- 日志监控:关注FFmpeg输出的
Non-monotonic DTS
等警告,及时处理异常视频文件。 - 性能测试:在高负载下测试推流稳定性,必要时可调整音频转码参数(如降低码率)以降低CPU使用率。
如果问题仍未解决,建议将所有视频预先转码为相同参数(包括固定帧率),并考虑使用x264
编码器的-preset ultrafast
参数降低转码延迟。