热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

HTML5视频直播

目前视频直播,尤其是移动端的视频直播已经火到不行了,基本上各大互联网公司都有了自己的直播产品,所以对于直播的一些基本知识和主要技术点也要有

目前视频直播,尤其是移动端的视频直播已经火到不行了,基本上各大互联网公司都有了自己的直播产品,所以对于直播的一些基本知识和主要技术点也要有所了解,本次分享就向大家介绍一下其中的奥秘。

内容大体框架: 
1. 怎样利用 HTML5 来播放直播视频 
2. 怎样录制直播视频 
3. 怎样实时上传直播视频 
4. 直播中的用户交互

分享人介绍:

吕鸣 目前在腾讯SNG担任手Q的web前端开发工作 
博客:http://www.nihaoshijie.com.cn/


下面是本期分享内容整理


Hello, 大家好,我是吕鸣,目前是在腾讯 SNG 的即通应用部负责手Q的兴趣部落 Web 前端开发工作。

针对目前比较火的视频直播,我做了一些研究和探索,同时我们的项目将会用到直播为此打下技术基础,下面就向大家分享一下直播的整个流程和一些技术点。

一、移动视频直播发展

大家首先来看下面这张图:

可以看到,直播从 PC 到一直发展到移动端,越来越多的直播类 App 上线,同时移动直播进入了前所未有的爆发阶段,但是对于大多数移动直播来说,还是要以 Native 客户端实现为主,但是 HTML5 在移动直播端也承载着不可替代的作用,例如 HTML5 有着传播快,易发布的优势,同时最为关键的时 HTML5 同样可以播放直播视频。

大家可以看下面这张大概的实现图

完整的直播可以分为以下几块:

  1. 视频录制端:一般是电脑上的音视频输入设备或者手机端的摄像头或者麦克风,目前以移动端的手机视频为主。
  2. 视频播放端:可以是电脑上的播放器,手机端的 Native 播放器,还有就是 HTML5 的 video 标签等,目前还是已手机端的 Native 播放器为主。
  3. 视频服务器端:一般是一台 nginx 服务器,用来接受视频录制端提供的视频源,同时提供给视频播放端流服务。

大家可以看下大致的结构图:

二、HTML5 录制视频:

对于HTML5视频录制,可以使用强大的 webRTC (Web Real-Time Communication)是一个支持网页浏览器进行实时语音对话或视频对话的技术,缺点是只在 PC 的 Chrome 上支持较好,移动端支持不太理想。

使用 webRTC 录制视频基本流程是:

  1. 调用 window.navigator.webkitGetUserMedia() 获取用户的PC摄像头视频数据。
  2. 将获取到视频流数据转换成 window.webkitRTCPeerConnection (一种视频流数据格式)。
  3. 利用 webscoket 将视频流数据传输到服务端

由于许多方法都要加上浏览器前缀,所以很多移动端的浏览器还不支持 webRTC,所以真正的视频录制还是要靠客户端(iOS,Android)来实现,效果会好一些。

三、HTML5 播放直播视频:

对于视频播放,可以使用 HLS(HTTP Live Streaming)协议播放直播流,iOS和 Android 都天然支持这种协议,配置简单,直接使用 video 标签即可。

下面是简单的代码使用 video 播放直播视频:

1.什么是 HLS 协议:

简单讲就是把整个流分成一个个小的,基于 HTTP 的文件来下载,每次只下载一些,前面提到了用于 HTML5 播放直播视频时引入的一个 .m3u8 的文件,这个文件就是基于 HLS 协议,存放视频流元数据的文件。

每一个 .m3u8 文件,分别对应若干个 ts 文件,这些 ts 文件才是真正存放视频的数据,m3u8 文件只是存放了一些 ts 文件的配置信息和相关路径,当视频播放时,.m3u8 是动态改变的,video 标签会解析这个文件,并找到对应的 ts 文件来播放,所以一般为了加快速度,.m3u8 放在 Web 服务器上,ts 文件放在 CDN 上。

.m3u8 文件,其实就是以 UTF-8 编码的 m3u 文件,这个文件本身不能播放,只是存放了播放信息的文本文件。

打开之后就是这个样子:

下面这个是 ts 文件,就是存放视频的文件:

2.HLS 的请求流程:

  1. HTTP 请求 m3u8 的 url。
  2. 服务端返回一个 m3u8 的播放列表,这个播放列表是实时更新的,一般一次给出5段数据的 url。
  3. 客户端解析 m3u8 的播放列表,再按序请求每一段的 url,获取 ts 数据流。

大概是这个流程:

3.HLS 直播延时:

我们知道 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

但是 HTML5 直播视频却有一些不可替代的优势:

  1. 传播性好,利于分享等操作。
  2. 可以动态发布,有利于实时迭代产品需求并迅速上线。
  3. 不用安装 App,直接打开浏览器即可。

四、iOS 采集(录制)音视频数据OS

关于音视频采集录制,首先明确下面几个概念:

  • 视频编码:所谓视频编码就是指通过特定的压缩技术,将某个视频格式的文件转换成另一种视频格式文件的方式,我们使用的 iPhone 录制的视频,必须要经过编码,上传,解码,才能真正的在用户端的播放器里播放。
  • 编解码标准:视频流传输中最为重要的编解码标准有国际电联的 H.261、H.263、H.264,其中 HLS 协议支持 H.264 格式的编码。
  • 音频编码:同视频编码类似,将原始的音频流按照一定的标准进行编码,上传,解码,同时在播放器里播放,当然音频也有许多编码标准,例如 PCM 编码,WMA 编码,AAC 编码等等,这里我们 HLS 协议支持的音频编码方式是 AAC 编码。

利用 iOS 上的摄像头,进行音视频的数据采集,主要分为以下几个步骤:

  1. 音视频的采集,iOS 中,利用 AVCaptureSession 和 AVCaptureDevice 可以采集到原始的音视频数据流。
  2. 对视频进行 H264 编码,对音频进行 AAC 编码,在 iOS 中分别有已经封装好的编码库来实现对音视频的编码。
  3. 对编码后的音、视频数据进行组装封包;
  4. 建立 RTMP 连接并上推到服务端。

下面是具体的采集音视频数据的流程:

1.关于 RTMP:

Real Time Messaging Protocol(简称 RTMP)是 Macromedia 开发的一套视频直播协议,现在属于 Adobe。和 HLS 一样都可以应用于视频直播,区别是 RTMP 基于 flash 无法在 iOS 的浏览器里播放,但是实时性比 HLS 要好。所以一般使用这种协议来上传视频流,也就是视频流推送到服务器。

下面是 HLS 和 RTMP 的对比:

2.推流

所谓推流,就是将我们已经编码好的音视频数据发往视频流服务器中,在 iOS 代码里面一般常用的是使用 RTMP 推流,可以使用第三方库 librtmp-iOS 进行推流,librtmp 封装了一些核心的 API 供使用者调用。例如推流 API 等等,配置服务器地址,即可将转码后的视频流推往服务器。

那么如何搭建一个推流服务器呢?

简单的推流服务器搭建,由于我们上传的视频流都是基于 RTMP 协议的,所以服务器也必须要支持 RTMP 才行,大概需要以下几个步骤:

  1. 安装一台 nginx 服务器。
  2. 安装 nginx 的 RTMP 扩展,目前使用比较多的是 https://github.com/arut/nginx-rtmp-module
  3. 配置 nginx 的 conf 文件
  4. 重启 nginx,将 RTMP 的推流地址写为 rtmp://ip:1935/hls/mystream, 其中 hls_path 表示生成的 .m3u8 和 ts 文件所存放的地址,hls_fragment 表示切片时长,mysteam 表示一个实例,即将来要生成的文件名可以先自己随便设置一个。

更多配置可以参考:https://github.com/arut/nginx-rtmp-module/wiki/

下面是 nginx 的配置文件

五、直播中的用户交互:

对于直播中的用户交互大致可以分为:

  1. 送礼物
  2. 发表评论或者弹幕

对于送礼物,在 HTML5 端可以利用 DOM 和 CSS3 实现送礼物逻辑和一些特殊的礼物动画,实现技术难点不大。

对于弹幕来说,要稍微复杂一些,可能需要关注以下几点:

  1. 弹幕实时性,可以利用 webscoket 来实时发送和接收新的弹幕并渲染出来。
  2. 对于不支持 webscoket 的浏览器来说,只能降级为长轮询或者前端定时器发送请求来获取实时弹幕。
  3. 弹幕渲染时的动画和碰撞检测(即弹幕不重叠)等等

六、总结

目前较为成熟的直播产品,大致都是以 Server 端和 HTML5 和 Native(android,ios)搭配实现直播:

基本是下图这个套路:

所以 HTML5 在整个直播中,还是有着重要的地位的!

Demo 分享

最后,根据本次分享的内容,我这边实现了一个 iOS 端录制,推流,NGINX 接收流,同时分发的 HLS 直播流的一整套 Demo,感兴趣的同学可以看下面这个链接:

https://github.com/lvming6816077/LMVideoTest

好了,本次分享先到这里了,谢谢大家~

互动问答环节

Q1: Demo 包含 iOS 端的 RTMP 播放不?

答:Demo 里面没有 RTMP 的播放,Demo 主要是提供录制,推流的。

Q2: 对于 HTML5 HLS 播放 卡顿问题,前端与 server 端,有什么配置上的优化吗?

答:server 端要做好分片策略,同时要将 ts 文件放在 CDN 上,前端这边可以尽量做到 DNS 缓存等,由于HTML5是使用的 video 标签,所以要修改 video 的播放优化,还是不那么容易。

Q3: 在手机推流时的码率是根据怎样的策略做选择的?不同机型和网络下如何保持流畅?

答:可以提供不同的视频码率来供用户选择,例如网速差的可以选择较为低清晰度的码率,网络好的用户可以选择更加清晰的码率,同时做好视频播放端的容错和异常处理等等。

Q4: RTMP 比起 HTTP 他的优势主要是几种在哪里?

答:RTMP 是基于 TCP 的保持的是长连接,而 HTTP 是一次性的,每次都要三次握手,所以对于直播来说还是 RTMP 好一些

Q5: 据我所知 nginx rtmp-module 好像性能不是很高…..为什么会采用这个来作为后端服务?

答:这里只是 Demo 用了这个 nginx rtmp-module,其实也可已选择 SRS(simple-rtmp-server)都是可以的哈

Q6: 移动端这边怎么进行编码转码?用 ffmpeg 编译时很麻烦

答:关于 iOS 这边,其实不用关心转码问题,因为已经有了很多开源的库提供给我们了例如: 
x264 编码:https://github.com/kewlbear/x264-ios 
faac 编码:https://github.com/fflydev/faac-ios-build

Q7: 您介绍的都是 Native 播放和还有 HTML5 的 video 标签播放, iOS 端有没有考虑过整个用原生的 OC 或者 Swift 实现?

答:关于播放端,其实真正体验好的还是要用 native 来实现的,而且 native 实现可以用 RTMP 来播放直播,延迟会好很多,HTML5 来播直播主要是考虑到易传播性好。

Q8: 在用户非常多的情况下,或者网络慢的情况下,有什么策略可以保证质量?

答:可以提供不同的视频码率来供用户选择,例如网速差的可以选择较为低清晰度的码率,网络好的用户可以选择更加清晰的码率,同时做好视频播放端的容错和异常处理等等。

Q9: 请问直播这块的测试中关注的几个指标是什么,有什么比较好的测试方法呢?

答:主要就是: 
1. 首次打开的白屏时间 
2. 直播中的卡顿和缓冲 
3. 直播的延时

Q10: 您提供的 Demo 为什么不是 HTML5 的呢 iOS 推流和 nginx 服务器都有,能不能提供一个前面第二张叶子美女直播那个页面的 Demo?

答:这个 Demo 你下载下拉运行的话,根据配置就可直接自己实现一个利用 HTML5 直播的页面,很简单,就像使用 video 标签一样,其他的样式你可以自己定制的。

Q11: HLS 的延时有没有比较好的方法解决?

答:HLS 确实是会有延迟,相对比较优的策略是调整好分片策略,在保证性能的情况下,和延迟达到平衡。

Q12: 如果加入视频电话功能,上面的结构需要作什么改变?视频电话的目的大概是:直播可以选择某一观众或者多个观众视频对话

答:视频电话,也就是说作为视频录制端的同时也作为视频播放端,所以实现实时电话简单就是:我在直播的同时观看别人的直播视频,别人在直播的同时观看我的直播视频,可以这样理解,上面的结构复制一份对调即可。

Q13: 如何实现滤镜功能?

答:一般是在视频录制之后,在转码前给视频数据增加滤镜功能,在 iOS 里可以使用一些滤镜库等等实现滤镜功能

Q14: 在 App 端如果不利用 HTML5 能实现直播吗?

答:可以啊,app 有更加丰富的播放接口,和开源播放器可以实现直播的。

Q15: 既然 HLS 有较高的延迟 为什么苹果推荐的的方式却是 HLS?

答:并不是说苹果主要推荐使用 HLS,对于 HTML5 来说目前只有这一种比较好的方式来播放直播视频,所以还是很期待苹果能对延迟问题做一些改进的。

Q16: 同滤镜问题,音频变声是如何实现的?

答:同样是可以在对音频转码前操作。

Q17: 如果针对网络较差的观看用户,是需要直播推流到服务器后做多份不同分辨率的拷贝,以适应不同网络的用户观看?如果是这样的话,对延迟会不会影响很大? 毕竟编解码也是需要时间的.

答:这个其实本身就应该做的,对于网络差的用户,完全可以提供给他们较低码率的直播流来减少卡顿问题,延迟问题的话还是要根据具体使用哪种协议来定。

Q18: 推流目前大部分都是第三方在做,难度点在哪?然后目前业内比较成熟的主要哪些?

答:难点主要是服务器端的性能压力和分发直播流的效率,业界都已经有了较成熟的方案,例如腾讯云的直播。


转:https://www.cnblogs.com/liulinjie/p/5775629.html



推荐阅读
  • 本文探讨了资源访问的学习路径与方法,旨在帮助学习者更高效地获取和利用各类资源。通过分析不同资源的特点和应用场景,提出了多种实用的学习策略和技术手段,为学习者提供了系统的指导和建议。 ... [详细]
  • 数字图书馆近期展出了一批精选的Linux经典著作,这些书籍虽然部分较为陈旧,但依然具有重要的参考价值。如需转载相关内容,请务必注明来源:小文论坛(http://www.xiaowenbbs.com)。 ... [详细]
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
  • 本文详细介绍了在 CentOS 7 系统中配置 fstab 文件以实现开机自动挂载 NFS 共享目录的方法,并解决了常见的配置失败问题。 ... [详细]
  • 解决Only fullscreen opaque activities can request orientation错误的方法
    本文介绍了在使用PictureSelectorLight第三方框架时遇到的Only fullscreen opaque activities can request orientation错误,并提供了一种有效的解决方案。 ... [详细]
  • 零拷贝技术是提高I/O性能的重要手段,常用于Java NIO、Netty、Kafka等框架中。本文将详细解析零拷贝技术的原理及其应用。 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • 在PHP中如何正确调用JavaScript变量及定义PHP变量的方法详解 ... [详细]
  • 本指南介绍了如何在ASP.NET Web应用程序中利用C#和JavaScript实现基于指纹识别的登录系统。通过集成指纹识别技术,用户无需输入传统的登录ID即可完成身份验证,从而提升用户体验和安全性。我们将详细探讨如何配置和部署这一功能,确保系统的稳定性和可靠性。 ... [详细]
  • Python 程序转换为 EXE 文件:详细解析 .py 脚本打包成独立可执行文件的方法与技巧
    在开发了几个简单的爬虫 Python 程序后,我决定将其封装成独立的可执行文件以便于分发和使用。为了实现这一目标,首先需要解决的是如何将 Python 脚本转换为 EXE 文件。在这个过程中,我选择了 Qt 作为 GUI 框架,因为之前对此并不熟悉,希望通过这个项目进一步学习和掌握 Qt 的基本用法。本文将详细介绍从 .py 脚本到 EXE 文件的整个过程,包括所需工具、具体步骤以及常见问题的解决方案。 ... [详细]
  • POJ 2482 星空中的星星:利用线段树与扫描线算法解决
    在《POJ 2482 星空中的星星》问题中,通过运用线段树和扫描线算法,可以高效地解决星星在窗口内的计数问题。该方法不仅能够快速处理大规模数据,还能确保时间复杂度的最优性,适用于各种复杂的星空模拟场景。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 在Delphi7下要制作系统托盘,只能制作一个比较简单的系统托盘,因为ShellAPI文件定义的TNotifyIconData结构体是比较早的版本。定义如下:1234 ... [详细]
  • 在使用SSH框架进行项目开发时,经常会遇到一些常见的问题。例如,在Spring配置文件中配置AOP事务声明后,进行单元测试时可能会出现“No Hibernate Session bound to thread”的错误。本文将详细探讨这一问题的原因,并提供有效的解决方案,帮助开发者顺利解决此类问题。 ... [详细]
author-avatar
ruishao520
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有