1

我的一些通过 ffmpeg 编码的 HLS 视频在通过缓冲区时会丢弃音频。再次同步音频和视频的唯一方法是重新启动视频。什么会导致这种情况?

示例配置文件:

bitrate: 4800, profile: 'high', level: '4.1', resolution: 1080, framerate: '24000/1001'
ffmpeg
    '-y' 
    '-i' input_file.mov                                                 
    '-v' error 
    '-map' '0:0'                                                        
    '-c:v' libx264                                                  
    '-x264opts' f'
        keyint=23:                  
        min-keyint=23:          
        no-scenecut                                                     
    '
    '-vf' f'scale=-1:1080'
    '-preset' 'slow'
    '-profile:v' 'high'
    '-level' '4.1'
    '-b:v' '4800k'
    '-maxrate' '4800k'
    '-movflags' 'faststart'
    '-bufsize' '9600k' 
    '-write_tmcd', '0'
    '-r' '24000/1001'                                   
    output_dir                                                      

分割命令:

FFMPEG 
    '-i' output_dir 
    '-v' 'error' 
    '-acodec' 'copy'
    '-vcodec' 'copy'
    '-hls_time' '4' #seconds
    '-hls_list_size' '0'
    '-hls_flags' 'single_file' 
    os.path.join(output_dir, f'{run_id}_{bitrate}.m3u8'

补充:苹果的mediastreamvalidator输出一些不同的错误:

Error: Playlist vs segment duration mismatch
--> Detail:  Segment duration 98.0146, Playlist duration: 4.7968
--> Source:  1559962503399_2200k.m3u8 - 1559962503399_2200k.ts:1746520@0
Error: Measured peak bitrate compared to master playlist declared value exceeds error tolerance
--> Detail:  Measured: 3182.61 kb/s, Master playlist: 2173.82 kb/s, Error: 46.41%, Combined rendition name: English
--> Source:  ...playlist.m3u8
--> Compare: 1559962503399_2200k.m3u8
Error: Different target durations detected
--> Detail:  Target duration: 5 vs Target duration: 4
--> Source:  1559962503399_64k.m3u8
--> Compare: 1559962503399_128k.m3u8

更新 1: 我修改了编码命令以利用 tee 伪多路复用器,但在将 HLS 分段为字节范围而不是单独的 .ts 文件时,似乎仍然存在相同的问题:

$ ffmpeg
-hide_banner
-report
-benchmark
-vstats
-i "../Jane_shallowing_Top_v08.mp4"
-dn
-sn
-filter_complex "[0:v]fps=fps=24.000,setpts=(PTS-STARTPTS),split=[vsplit1][vsplit2];[vsplit1]scale=-1:144[video_144];[vsplit2]scale=-1:1080[video_1080]"
-map "[video_144]"
-r:v:0 "24.000"
-c:v:0 "libx264"
-x264-params "keyint=144:min-keyint=144:scenecut=0:open_gop=0"
-preset:v:0 "slow"
-profile:v:0 "baseline"
-refs:v:0 "2"
-b-pyramid:v:0 "strict"
-tune:v:0 "film"
-b:v:0 "96000"
-maxrate:v:0 "56000"
-bufsize:v:0 "6*56000/8"
-vsync:v:0 "cfr"
-bsf:v:0 "h264_metadata=fixed_frame_rate_flag=1"
-map "[video_1080]"
-r:v:1 "24.000"
-c:v:1 "libx264"
-x264-params "keyint=144:min-keyint=144:scenecut=0:open_gop=0"
-preset:v:1 "slow"
-profile:v:1 "high"
-refs:v:1 "2"
-b-pyramid:v:1 "strict"
-tune:v:1 "film"
-b:v:1 "4800000"
-maxrate:v:1 "4800000"
-bufsize:v:1 "6*4800000/8"
-vsync:v:1 "cfr"
-bsf:v:1 "h264_metadata=fixed_frame_rate_flag=1"
-map a:0 -map a:0
-c:a "libfdk_aac"
-ar "48000"
-ab "128k"
-af "aresample=async=1:min_hard_comp=0.100000:first_pts=0"
-f "hls"
-var_stream_map "v:1,a:0 v:0,a:1"
-hls_time "6.000"
-hls_segment_type "mpegts"
-hls_flags "discont_start+temp_file+single_file"
-hls_list_size "0"
-master_pl_name "playlist.m3u8"
-hls_segment_filename "out_%v.ts" "out_%v.m3u8" 
Segment duration 98.0267, Playlist duration: 6.0000
4

1 回答 1

1

您必须根据帧速率和分段时间设置 GOP。在您的示例中,您每秒有 24 帧和 4 秒段。GOP 应设置为 96。

也尝试设置 minrate maxrate 和 bufsize 相同。如果这可行,请尝试将 bufsize 扩展为您想要的。

我会建议类似(注意 GOP 如何为 24(帧率)*4(HLS 容器时间);

ffmpeg -i videofile -c:v libx264 -preset slow -profile:v high -level 4.1 -minrate 4800k -maxrate 4800k -bufsuze 4800k -b:v 4800k -vf scale=-1:1080 -flags +cgop -g 96 -x264-params scenecut=0:open_gop=0:min-keyint=96:keyint=96 

你没有提到音频链。我会建议类似的东西;

-c:a aac -b:a 64k -filter:a aresample=48000:async=1:min_hard_comp=0.100000:first_pts=0 -fflags +genpts

如果您有 libfdk_aac 和其他需要的设置,请更改音频编解码器。关键设置是段大小的正确 GOP。

于 2019-06-13T02:31:49.400 回答