需要了解下Linux和c语言基础,主要用到的工具 ffmpeg
安装 ffmpeg
mac 环境下推荐 brew 方式, 其他环境推荐使用源码方式下载安装
-
可以选择 git 下载,慢的话用 http方式下载快照版本
编译 ffmpeg
如果出现操作权限不够,可以同过在命令前面加 sudo 提高权限
1
2
3
4
5
6// 指定安装目录 /usr/local/ffmpeg,设置debug模式3
./configure -prefix=/usr/local/ffmpeg -enable-debug=3
// 指定 4核模式
make -j 4
// 安装
make install
直播客户端处理流程
共享端
- 音视频采集
- 音视频编码
观管端
- 音视频解码
- 音视频渲染
音频
音频数据流
采集的音视频数据为 PCM 数据
- PCM 原始数据
- acc/mp3 编码
- mp4/flv 封装生成多媒体文件
声音的三要素
- 音调 由震动的频率快慢决定
- 音量 由振幅的高低决定
- 音色 影响的决定因素是谐波
音频的原始数据格式
- PCM
- WAV 此格式是在PCM数据套上指定格式头部信息
量化基本概念
- 采样大小:一个采样放置多少bit数据。通常16bit
- 采样率:采样频率8k,16k,44.1k,48k(1s钟采样次数)
- 声道数:单声道,双声道,多声道
码率计算
要算一个PCM音频流的码率是一件很轻松的事情,采样率x采样大小x声道数。
例如:采样率为44.1KHz,采样大小为16bit,双声道的 PCM 编码的WAV文件,它的码率为44.1Kx16x2=1411.2Kb/s.
音频采集
通过 ffmpeg 封装的api对Android,ios,pc 等端 采集,不需要了解各端的具体api
1 | // 通过avfoundation库对 mac 端音频采集,不同端采集命令会有所不同 |
音频压缩
有损压缩:压缩后去除冗余信息(人类听觉范围之外的频段),并且无法恢复成未压缩前的状态
无损压缩:编码压缩后,可以通过解码还原会压缩前的状态
熵编码
- 哈夫曼编码
- 算数编码
- 香浓编码
常见的音频编码器
OPUS>AAC>Ogg>other
- OPUS 较新,比较强
- AAC 直播应用,成熟应用范围广(取代mp3)
- Ogg
- Speex
- iLBC
- AMR
- G.711 固话应用
AAC规格描术
- AAC LC :(Low Complexity) 低复杂度规格,码流是128k,音质好。
- AAC HE:等于 AAC LC + SBR (Spectral Band Replication)。其核心思相是按频谱分保存。低频编码保存主要成分,高频单独放大编码保存音质。码流在64k左右
- AAC HE V2:等于 AAC LC + SBR + PS(Parametric Stereo)。其核心思相是双声道中的声音存在某种相似性,只需存储一个声道的全部信息,然后,花很少的字节用参数描述另一个声道和它不同的地方。
AAC格式
- ADIF ( Audio Data Interchange Format )
这种格式的特征是可以确定的找到这个音频数据的开始,只能从头开始解码,不能在音频数据流中间开始。这种格式常用在磁盘文件中 - ADTS( Audio Data Transport Stream
这种格式的特征是每一帧都有一个同步字,所以可以在音频流的任何位置开始解码。它类似于数据流格式。
ffmpeg 生成 AAC 文件
1 | //-vn 没有视频 指定音频编码器 libfdk_aac,-profile 设置编码器参数, 采样率 44100 |
什么是音频重采样 ?
将音频三元组(采样率,采样大小和通道数)的值转成另外一组值
例如:将 44100/16/2 转成 48000/16/2. 三要素任何一个或多个发生变化,都叫做重采样
为什么要重采样
- 从设备采集的音频数据与编码器要求的数据不一致、
- 扬声器要求的音频数据与要播放的音频数据不一致
视频
- 由一组图像组成
- 为了传输/占用更小的空间而被压缩
- 最终在显示设备上展示(未被压缩)
图像
像素
位深
- RGB24位
- RGBA32位
RGB
每个像素由红绿蓝三个发光二极管组成
分辨率
屏幕的横向像素与纵向像素比
图像与屏幕的关系
- 图像是数据
- 屏幕是显示设备
- 图像数据经过驱动程序让屏幕显示图像
RGB的色彩问题
图片会展示色彩不一致问题
- RGB 与 BGR
- BMP 使用的是 BGR格式,需要进行转换
屏幕指标
PPI ( pixels per inch )
每英寸的像素数
DPI ( Dots pen inch )
每英寸的而点数(每个点对应指定像素)
PPI >300 就属于视网膜级别
分辨率
- X轴的像素个数xY轴的像素个数
- 常见的宽高比 16:9 /4:3 (屏比不同需要转换)
- 370p,720p,1k,2k
帧率
- 每秒钟采集/播放图像的个数
- 动画的帧率是25帧/s
- 常见的帧率:15帧/s(可满足视频通话),30/s,60帧/s
未编码视频的RGB码流
RGB码流 = 分变率(宽x高)x 3(Byte) x 率(25帧)
例如:1280x720x3x25 =69120000 约 69M
图像的显示
- 图像大小等于显示区域大小
- 图像小于显示区域(拉伸/留白)
- 图像大于显示区域(缩小/截断)
YUV
电视图像格式
- YUV(也称YCbCr):Y 表示明亮度,UV 的作用是描述影像色彩及饱和度
- 主要的采样格式有YUV4:2:0、YUV4:2:2和YUV4:4:4 (可能需要转为前面两种格式)
RGB与YUV的关系
- RGB用于屏幕图像的展示
- YUV用于采集与编码
RGB转YUV
Y=0.299*R +0.587*G+0.114*B
U=-0.147*R-0.289*G+0.436*B =0.492*(B-Y)
V=0.615*R-0.515*G-0.100*B =0.877*(R-Y)
YUV转RGB
R=Y+1.140*V
G=Y-0.394*U-.581*V
B=Y+2.032*U
YUV常见格式
YUV4:4:4
YUV4:2:2
YUV4:2:0(最广泛)
4:2:0并不意味着只有Y、Cb两个分量,而没有Cr分量。它实际指得是对每行扫描线来说,只有一种色度分量,它以2:1的抽样率存储相邻的扫描行存储不同的色度分量,也就是说,如果一行是4:2:0的话,下一行就是4:0:2,再下一行是4:2:0…以此类推
数据量的计算
电视从黑白电视(YUV)发展到彩色电视(RGB),为了兼容以前的格式。所以要使用YUV
- YUV =Y*1.5
- YUV = RGB/2
未编码视频的YUV码流
- RGB码流 =分辩率(宽x高)x 3x 率
- YUV码流 =分辩率(宽x高)x 1.5x 率
生成YUV
1 | ffmpeg -i jjjr.mp4 -an -c:v rawvideo -pix_fmt yuv420p out.yuv |
播放YUV
1 | // 需要指定生成时的清晰度和分辨率 |
播放Y 分量
y分量存储的是黑白视频信息,单独播放U,V 分量播放没有显示颜色
1 | ffplay -pix_fmt yuv420p -s 1280x720 |
h264编码
H264压缩比
条件:
- YUV格式为 YUV420
- 分辨率为 640x480
- 帧率为 15
建议码流:500kpbs
结果:约1/100
GOP
强相关视频帧分组,GOP中帧与帧之间的差别小
编码帧分类
- I(intraframe frame),关键帧,采用内压缩技术。IDR帧属于I帧
- P (forward Predicted frame),前参考。压缩时,只参考前面已经处理的帧,采用帧间压缩技术。它占顿的一半大小
- B (Bidirectionally predicted frame),双向参考。压缩时既参考前面已经处理的帧,也参考后面的帧,间压缩技术。它占I帧1/4大小
IDR帧与I顿的区别与联系
- IDR(Instantaneous Decoder Refresh)解码器立即刷新
- 每当遇到IDR 帧时,解码器就会清空解码器参考buffer中的内容每个
- GOP 中的第一帧就是 IDR
- IDR 帧是一种特殊的I帧
H264压缩技术
- 帧内压缩,解决的是空域数据几余问题
- 帧间压缩,解决的是时域数据几徐问题
- 整数离散余弦变换(DCT),将空间上的相关性变为频域上无关的数据然后进行量化
- CABAC压缩
Profile与Level
- H264 Profile
对视频压缩特性的描述,Profile越高,就说明采用了越高级的压缩特性 - H264 Level
Level是对视频的描述,Level越高,视频的码率、分辨率、fps越高
RTMP协议
FLV协议
就是RTMP协议加上了 flv header
Nginx 搭建流媒体服务器
1 | wget https://github.com/arut/nginx-rtmp-module/archive/v1.2.1.zip |
安装踩坑总结
1 | ./configure: error: C compiler cc is not found |
make 命令报错
1 | sudo apt install make |
nginx配置文件
与http 同层级
1 | rtmp { |
检测nginx
访问nginx 地址 会出现 welcome 界面
查看 1935 端口是否在监听
1 | netstat -an |grep 1935 |
推流与拉流
ubuntu 系统下可以直接拉流播放
1 | 推 |
SRS介绍
SRS( Simple Rtmp Server),它是单进程实现的。在同一台服务器上可以起动多个进程同时提供服务。
它的定位是运营级的互联网直播服务器集群,它提供了非常丰富的接入方案,支持 RTMP、HLS、HTTP-FLV等。
国内开源项目
VHost
- 支持多客户
- 支持多配置
- 域名调度
Vhost配置
1 | listen 1935; |
功能说明:
1、WEB无插件开发包是基于标准HTML5技术开发,在不使用插件的情况下,为大华各类网络摄像机、球机、NVR等产品提供音视频播放二次开发服务。
2、该方案使用Websocket+RTSP/RTP推流,WASM解码方式进行音视频的解码播放,具有高安全性、可扩展性和跨平台等特点;支持H264,H265等视频编码模式;适用于谷歌、火狐、safari、Edge浏览器。
3、支持搭建nginx代理服务实现云台、录像查询等业务。
WEB3.3控件开发包 V3.3,登陆后下载
HCWebSDK,以 JavaScript 接口形式提供用户集成,支持网页上实现预览、回放、云台控制等功能。支持Win32&Win64,支持的浏览器:Chrome57+、Firefox52+。
给你推荐两个毫秒级方案:
\1. github搜webrtc-streamer,拉rtsp流转webrtc播放
\2. ffmpeg转flv rtmp推到SRS流媒体服务器,从SRS上拉webrtc流播放
- 本文作者: 王不留行
- 本文链接: https://wyf195075595.github.io/2023/10/31/programming/音视频/基础知识/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!