文章结构

  1. 直播构成
  2. 直播流程
  3. web中直播技术
    • HLS协议
    • RTMP协议
    • HLS与RTMP对比
  4. 直播实战
    • 安装nginx、nginx-rtmp-module、FFmpeg(以下操作均在mac下进行)
    • nginx.conf配置文件,配置RTMP、HLS
    • 重启nginx
    • 查看端口是否启动
    • FFmpeg执行命令
    • 代码
    • 效果
  5. 直播中遇到坑
  6. 总结

直播构成

直播流程

视频直播可以分为采集,前处理,编码,传输,解码,渲染 这几个环节。

采集

一般是由客户端(IOS、安卓、PC或其它工具,如OBS)完成的,iOS是比较简单的,Android则要做些机型适配工作,PC最麻烦各种奇葩摄像头驱动,当然这些问题,腾讯云已经帮我们处理好了,呵呵。

前处理

主要是处理直播美颜,美颜算法需要用到GPU编程,需要懂图像处理算法的人,没有好的开源实现,要自己参考论文去研究。难点不在于美颜效果,而在于GPU占用和美颜效果之间找平衡。

编码

肯定要采用硬编码,软编码720p完全没希望,勉强能编码也会导致CPU过热烫到摄像头。编码要在分辨率,帧率,码率,GOP等参数设计上找到最佳平衡点。

传输

一般交给了CDN服务商。

解码

是对之前编码的操作,进行解码,在web里需要解码是HLS。

渲染

主要用播放器来解决,web中常用到的播放器有 video.js ,目前我们使用是腾讯云播放器。

其实一个完成直播,远远不上面这几个环节,下面是腾讯云直播方案的整个流程图:

web中直播技术

目前互联网上web做直播,主要是展示,主流web展示的话可能涉及到HLS跟RTMP这两个东西,现在我们重点讲解hls跟RTMP协议。

HLS

HLS(HTTP Live Streaming全称)是一个基于HTTP的视频流协议,由Apple公司实现,Mac OS上的QuickTime、Safari 以及iOS上的 Safari都能很好的支持 HLS,高版本 Android 也增加了对 HLS 的支持。

一些常见的客户端如:MPlayerX、VLC 也都支持HLS协议,如果需要在chrome上播放,需要使用 videojs-contrib-hls.js 解析。

HLS工作流程图

Server服务器

HLS的服务器组件负责获取的媒体输入流 , 然后Media编码后 MPEG-4(H.264 video 和 AAC audio)格式然后用硬件打包到 MPEG-2 (MPEG-2 transport stream)的传输流中。图中显示,传输流会经过stream segmenter, 这里的工作是MPEG-2传输流会被分散为小片段然后保存为一个或多个系列的 .ts 格式的媒体文件。这个过程需要借助编码工具来完成,比如 Apple stream segmenter。 (视频类是.ts文件,纯音频会被编码为一些音频小片段,通常为 ADTS头的AAC、MP3、或者 AC-3格式。) 服务端可以采用硬件编码和软件编码两种形式,其功能都是按照上文描述的规则对现有的媒体文件进行切片并使用索引文件进行管理。而软件切片通常会使用 Apple 公司提供的工具或者第三方的集成工具。

Distribution分配组件

同时上面提到的那个切片器(segmenter)也会创建一个索引文件,通常会包含这些媒体文件的一个列表,也能包含元数据。它一般都是一个个.M38U的列表。列表元素会关联一个 URL 用于客户端访问。然后按序去请求这些 URL。

索引文件结构图

主索引文件

#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=409037,RESOLUTION=416x234,CODECS="mp4a.40.2, avc1.42001e"
Gear1/prog_index.m3u8复制代码

第一行:#EXTM3U

每个M3U文件第一行必须是这个tag,起标示作用

第二行:#EXT-X-STREAM-INF

标签的属性列表中直接指明当前流是VIDEO还是AUDIO

包含属性 :

  1. BANDWIDTH 指定码率
  2. PROGRAM-ID 唯一ID (这个属性在后面的协议版本废除了)
  3. CODECS 指定流的编码类型
  4. RESOLUTION:分辨率

子索引文件

#EXTM3U
#EXT-X-TARGETDURATION:11
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:10.133333,
fileSequence0.ts
#EXTINF:10.000666,
fileSequence1.ts
#EXTINF:10.667334,
fileSequence2.ts
#EXTINF:9.686001,
fileSequence3.ts
#EXTINF:9.768665,
fileSequence4.ts
#EXTINF:10.000000,
fileSequence5.ts
#EXT-X-ENDLIST复制代码

#EXTM3U m3u文件头,必须放在第一行。

#EXT-X-TARGETDURATION 每个分片TS的最大的时长。

#EXT-X-VERSION 用以标示协议版本。

#EXT-X-MEDIA-SEQUENCE TS分片的序列号。

#EXT-X-PLAYLIST-TYPE 提供关于PlayList的可变性的信息, 这个对整个PlayList文件有效,是可选的。

#EXTINF extra info,分片TS的信息,如时长,带宽等。

主索引文件与子索引文件的区别

  • 主索引文件和子索引文件都是.M3U8的playlist
  • 主索引文件只需下载一次,但对于直播节目子索引文件定期重新加载

client客户端

分配组件由标准的网络服务器。他们负责接受Client客户端请求并提供相关联的资源给客户端。

videojs-contrib-hls.js组件解析过程

videojs-contrib-hls.js解析图

HLS简单讲就是把整个流分成一个个小的片段,基于 HTTP 的文件来下载,每次只下载一小部分。

前面提到了用于 H5 播放直播视频时引入的一个 .m3u8 的文件,这个文件就是基于 HLS 协议,存放视频流元数据的文件。

每一个 .m3u8 文件,分别对应若干个 ts 文件,这些 ts 文件才是真正存放视频的数据,m3u8 文件只是存放了一些 ts 文件的配置信息和相关路径,当视频播放时,.m3u8 是动态改变的,再通过解析器(videojs-contrib-hls.js)解析这个文件,并找到对应的 ts 文件来播放,所以一般为了加快速度,.m3u8 放在 web 服务器上,ts 文件放在 cdn 上。

RTMP

Real Time Messaging Protocol(简称 RTMP)是 Macromedia 开发的一套视频直播协议,现在属于 Adobe。这套方案需要搭建专门的 RTMP 流媒体服务如 Adobe Media Server,并且在浏览器中只能使用 Flash 实现播放器。它的实时性非常好,延迟很小,但无法支持移动端 WEB 播放是它的硬伤。

浏览器端,HTML5 video标签无法播放 RTMP 协议的视频,可以通过 video.js 来实现。

<link href="http://vjs.zencdn.net/5.8.8/video-js.css" rel="stylesheet"><video id="example_video_1" class="video-js vjs-default-skin" controls preload="auto" width="640" height="264" loop="loop" webkit-playsinline>
<source src="rtmp://10.14.221.17:1935/rtmplive/home" type='rtmp/flv'>
</video><script src="http://vjs.zencdn.net/5.8.8/video.js"></script>
<script>
videojs.options.flash.swf = 'video.swf';
videojs('example_video_1').ready(function() {
this.play();
});
</script>
复制代码

HLS VS RTMP 优缺点对比

协议 原理 延时 优点 缺点 使用场景
HLS(http) 集合一段时间数据生成ts切片文件更m3u8文件 10s-30s 跨平台 延时性高 移动端
RTMP(TCP) 每个时刻的数据收到后立即发送 2s 延时低、实时性好 跨平台差 PC+直播+实时性要求高+互动性强

直播实战(搭建RTMP、HLS直播流服务)

安装nginx

brew install nginx
复制代码

安装nginx-rtmp-module

brew install nginx-full --with-rtmp-module
复制代码

然后安装FFmpeg(是一个集录制、转换、音/视频编码解码功能 为一体的完整的开源工具,我们下面用它来做推流跟切片)。

brew install ffmpeg
复制代码

nginx.conf配置文件,配置RTMP、HLS

查找到nginx.conf配置文件(/usr/local/etc/nginx/nginx.conf),并配置相应的直播流配置。

rtmp {server {#监听的端口listen 1935;# RTMP 直播流配置application rtmplive {live on;#为 rtmp 引擎设置最大连接数。默认为 offmax_connections 1024;}# HLS 直播流配置application hls{live on;hls on;hls_path /Users/youname/Documents/notes/live/public/hls;  #这里的路径切片需要保存的路径hls_fragment 1s;}}
}
复制代码

在http中添加 HLS 的配置:

location /hls {# Serve HLS fragmentstypes {application/vnd.apple.mpegurl m3u8;video/mp2t ts;}root /Users/youname/Documents/notes/live/public;#切片的路径#add_header Cache-Controll no-cache;expires -1;
}
复制代码

重启nginx

sudo nginx -s reload
复制代码

查看端口是否启动

netstat -an | grep 1935
复制代码

如果显示如下,显示已经启用。

http端口同理。

到现在我们已经完成了,服务的搭建。

  1. RTMP推流地址为 rtmp://127.0.0.1:1935/rtmplive/home
  2. HLS推流地址为 rtmp://localhost:1935/rtmplive/hls

FFmpeg执行命令

我们以推流MP4文件为例,我的视频文件地址:/Users/youname/Desktop/w01661pl9vw.p702.1.mp4

RTMP 协议推流命令:

ffmpeg -re -i /Users/youname/Desktop/w01661pl9vw.p702.1.mp4 -vcodec libx264 -acodec aac -f flv rtmp://127.0.0.1:1935/rtmplive/home复制代码

HLS 协议推流命令:

ffmpeg -re -i  /Users/youname/Desktop/w01661pl9vw.p702.1.mp4 -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -q 10 rtmp://127.0.0.1:1935/hls/test 复制代码

参数:

  1. 视频的地址:/Users/youname/Desktop/w01661pl9vw.p702.1.mp4
  2. 推流地址:rtmp://127.0.0.1:1935/rtmplive/home,rtmp://localhost:1935/rtmplive/hls

上面的命令操作后,命令行出现了如下图,表示已经成功了。

关于FFmpeg功能命令可参考:FFmpeg功能命令集合

web实现直播

两种推流方式播放的话,我们都使用video.js播放器播放(牛牛里使用的是腾讯云播放器)

RTMP协议代码实现

需要注意的是src中的地址填的是RTMP推流地址。播放时,如果出现“当前系统环境不支持播放该视频格式”,浏览器需要启用flash,才能正常播放。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<link href="http://vjs.zencdn.net/5.19/video-js.min.css" rel="stylesheet">
<script src="http://vjs.zencdn.net/5.19/video.min.js"></script>
</head>
<body>
<videoid="my-player"class="video-js"controlspreload="auto"data-setup='{}'><source src='rtmp://127.0.0.1/rtmplive/home' type='rtmp/flv'/>  </p>
</video>
<script type="text/javascript">var player = videojs('my-player');var options = {};var player = videojs('my-player', options, function onPlayerReady() {videojs.log('Your player is ready!');// In this context, `this` is the player that was created by Video.js.this.play();// How about an event listener?this.on('ended', function() {videojs.log('Awww...over so soon?!');});});
</script>
</body>
</html>
复制代码

HLS代码实现

下面的src填的是切片地址。

<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>videojs-contrib-hls embed</title><link href="https://unpkg.com/video.js/dist/video-js.css" rel="stylesheet"><script src="https://unpkg.com/video.js/dist/video.js"></script><script src="https://unpkg.com/videojs-contrib-hls/dist/videojs-contrib-hls.js"></script>
</head>
<body><video id="my_video_1" class="video-js vjs-default-skin" controls preload="auto" width="640" height="268" data-setup='{}'><source src="http://www.tony.com/hls/test.m3u8" type="application/x-mpegURL"></video>
</body>
</html>
复制代码

效果

我们来看看真正的效果如何。

RTMP效果图

HLS效果

ts和m3u8文件

实战中遇到的坑

  • 自动播放问题
  • 各平台播放器表现不统一
  • 内页面调试困难
  • Native与web通信问题

自动播放问题

在X5内核浏览器里必须使用触发touchend、click、doubleclick或keydown事件等标准的事件才能触发。

各平台播放器表现不统一

安卓下很多浏览器把video标签替换成了原生自带播放器样式跟行为,很难控制其行为跟样式。

内嵌页面调试困难

目前使用的是weinre调试,但weinre调试看不到在native实际效果,比如web调用native,需要native反馈一种效果,weinre是看不到效果。

Native与web通信

schema跟jsBridge,schema只能做到web调用native,而且做不到native调用web;jsBridge虽然可以做native调用web,但在iframe没加载完的情况下,也是通知不到web的;

总结

整个直播是一个非常复杂的过程,实现过程中会遇到很多性能问题,需要在性能跟即时性做一个权衡,ts跟m3u8尽量做到缓存,浏览器里尽量使用推流。

直播平台源码搭建教程直播原理与web直播实战相关推荐

  1. 直播平台源码搭建教程盘点直播技术中的编解码、直播协议、网络传输与简单实现

    直播平台源码搭建教程盘点直播技术中的编解码.直播协议.网络传输与简单实现 Live CheatSheet | 直播技术理论基础与实践概论 音视频直播的基本流程都是采集 → 编码推流 → 网络分发 → ...

  2. 直播系统源码App中Android酷炫礼物动画直播平台源码搭建教程(上篇)

    直播系统源码App中Android酷炫礼物动画直播平台源码搭建教程(上篇) 在当下移动直播火爆的年代,如果你曾经使用过移动端直播应用,相信会被里面那令人惊叹的礼物动画效果迷住,比如像下面这样的效果. ...

  3. 在找直播平台源码搭建教程?先看看这些吧

    很多人都在找直播平台源码教程,但其实连一些基础知识都不知道,因此小编特地编辑了这份跟直播平台源码搭建相关知识,以供大家进行学习. 1.服务器的选择: 服务器是搭建直播平台唯一需要购买的硬件设备,通常会 ...

  4. 直播平台开发时iOS 开发内购功能,直播平台源码搭建

    1.首先登录苹果账号,在直播平台源码搭建完成好后,进入后台管理中心添加商品,选择功能----App内购买项目------添加商品类型.商品的ID.以及说明信息. 2.在直播平台源码搭建后台创建沙盒测试 ...

  5. 直播源码搭建教程5 分钟完成(直播 + 分流 + 画面水印)

    直播源码搭建教程5 分钟完成(直播 + 分流 + 画面水印) 部署运行 服务器 安装docker(Centos7,其他系统请发挥你的搜索功能) $ yum -y install docker #安装d ...

  6. php婚恋相亲交友/聊天通讯/红娘认证/婚介所择爱平台源码搭建教程

    php婚恋相亲交友/聊天通讯/红娘认证/婚介所择爱平台源码搭建教程 环境要求: 系统建议:建议使用Linux CentOS 6.8以上系统 面板建议:建议使用宝塔一键环境安装 基础环境要求: PHP5 ...

  7. 互站卖8000的APK打包平台源码+搭建教程,可是实现自动打包app

    互站卖8000的APK打包平台源码+搭建教程,可是实现自动打包app 程序可实现安卓app五分钟自动打包更换包名和签名互站卖8000的APK打包平台源码+搭建教程,可是实现自动打包app 也可以上传打 ...

  8. 直播APP开发 社交直播平台源码搭建——流媒体技术详解

    随着移动互联网的发展,国内也涌现大大小小十几款视频直播app.以王思聪投资的17在2015年的爆红为代表,视频移动直播浮出水面,再到后来的映客.花椒.蜜友圈等等,直播自媒体时代的快速发展改变了人们传统 ...

  9. 直播平台源码搭建教程之Android音视频开发

    直播平台源码搭建教程之Android音视频开发 音频 将声音保存成音频的过程,其实就是将模拟音频数字化的过程,为了实现这个过程,就需要对模拟音频进行采样.量化和编码.接下来我们详细讲解这一过程. 采样 ...

最新文章

  1. php ids,PHP / MYSQL查询id“duplicate ids”
  2. SAP PM 初级系列3 - 主数据相关的基础设置
  3. 如何做好网站开发项目需求分析(转)
  4. 后台开发经典书籍--深入理解计算机系统
  5. 【MySQL】 已经存在大量数据的表做分区
  6. LigerUi之Grid使用详解(二)——数据编辑
  7. 在控制台中输出 出现SIGBAT或者EXC_BAD_ACCESS的原因的方法
  8. AUTOSAR从入门到精通100讲(二十八)-AutoSar之CAN网络管理
  9. keras 多层lstm_tensorflow-如何在keras中堆叠多个lstm?
  10. 解决安卓中XML文件声明高度 宽度无效的问题
  11. MapReduce框架下的FP Growth算法概述
  12. 在Windows上安装虚拟机详细图文教程
  13. Mangos与mmorpg(转自百科)
  14. 夸奖对方代码写的好_形容夸人的成语有哪些
  15. CM201-1广东移动盒子YS版(易视腾代工)TTL方式保留原系统 或不保留原系统方法
  16. Java核心技术大会|Java应用开发专场
  17. 超级马里奥代码_任天堂源代码泄露,引出超级马里奥64隐藏24年的角色
  18. 十进制转8421_BCD码
  19. 一个简单的神经网络,三种常见的神经网络
  20. 北师大计算机在线作业9,北师大网络教育《计算机动画》在线作业-20210614020942.pdf-原创力文档...

热门文章

  1. 【超详细】Anaconda简介、下载及安装教程(Windows 64位系统)
  2. 浅谈我用过的有限元软件-第一弹
  3. tkinter事件绑定方法总结
  4. mysql xor详细_PHP MySQL应用中使用XOR运算加密算法分享
  5. Qt压缩解压缩zip文件,解压缩加密zip文件
  6. 【面试】Java 反射机制(常见面试题)
  7. mysql 各部门前三薪资_选出每个部门薪资前三的员工的信息
  8. 【论文泛读123】跨语言情感检测
  9. SAP生产订单实现多套工艺路线切换
  10. 公司子系统整合统一登录的架构