译者:吕鸣
原文:百度Bugly(http://bugly.qq.com)
音频现场直播那么火,再称名就 out 了。
为的是紧随流行时尚,责任编辑将向我们如是说呵呵音频现场直播中的基本上业务流程和主要就的控制技术点,主要就包括但不局限于后端控制技术。
H5 究竟能无法做音频现场直播?总之能, H5 火了很久,囊括了方方面面的控制技术。
对音频演唱,能采用强悍的 webRTC(Web Real-Time Communication)是两个全力支持页面浏览器展开动态音频谈话或音频谈话的控制技术,优点是只在 PC 的 chrome 上全力支持良好,终端端全力支持不太平庸。
对音频播映,能采用 HLS(HTTP Live Streaming)协定播映现场直播流, ios 和 android 都纯天然全力支持此种协定,实用性单纯,间接采用 video 条码方可。
webRTC 相容性单纯讲是把整座流分为无数个小的,如前所述 HTTP 的文档来浏览,每天只浏览许多,后面提及了用作 H5 播映现场直播音频时导入的两个 .m3u8 的文档,那个文档是如前所述 HLS 协定,放置音频流元数据的文档。
每两个 .m3u8 文档,分别对应若干个 ts 文档,这些 ts 文档才是真正放置音频的数据,m3u8 文档只是放置了许多 ts 文档的实用性信息和相关路径,当音频播映时,.m3u8 是动态改变的,video 条码会解析那个文档,并找到对应的 ts 文档来播映,所以一般为的是加快速度,.m3u8 放在 web 服务器上,ts 文档放在 cdn 上。
.m3u8 文档,其实是以 UTF-8 编码的 m3u 文档,那个文档本身无法播映,只是放置了播映信息的文责任编辑档:
#EXTM3U m3u文档头
#EXT-X-MEDIA-SEQUENCE 第两个TS分片的序列号
#EXT-X-TARGETDURATION 每个分片TS的最大的时长
#EXT-X-ALLOW-CACHE 是否允许cache
#EXT-X-ENDLIST m3u8文件结束符
#EXTINF 指定每个媒体段(ts)的持续时间(秒),仅对其后面的URI有效
mystream-12.ts
ts 文档http 请求 m3u8 的 url。
服务端返回两个 m3u8 的播映列表,那个播映列表是动态更新的,一般一次给出5段数据的 url。
单纯业务流程我们知道 hls 协定是将现场直播流分为一段一段的小段音频去浏览播映的,所以假设列表里面的包含5个 ts 文档,每个 TS 文档包含5秒的音频内容,那么整体的延迟是25秒。因为当你看到这些音频时,主播已经将音频演唱好上传上去了,所以时这样产生的延迟。总之能缩短列表的长度和单个 ts 文档的大小来降低延迟,极致来说能缩减列表长度为1,并且 ts 的时长为1s,但是这样会造成请求次数增加,增大服务器压力,当网速慢时回造成更多的缓冲,所以苹果官方推荐的ts时长时10s,所以这样就会大改有30s的延迟。参考资料:https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/StreamingMediaGuide/FrequentlyAskedQuestions/FrequentlyAskedQuestions.html(复制此链接到应用程序打开)
音频现场直播的整座业务流程是甚么?当音频现场直播可大致分为音频演唱端:一般是电脑上的音音频输入设备或者手机端的摄像头或者麦克风,目前以终端端的手机音频为主。
音频播映端:能是电脑上的播映器,手机端的 native 播映器,还有是 h5 的 video 条码等,目前还是已手机端的 native 播映器为主。
音频服务器端:一般是一台 nginx 服务器,用来接受音频演唱端提供的音频源,同时提供给音频播映端流服务。
单纯业务流程当首先明确几个概念:
音频编码:所谓音频编码是指通过特定的压缩控制技术,将某个音频格式的文档转换成另一种音频格式文档的方式,我们采用的 iphone 演唱的音频,必须要经过编码,上传,解码,才能真正的在用户端的播映器里播映。
编解码标准:音频流传输中最为重要的编解码标准有国际电联的H.261、H.263、H.264,其中 HLS 协定全力支持 H.264 格式的编码。
音频编码:同音频编码类似,将原始的音频流按照一定的标准展开编码,上传,解码,同时在播映器里播映,总之音频也有许多编码标准,例如 PCM 编码,WMA 编码,AAC 编码等等,这里我们 HLS 协定全力支持的音频编码方式是AAC编码。
下面将利用 ios 上的摄像头,展开音音频的数据采集,主要就分为以下几个步骤:
音音频的采集,ios 中,利用 AVCaptureSession和AVCaptureDevice 能采集到原始的音音频数据流。
对音频展开 H264 编码,对音频展开 AAC 编码,在 ios 中分别有已经封装好的编码库来实现对音音频的编码。
对编码后的音、音频数据展开组装封包;
建立 RTMP 连接并上推到服务端。
ps:由于编码库大多采用 c 语言编写,需要自己采用时编译,对 ios,能采用已经编译好的编码库。
x264编码:https://github.com/kewlbear/x264-ios(复制此链接到应用程序打开)
faac编码:https://github.com/fflydev/faac-ios-build(操作同上)
ffmpeg编码:https://github.com/kewlbear/FFmpeg-iOS-build-script(操作同上)
关于如果想给音频增加许多特殊效果,例如增加滤镜等,一般在编码前给采用滤镜库,但是这样也会造成许多耗时,导致上传音频数据有一定延时。
单纯业务流程和之前的 x264 一样,ffmpeg 其实也是一套编码库,类似的还有 Xvid,Xvid 是基于 MPEG4 协定的编解码器,x264是如前所述 H.264 协定的编码器, ffmpeg 集合了各种音频,音频编解码协定,通过设置参数能完成如前所述 MPEG4,H.264 等协定的编解码,demo 这里采用的是 x264 编码库。
甚么是 RTMP?Real Time Messaging Protocol(简称 RTMP)是 Macromedia 开发的一套音频现场直播协定,现在属于 Adobe。和 HLS 一样都能应用作音频现场直播,区别是 RTMP 如前所述 flash 无法在 ios 的应用程序里播映,但是动态性比 HLS 要好。所以一般采用此种协定来上传音频流,也是音频流推送到服务器。
这里列举呵呵 hls 和 rtmp 对比:
简所谓推流,是将我们已经编码好的音音频数据发往音频流服务器中,一般常用的是采用 rtmp 推流,能采用第三方库 librtmp-iOS 展开推流,librtmp 封装了许多核心的 api 供采用者调用,如果觉得麻烦,能采用现成的 ios 音频推流sdk,也是如前所述 rtmp 的,https://github.com/runner365/LiveVideoCoreSDK(复制此链接到应用程序打开)
推流服务器搭建简单纯的推流服务器搭建,由于我们上传的音频流都是如前所述 rtmp 协定的,所以服务器也必须要全力支持 rtmp 才行,大概需要以下几个步骤:
安装一台 nginx 服务器。
安装 nginx 的 rtmp 扩展,目前采用比较多的是https://github.com/arut/nginx-rtmp-module(复制此链接到应用程序打开)
实用性 nginx 的 conf 文档:
rtmp { server { listen 1935; #监听的端口 chunk_size 4000;application hls { #rtmp推流请求路径 live on; hls on; hls_path /usr/local/var/www/hls; hls_fragment 5s; } } }重启 nginx,将 rtmp 的推流地址写为 rtmp://ip:1935/hls/mystream,其中 hls_path 表示生成的 .m3u8 和 ts 文档所放置的地址,hls_fragment 表示切片时长,mysteam 表示两个实例,即将来要生成的文件名能先自己随便设置两个。更多实用性能参考:https://github.com/arut/nginx-rtmp-module/wiki/(复制此链接到应用程序打开)
根据以上步骤基本上上已经实现了两个支持 rtmp 的音频服务器了。
在 html5 页面展开播映现场直播音频?单纯来说,间接采用 video 条码方可播映 hls 协定的现场直播音频:
<video autoplay webkit-playsinline> <source src=”http://10.66.69.77:8080/hls/mystream.m3u8″ type=”application/vnd.apple.mpegurl” /> <p class=”warning”>Your browser does not support HTML5 video.</p> </video>需要注意的是,给 video 条码增加 webkit-playsinline 属性,那个属性是为的是让 video 音频在 ios 的 uiwebview 里面能不全屏播映,默认 ios 会全屏播映音频,需要给 uiwebview 设置 allowsInlineMediaPlayback=YES。 业界比较成熟的 videojs,能根据不同平台选择不同的策略,例如 ios 采用 video 条码,pc 采用 flash 等。
坑点总结简根据以上步骤,笔者写了两个 demo,从实现 ios 音频演唱,采集,上传,nginx 服务器下发现场直播流,h5 页面播映现场直播音频者一整套业务流程,总结出以下几点比较坑的地方:
在采用 AVCaptureSession 展开采集音频时,需要实现 AVCaptureVideoDataOutputSampleBufferDelegate 协定,同时在- (void)captureOutput:(AVCaptureOutput )captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection )connection 捕获到音频流,要注意的是 didOutputSampleBuffer 那个方法不是 didDropSampleBuffer 方法,后者只会触发一次,当时开始写的是 didDropSampleBuffer 方法,差了半天才发现方法调用错了。
在采用 rtmp 推流时,rmtp 地址要以 rtmp:// 开头,ip 地址要写实际 ip 地址,不要写成 localhost,同时要加上端口号,因为手机端上传时是无法识别 localhos t的。
这里后续会补充上许多坑点,有的需要贴代码,这里先列那么多。
业界全力支持目前,百度云,百度云,阿里云都已经有了如前所述音频现场直播的解决方案,从音频演唱到音频播映,推流,都有一系列的 sdk 能采用,优点是需要收费,如果能的话,自己实现一套也并不是难事哈。
demo地址:https://github.com/lvming6816077/LMVideoTest/(复制此链接到应用程序打开)
参考资料:http://www.nihaoshijie.com.cn/index.php/archives/615(复制此链接到应用程序打开)
责任编辑系百度Bugly独家内容,转载请在文章开头显眼处注明译者和原文“百度Bugly(http://bugly.qq.com)”