首先我们来初步认识一些名词,了解一些流媒体技术相关的基本概念,其次通过一个实例加深对基本概念的理解和记忆。
| 名词 | 说明 |
|---|---|
| AVI | Audio Video Interleave,音频视频交错 |
| MPEG | Moving Picture Experts Group,现泛指一系列视频编码标准正式审核程序 |
| RMVB | RealMedia Variable Bitrate,多媒体封装格式的一种动态比特率扩展 |
| MP4 | MPEG-4第14部分的一种标准数字多媒体容器格式 |
| MOV | 即QuickTime的影片格式用于存储常用数字媒体类型 |
| FLV | FLASH VIDEO,用作流媒体格式 |
| WebM | Google提出的开放免费的媒体文件格式 |
| WMV | Windows Media Video,微软开发的一组数字影片的编解码格式 |
| MKV | Matroska媒体系列中的一种文件格式 |
| H.264 | 一种较流行的视频压缩标准 |
| MPEG-4 | 一套用于音频、视频信息的压缩编码的国际标准 |

| 概念 | 说明 | 补充说明 |
|---|---|---|
| 帧 | 可以简单理解对于每一张图片或画面都可以理解成是一帧 | 暂无 |
| 帧率FPS | 每秒钟播放的图片数画面数,比如FPS 120那就是每秒切换播放了120张图片 | 可以理解成每秒传输的帧数 |
| 像素 | 图片由像素构成,每个像素由RGB组成,每个8位,三原色构图共24位 | 像素便是一个图像中的最小单位 |
| 视频 | 个人观点单位时间内同一像素下由N帧组成的内容呈现 | 暂无 |
| 视频编码 | 根据各种算法将视频压缩的一个过程 (视频为何要编码?减小视频占用的容量大小,视频的编码过程本身就是一个压缩的过程。) | 将原始视频格式转换为另一种视频文件格式的形式 |
| 流派 | 主流俩大类,ITU的VCEG,ISO的MPEG | ITU与MPEG联合制定了H.264/MPEG-4 AVC |
| 接流 | 使用某一网络协议将编码完毕的视频流从主播端传到服务器端的过程 | 个人理解对服务端来说是接流,对主播端来说是推流操作 |
| 转码 | 服务器端接到视频流后对视频流进行一定的处理,从一个编码格式转换为另一个编码格式的过程 | 因为客户端存在差异性的原因 |
| 拉流 | 流处理完毕之后,客户端请求视频资源的过程 | 暂无 |
| 分发网络 | 如果某一时间段内请求该视屏资源的观众非常多,那么从单一服务器节点上拉流导致节点压力大,所以加入分发网络也就是CDN,将资源预先加载到CDN的边缘节点 | 可以显著降低真实服务器的压力,提升用户质量 |
| 解码 | 当客户端将视频拉下来后就需要解码才能播放,将二进制文件转换为视频的过程 | 暂无 |
| I帧 | Intra-coded picture 关键帧,里面是完整的图片 | 最完整,只需要本帧即可完成解码 |
| P帧 | Predictive-coded Picture 前向预测编码帧,表示这一帧和之前一个I帧或P帧的差别 | 解码的时侯需要用之前缓存的画面叠加上和本帧定义的差别才可以生成最终的画面 |
| B帧 | Bidirectionally predicted picture 双向预测内插编码帧,记录本帧与前后帧的区别 | 通过前后画面的数据与本帧数据的叠加才能取得最终画面 |
| DTS | Decoding Time Stamp 解码时间戳 | 告诉播放器该在什么时候解码这一帧的数据 |
| PTS | Presentation Time Stamp 显示时间戳 | 告诉播放器该在什么时候显示这一帧的数据 |
| NALU | 网络提取层单元,二进制流的结构是由一个个的NALU组成的 | 这种格式就是为了传输,按照帧和片依次排列 |
| NALU Type | 在NALU头里面,0x07表示SPS,序列参数集,包括一个图像序列的所有信息,0x08表示PPS,图像参数集,包括一个图像的所有分片的所有相关信息 | 在传输视频流之前必须传输这俩个参数,否则无法解码 |
| 推流 | 将二进制数据流打包成网络包传输到对端 | 将NALU放到Message里面发送,这个也被称为RTMP Packet包 |
| RTMP | RTMP通过协商版本号,时间戳来建立连接 | 一般RTMP的包会被拆分成Chunk进行传输 |
这里又涉及到直播的三种常见协议,这里简单总结对比下。
| RTMP | HTTP-HLS | HTTP-FLV | |
|---|---|---|---|
| 协议 | TCP长连接 | HTTP短连接 | HTTP长连接 |
| 基本原理 | 每个时刻收到的数据立即转发 | 集合一段时间内的数据生成ts切片,更新索引 | 同RTMP相似 |
| 延时 | 1~3s | 5~20s | 1~3秒 |
| web支持 | 网页中需要插件 | 支持网页访问 | 网页中需要插件 |
| 其它 | 延迟小适合交互强的直播 | 延迟大适合交互较弱的直播 | 延迟小适合交互强的直播 |
[root@iZ2ze0a8w2ct7mzctse5r5Z ~]# cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
1.需要下载nginx的nginx-rtmp-module模块用来支持RTMP协议
git地址:https://github.com/arut/nginx-rtmp-module
编译安装添加参数:--add-module=/path/to/nginx-rtmp-module
Tengine编译安装过程此处省略~
2.修改nginx的配置文件
[root@iZ2ze0a8w2ct7mzctse5r5Z src]# cat /usr/local/tengine/conf/nginx.conf
在配置文件中http的server区域添加如下
location /hls { //配置推流地址
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias /data/wwwroot/hls;
expires -1;
add_header Cache-Control no-cache;
}
location /stat { //推流状态查看
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
root /usr/local/extend_module/nginx-rtmp-module/;
}
在配置文件http区域之后添加rtmp区域
rtmp {
server {
listen 1935; //监听端口1935
chunk_size 4096; //chunk的大小设定
application hls {
live on;
hls on; //实时回访
hls_path /data/wwwroot/hls; //媒体块的存放位置,这个目录是安装完nginx自建的
hls_fragment 3s; //每个ts文件为3秒
}
}
}
3.检测nginx的配置文件并重启
[root@iZ2ze0a8w2ct7mzctse5r5Z ~]# nginx -t
nginx: the configuration file /usr/local/tengine/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/tengine/conf/nginx.conf test is successful
[root@iZ2ze0a8w2ct7mzctse5r5Z ~]# systemctl reload nginx.service
1.mac下的软件下载
wget https://cdn-fastly.obsproject.com/downloads/obs-mac-24.0.2-installer.pkg
2.使用
操作很简单,但是这里需要注意设置中推流的服务器和串流密钥的设置
举例:
服务器:rtmp://47.94.38.112:1935/hls
串流密钥:ssxx
那么访问的地址就是:http://DomainName(域名)/hls/ssxx.m3u8
希望大家能和我一样通过这个例子对视频直播流媒体技术相关的基础概念有一个基本的认知
也希望我花时间整理的文章能帮到大家。~~~
| 编码名词 | 说明 |
|---|---|
| 空间冗余 | 图像的相邻像素之间有较强的关联性,一张图片相邻的像素基本是渐变的不是突变的,所以没必要每个像素都完整的保留 |
| 时间冗余 | 视频中相邻图片之间的内容相似,连续出现的图片也不是突变的,可以根据已有的图片进行预测和推断 |
| 视觉冗余 | 人的视觉系统允许某些细节的丢失也就是允许丢失一些数据 |
| 编码冗余 | 不同像素值出现的概率不同,概率高的用的字节少,概率低的用的字节多 |
| 帧内预测 | 去除空间冗余 |
| 帧间预测 | 去除时间冗余 |
| 变换 | 去除空间冗余 |
| 量化 | 去除视觉冗余,通过降低图像质量提高压缩比 |
| 熵编码 | 去除编码冗余 |
| GOP | 关键帧间隔,从I帧开头到下一个I帧结束,是一些按顺序排序的图像帧的组合。GOP值,表示俩个关键帧之间的间隔 |
| I帧 | 关键帧里面是完整的图片,只需要本帧数据即可以完成编码 ;帧内编码帧,无需参考其他图像可以进行独立编码,也就是说是不依赖前后帧的独立的一帧图像 |
| P帧 | 前向预测编码帧,表示这一帧和前一关键帧的差别,解码时需要用之前缓存的画面叠加和本帧定义的差别生成最终画面;需要参考I帧才能进行编码,采用运动预测的方式进行帧间编码,基于帧间预测计算得到的帧 |
| B帧 | 双向预测内插编码帧,记录本帧与前后帧的差别,要解码B帧需要前后画面的数据与本帧数据的叠加取得最终画面;采用运动预测的方式进行帧间双向预测编码 |
| NALU | Network Abstraction Layer Unit,网络提取层单元,H264的基本结构,由起始标志符和NALU头和Palyload承载的数据构成 |
| 原始码流 | 由一个接一个的NALU组成,我的理解NALU序列 |
| 片 | 在一帧中分成多个片 |
| 宏块 | 在一片中分成多个宏块 |
| 子块 | 在一个宏块中分成多个子块,这样做的目的是为了方便进行空间上的编码 |
| NALU头 | 0x07表示SPS序列参数集,包含一个图像序列的所有信息;0x08表示PPS图像参数集,包含一个图像的所有分片的所有信息 |
| pts | 表示该帧播放的相对时间戳 |
| dts | 表示该帧解码的相对时间戳 |
在字节大小方面,P帧,B帧远小于I帧,GOP太大会导致首屏播放时间变长,GOP太小会导致I帧的比例增大,压缩比降低,同码率下视频播放的质量降低。理论上pts是单调递增的,推流源流时间戳异常会导致pts突变。也会导致录制的时长有问题,导致转码水印异常,花屏等问题。
如何修复录制文件:
1.剔除异常帧。
2.对记录的每个视频帧重新设置pts。
1.查看一个视频中关键帧的分布情况:
ffprobe -v error -show_frames "rtmp://rtstest.kivensu.club/rtstest0211/rtstest0211?auth_key=1644576853-0-0-635196d1093d1d1f980e427c9bd7af76" | grep pict_type
2.查看pts,dts。
ffprobe -show_frames https://cloud.video.taobao.com/play/u/null/p/1/e/6/t/1/d/ud/344704485848.mp4
pkt_pts=1945600
pkt_dts=1945600
3.视频截取
use stream copying & input seeking
ffmpeg -ss 00:01:01 -i gemfield.mp4 -t 4 -c copy cut1.mp4
use stream copying & output seeking
ffmpeg -i gemfield.mp4 -ss 00:01:01 -t 4 -c:v copy cut2.mp4
use transcoding & input seeking
ffmpeg -ss 00:01:01 -i gemfield.mp4 -t 4 -c:v libx264 cut3.mp4
use transcoding & output seeking
ffmpeg -i gemfield.mp4 -ss 00:01:01 -t 4 -c:v libx264 cut4.mp4
我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在
我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e
需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc
动漫制作技巧是很多新人想了解的问题,今天小编就来解答与大家分享一下动漫制作流程,为了帮助有兴趣的同学理解,大多数人会选择动漫培训机构,那么今天小编就带大家来看看动漫制作要掌握哪些技巧?一、动漫作品首先完成草图设计和原型制作。设计草图要有目的、有对象、有步骤、要形象、要简单、符合实际。设计图要一致性,以保证制作的顺利进行。二、原型制作是根据设计图纸和制作材料,可以是手绘也可以是3d软件创建。在此步骤中,要注意的问题是色彩和平面布局。三、动漫制作制作完成后,加工成型。完成不同的表现形式后,就要对设计稿进行加工处理,使加工的难易度降低,并得到一些基本准确的概念,以便于后续的大样、准确的尺寸制定。四、
2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p
Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图
我有一个ActiveRecord对象,我想在不对模型进行永久验证的情况下阻止它被保存。您过去可以使用errors.add执行类似的操作,但它看起来不再有效了。user=User.lastuser.errors.add:name,"namedoesn'trhymewithorange"user.valid?#=>trueuser.save#=>true或user=User.lastuser.errors.add:base,"myuniqueerror"user.valid?#=>trueuser.save#=>true如何在不修改用户对象模型的情况下防止将用户对象保存在Rails3.2中
目前我正在使用这个正则表达式从YoutubeURL中提取视频ID:url.match(/v=([^&]*)/)[1]我怎样才能改变它,以便它也可以从这个没有v参数的YoutubeURL获取视频ID:http://www.youtube.com/user/SHAYTARDS#p/u/9/Xc81AajGUMU感谢阅读。编辑:我正在使用ruby1.8.7 最佳答案 对于Ruby1.8.7,这就可以了。url_1='http://www.youtube.com/watch?v=8WVTOUh53QY&feature=feedf'url
我有一个正在HerokuCedar堆栈上部署的Rails3.2应用程序。这意味着应用程序本身负责为其静态Assets提供服务。我希望对这些Assets进行gzip压缩,所以我在production.rb的中间件堆栈中插入了Rack::Deflater:middleware.insert_after('Rack::Cache',Rack::Deflater)...curl告诉我这与宣传的一样有效。但是,由于Heroku将全力运行rakeassets:precompile,生成一堆预gzipAssets,我很想使用它们(而不是让Rack::Deflater再次完成所有工作)。我已经看到使用
使用rubyonrails,我想做类似的事情:@tasks=Task.where(:def=>true||:house_id=>current_user.house_id)执行此操作的最有效/最干净的方法是什么? 最佳答案 你可以这样做:Task.where("def=?orhouse_id=?",true,current_user.house_id)一般情况是:Model.where("column=?orother_column=?",value,other_value)您还可以利用Arel:t=Task.arel_tabl