gpt4 book ai didi

video - 将 HLS M3U8 转换为 MP4 后,如何找出是否缺少 TS 段?

转载 作者:行者123 更新时间:2023-12-04 22:48:59 29 4
gpt4 key购买 nike

我有几个.ts文件和相应的index.m3u8看起来像这样的文件:

#EXTM3U
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:15
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:1
#EXTINF:3.170,
seg-1-v1-a1.ts
#EXTINF:3.170,
seg-2-v1-a1.ts
#EXTINF:3.170,
seg-3-v1-a1.ts
#EXTINF:3.170,
seg-4-v1-a1.ts
#EXTINF:3.170,
seg-5-v1-a1.ts
#EXT-X-ENDLIST
因此,将其转换为单个 output.mp4文件,我运行了以下命令:
$ ffmpeg -i index.m3u8 -c copy output.mp4
...
[hls @ 0x55d78a3a6280] Opening 'seg-1-v1-a1.ts' for reading
...
[hls @ 0x55d78a3a6280] Opening 'seg-2-v1-a1.ts' for reading
[hls @ 0x55d78a3a6280] Opening 'seg-3-v1-a1.ts' for reading
[hls @ 0x55d78a3a6280] Opening 'seg-4-v1-a1.ts' for reading
[hls @ 0x55d78a3a6280] Opening 'seg-5-v1-a1.ts' for reading
...
之后,我删除了 .ts文件和 index.m3u8并保留 output.mp4 .然而,事实证明,我没有所有 .ts文件和输出最初更像是这样的:
$ rm seg-3-v1-a1.ts
$ ffmpeg -i index.m3u8 -c copy output.mp4
...
[hls @ 0x5555d0d86280] Opening 'seg-1-v1-a1.ts' for reading
...
[hls @ 0x5555d0d86280] Opening 'seg-2-v1-a1.ts' for reading
[hls @ 0x5555d0d86280] Opening 'seg-3-v1-a1.ts' for reading
[hls @ 0x5555d0d86280] Failed to open segment 3 of playlist 0
[hls @ 0x5555d0d86280] Opening 'seg-4-v1-a1.ts' for reading
[hls @ 0x5555d0d86280] Opening 'seg-5-v1-a1.ts' for reading
...
观看视频时,在缺失片段的位置,画面卡住几秒钟,然后视频继续播放。我有几个 .mp4文件,我想找出其中哪些受此问题的影响。在没有原始日志的情况下,我如何在运行 ffmpeg -i index.m3u8 -c copy output.mp4 时找出是否缺少任何段?命令?
我在 https://superuser.com/questions/100288/how-can-i-check-the-integrity-of-a-video-file-avi-mpeg-mp4 找到了一个命令不幸的是没有发现任何问题:
$ ffmpeg -v error -i output.mp4 -f null -
$ echo $?
0

最佳答案

您可以检查 r_frame_rate 和 avg_frame_rate 是否相等。
下面的命令:

ffprobe -v error -show_streams output.mp4 | grep "frame_rate"
将输出(对于正确的文件)是这样的:

r_frame_rate=24/1
avg_frame_rate=24/1


和(对于损坏的文件)是这样的:

r_frame_rate=24/1
avg_frame_rate=886/37


这种方法并不完美,但在很多情况下应该完全没问题。

第二种方法,直观且在我看来仅在特定条件下工作,正在寻找卡住。例如:
ffmpeg -i output.mp4 -vf "freezedetect=n=-60dB:d=2" -f null - 1>/dev/null 2>&1 \
| grep "duration"
它可以工作,但前提是流确实是特定的。

另一种方法,类似于第一种方法,是寻找 VFR。
命令:
ffmpeg -i output.mp4 -vf vfrdet -an -f null -
将输出:

[Parsed_vfrdet_0 @ 0x55563547bf00] VFR:0.000094 (2/21261) min: 3750 max: 183750 avg: 93750


对于损坏的文件。为了正确,它将是:

[Parsed_vfrdet_0 @ 0x564c33d53140] VFR:0.000000 (0/21311)


这与第一种方法相似,但与外表相反——不同!
据我所知, r_frame_rate 可能相等和 avg_frame_rate ,而 VFR 不为零!
在我看来,检查 VFR 是最好的选择,并且可能会奏效。很糟糕,您没有提供任何示例文件。我假设您的流应该有 VFR:0.000000,但那是在阅读茶叶。
据我所知,没有通用的方法可以满足您的需求。我希望我的任何示例都适合,但它确实取决于并且需要在实践中在正确的文件上进行测试。正是这些,您要检查。

根据您在我的回答下方的回复,我已经实现了简单的脚本:
  • 下载ts文件
  • 将这些转换为正确的 mp4
  • 损坏 ts 文件之一
  • 将这些(缺少 ts 文件)转换为损坏的 mp4
  • 使用我的第一种方法测试每个 mp4 文件(比较 r_frame_rate == avg_frame_rate)

  • #!/usr/bin/bash

    # Blender demo movie https://en.wikipedia.org/wiki/Sintel
    # Full URL: https://bitdash-a.akamaihd.net/content/sintel/hls/playlist.m3u8

    bURL=https://bitdash-a.akamaihd.net/content/sintel/hls/video/

    # I'm checking each available bitrate. You can modify that.
    bitratesArray=("250" "500" "800" "1100" "1500" "4000" "6000" "10000")

    # Here you can choose which ts file you want to remove from
    # the ffmpeg conversion (it'll be temporary renamed, doesn't matter).
    tsToCorrupt="14"

    for i in ${bitratesArray[@]}
    do
    # Download all files.
    # To be nice, I'm preventing unnecessary server load.
    if [ ! -d "${i}kbit" ]
    then
    echo -e "\nDownloading ${i}kbit version"

    curl "${bURL}${i}kbit.m3u8" | tee -a "${i}kbit.m3u8" | grep '\.ts' | \
    sed -e "s|^|$bURL|g" -e "s/\.ts/\.ts /g" > "${i}kbit_fullURL.m3u8"

    aria2c -q -c -j 16 -x 16 -d "${i}kbit" -i"${i}kbit_fullURL.m3u8"
    echo -e "\n"
    fi

    # Convert proper
    echo "Converting: ${i}kbit_proper.mp4"
    ffmpeg -y -hide_banner -loglevel error \
    -i "${i}kbit.m3u8" -c copy "${i}kbit_proper.mp4"

    # Make temporal source defect
    mv "${i}kbit/seq-${tsToCorrupt}.ts" "${i}kbit/seq-${tsToCorrupt}.ts_CORRUPTED"

    # Convert defective
    echo "Converting: ${i}kbit_defective.mp4"
    ffmpeg -y -hide_banner -loglevel error \
    -i "${i}kbit.m3u8" -c copy "${i}kbit_defective.mp4"

    # Repair defected source (obviously converted file is still corrupted)
    mv "${i}kbit/seq-${tsToCorrupt}.ts_CORRUPTED" "${i}kbit/seq-${tsToCorrupt}.ts"
    done

    # Examine generated files
    echo -e "\n\nREPORT"
    for i in *.mp4
    do
    echo -e "\n---------------------------\nFilename: \n${i}"

    report=$(ffprobe -v error -show_streams $i | grep "frame_rate")

    echo -e "\ncalculated frame rates:\n${report}"
    echo -e "\nVerdict: \nFile ${i} is "

    echo ${report} | \
    awk -F'[=\n ]' ' { if ( $2 == $4 ) { print "OK" } else { print "WRONG" }; } '
    done
    对我来说它工作正常。

    关于video - 将 HLS M3U8 转换为 MP4 后,如何找出是否缺少 TS 段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69949558/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com