用ffmpeg拉流HLS转推至nginx-rtmp-module没有声音的问题

命令行很简单,如下

ffmpeg -re -analyzeduration 8000 -probesize 200000 -i http://ip1/test.m3u8 -strict -2 -c:v copy -c:a copy -bsf:a aac_adtstoasc -f flv rtmp://ip2/test/1

从ip1所在的服务器拉一路HLS直播流,转推给ip2所在的服务器上的nginx-rtmp。

视频没有问题,音频用flash player播放是静音的。

用VLC播放音视频都正常。

用windows版ffplay播放音视频也正常。

其实仔细看,会发现vlc、ffplay虽然能够播放声音,但是他们显示音频是44100Hz,而不是实际的48000Hz。

将nginx-rtmp录制的flv文件下载下来分析

发现录制的文件没有AudioSpecificConfig(ASC)信息。有同学问什么是ASC,可以看这里。前面有篇文章介绍了在windows下编译ffmpeg,打开这个debug一下看看。

这里flvenc.c中函数flv_write_header中,单步调试一下,

红圈标注的位置条件为假,所以没有正确的写入AAC sequence header,如果在这里硬编码写入AAC sequence header,声音就正常了。

最简单的解决方法,就是自己重新做一下音频编码。

ffmpeg -re -analyzeduration 8000 -probesize 200000 -i http://ip1/test.m3u8 -strict -2 -c:v copy -c:a aac -bsf:a aac_adtstoasc -f flv rtmp://ip2/test/1

上面的方法简单粗暴,但是会浪费CPU时间,有位大神在去年12月提交了一个补丁 [FFmpeg-devel] [PATCH] AAC sequence header data setup if stream copy,很好的解决这个问题。

-aac_seq_header_data "1190" 这样是直接硬编码AudioSpecificConfig(ASC),最新的代码已删除,只有前面两个了。正确的命令行是(前提是你的ffmpeg代码要是2015.12以后的)

ffmpeg -re -analyzeduration 8000 -probesize 200000 -i http://ip1/test.m3u8 -strict -2 -bsf:a aac_adtstoasc -c copy -flvflags aac_seq_header_detect -f flv rtmp://ip2/test/1

推荐阅读更多精彩内容

  • 前言 如此强大的FFmpeg,能够实现视频采集、视频格式转化、视频截图、视频添加水印、视频切片、视频录制、视频推流...
    骚之哈塞給阅读 17,401评论 7 38
  • 前言 如此强大的FFmpeg,能够实现视频采集、视频格式转化、视频截图、视频添加水印、视频切片、视频录制、视频推流...
    sillen阅读 2,990评论 3 47
  • 下列说明完全摘自网络,后期会整理后修改。 RTMP是Real Time Messaging Protocol(实时...
    muction阅读 2,778评论 0 6
  • 前言 如此强大的FFmpeg,能够实现视频采集、视频格式转化、视频截图、视频添加水印、视频切片、视频录制、视频推流...
    RichyLeo阅读 14,812评论 2 21
  • 0 概述 FFmpeg是一套领先的音视频多媒体处理开源框架,采用LGPL或GPL许可证。它提供了对音视频的采集、编...
    但行耕者阅读 3,671评论 2 19