一、视频技术
1. 简介
视频是一种有结构的数据。直播的时候传的是数据,是视频的一个小单元。
视频 = 图像 + 音频
-
视频里边的原始图像数据 通常会采用“H.264编码格式” 进行压缩。
-
音频采样数据 通常会采用“AAC编码格式” 进行压缩。
2. 视频的实时传输
-
-
实时发生的事(直播)肯定是有延迟的。我们要提高直播的质量就需要减小延迟。
3.
-
-
在直播的时候传输的视频数据通常都要压缩(编码),传输数据的量是越少越好,播放的时候需要解压(解码/还原)。
4. 视频解码压缩
-
-
编码和解码之前,需要约定一种编码器和解码器都可以理解的约定。
- 例如,视频图像编码和解码过程:
编码器将多张图像进行编码后生成一段一段的GOP(Group of Pictures),传输的是GOP(Group of Pictures),解码器在播放时则是读取一段一段的GOP进行解码后读取画面再渲染显示。
GOP:表示一组图片(即一组连续的画面),是视频图像编码器和解码器存取的基本单位,由一张I帧和数张B/P帧组成(I帧又叫关键帧,B/P帧又叫参考帧过渡帧),它的排列顺序将会一直重复到影像结束。
5. 视频怎么传输?
-
-
将视频分成分子(GOP),再将分子分成原子(I帧、B帧、P帧)。
——— 这种体验就类似于直播。
6.
7.
主播端
——RTMP协议——》直播流媒体服务器
——RTMP/HLS协议——》观众(粉丝)
- RTMP协议:延时比较小,传输速度比较快。(主播录视频用这个协议,把视频数据即时传到服务器上)
- HLS协议:把主播已经传好的视频流切片,切片之后再给粉丝传输。(根据时间点去播放,粉丝播放视频用这个协议,回看也用这个协议)
协议差异:
- RTMP(Real Time Messaging Protocol)协议:是一个TCP协议(长连接),每个时刻的数据,收到后立刻转发,延时 1~3秒。
- HLS(HTTP Live Streaming)协议:是一个HTTP协议(短连接),集合一段时间数据,生成ts切片文件,更新m3u8,延时大于10秒。
- RTMP-FLV(RTMP over HTTP)协议:是一个HTTP协议(长连接),同RTMP,使用HTTP协议,延时1~3秒。
8. 延迟(Delay)
- 物理延迟
- 延迟指稳定网络下,发送和接收时差。
- 转发环节越多,延迟越大。
- 可计算。
- 延迟跟服务器的转发数 / 主播与粉丝直接的距离有关。
- 抖动(Jitter)延迟
- 抖动,信号会不好。
9. 直播过程
从推流到播放,再经过中间转发环节,延迟越低,则用户体验越好。
10.
软编的意思是,资源消耗的是CPU,通过一些软件代码的模式去编码。(一般用软编)
硬编的意思是,资源消耗的是GPU,GPU就相当于是显卡/显示的功能。(好手机不卡,坏手机很卡)
二、直播/
视频端的播放用 ijkplayer,ijkplayer 是B站(bilibili)开源的第三方框架。ijkplayer 已经帮我们集成好了 FFmpeg。
- FFmpeg 是音视频处理工具,既有音视频编码解码功能,又可以作为播放器使用。
- 任何播放器都是基于FFmpeg的。苹果提供的AVPlayer,播放不了直播文件/播放不了直播格式(如,RTMP的播放不了,可以用 ijkplayer 去播放)。所以真正的要基于 FFmpeg 去播放,B站帮我们封装好了,所以我们使用 ijkplayer。
- 斗鱼也用的这个,到公司如果不想花钱也可以用这个(ijkplayer)。
- ijkplayer 只能播放,不能推流。
VLC:视频播放器,编码格式多(支持的格式多,可以播直播格式的 rtmp://,一般可以用来测试直播地址)。
测试地址:rtmp://live.hkstv.hk.lxdns.com/live/hks (提示:用Safari打开,会自动加入到VLC播放列表中去)
2. ijkplayer 的使用
-
第一步:配置好依赖环境:下载 FFmpeg,编译FFmpeg。(即如何把 ijkplayer自带的 IJKMediaDemo 运行起来)
2) 来到README.md文档的 Build iOS 处,按步骤进行操作
3) 克隆项目:git clone https://github.com/Bilibili/ijkplayer.git ijkplayer-ios
4) 先进入ijkplayer-ios目录: cd ijkplayer-ios
,执行: git checkout -B latest k0.7.7.1
5) 再执行: ./init-ios.sh
(意思是去下载 FFmpeg)
(ijkplayer 是基于FFmpeg的,由于FFmpeg比较大,所以要单独去下载,下载比较慢)
6) 下载完后,进入ios目录: cd ios
,准备编译FFmpeg。
7) 编译FFmpeg,需执行以下命令:
./compile-ffmpeg.sh clean
./compile-ffmpeg.sh all
8) 编译成功后,我们就可以运行 IJKMediaDemo 了。
-
第二步:将 IJKMediaPlayer(播放器)项目打包成 framework(方便集成到自己的项目中去)
如何把视频播放器集成到自己的项目中去?
把一个工程集成到另一个工程一般有两种方法:
1)工程里集成工程。(这种方法比较麻烦、重量级,不推荐使用)
2)把要集成的工程所有的源码打包成一个framework,我们只需要集成这个framework到其它项目即可。(推荐)
生成framework的步骤:
1)打开 IJKMediaPlayer 项目
2)修改工程的编译模式为 Release (因为framework不需要调试,他的代码已经写好了的,不需要去修改,所以直接生成release版的framework)
3)编译一个模拟器版本的framework
4)再编译一个模拟器版本的framework
5)最后将这两个framework合并成一个framework,这样就能保证这个framework既可以在模拟器上运行,又可以在真机上运行。
合并文件命令: lipo -create "真机版本路径" "模拟器版本路径" -output "合并后文件的路径"
6)替换文件:复制合并后的IJKMediaFramework文件到模拟器版/真机版framework中进行替换。
3. 导入 ijkplayer 播放器的 framework
1)直接拖拽framework进行导入
2)添加 ijkplayer 的一些依赖库
########################################################
AudioToolbox.framework
AVFoundation.framework
CoreGraphics.framework
CoreMedia.framework
CoreVideo.framework
libbz2.tbd
libz.tbd
MediaPlayer.framework
MobileCoreServices.framework
OpenGLES.framework
QuartzCore.framework
UIKit.framework
VideoToolbox.framework
########################################################
如果编译报以下错误:
This is a linker error. You can resolve it by adding "-lc++" to Other Linker Flags in your Build Settings.
解决办法:Build Settings —》Other Linker Flags —》 添加 -lc++
4. 集成ijkplayer
初始化播放器,设置相关属性。
5. 创建直播播放界面和直播聊天界面