FFmpeg处理时间戳连续并避免断流

为了在视频列表循环播放时实现无缝切换,需要确保FFmpeg处理时间戳连续并避免断流。以下是修改后的代码和解决方案:

步骤说明:​

  1. 生成连续的时间戳​:通过添加-fflags +genpts生成新的演示时间戳,确保每个视频的起始时间戳连续。
  2. 避免负时间戳​:使用-avoid_negative_ts make_zero防止负时间戳导致的问题。
  3. 同步参数​:添加-vsync 1确保视频帧率同步,减少时间戳跳跃的可能性。
  4. 优化输入缓冲​:调整-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,提高稳定性。

注意事项:​

  1. 视频格式统一​:确保所有视频的分辨率、编码格式、帧率等参数完全一致,避免因格式不匹配导致的问题。
  2. 日志监控​:关注FFmpeg输出的Non-monotonic DTS等警告,及时处理异常视频文件。
  3. 性能测试​:在高负载下测试推流稳定性,必要时可调整音频转码参数(如降低码率)以降低CPU使用率。

如果问题仍未解决,建议将所有视频预先转码为相同参数(包括固定帧率),并考虑使用x264编码器的-preset ultrafast参数降低转码延迟。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
下一篇