视频点播、视频编码、多媒体容器文件、HLS 你知道多少?

650 阅读16分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

1、视频点播 VOD

VOD代表Video on Demand(视频点播),这种视频流化和交付技术使人们可以随时随地在任何设备上立即观看视频。其中视频点播有多种类型:

AVOD:Advertising-based VOD 广告型视频点播

TVOD:Transactional VOD 交易型视频点播

SVOD:Subscription VOD订阅型视频点播

PVOD:Premium VOD 优质视频点播

基于不同收费策略的Freemium VOD

AVOD

AVOD(广告型视频点播)是一种将广告插入到视频中进行收费的策略。用户不必付费或者订阅服务就可以免费观看内容。点播公司的所有收入通过插入广告来获取。YouTube就在此列,它通过向内容中插入广告来产生几乎所有收入。

SVOD

SVOD(订阅型视频点播)中,用户被要求支付订阅费用,才能访问内容提供商的内容库。这种收费是经常性费用(需要按月或者按年支付)。Netflix就是典型的SVOD模式。

TVOD

TVOD(交易型视频点播)是一种基于租赁的VOD收费商业模式,其中用户通过付费租用内容或者在短时间内访问服务,也被称为“按次付费”(Pay Per View)。DAZN是典型的TVOD模式,上面有好几场按次付费的拳击比赛。

PVOD

PVOD(优质视频点播)是TVOD或SVOD的一种形式,选择PVOD模式的用户可以比其他TVOD或SVOD用户更快访问内容!

电影一般先以PVOD模式发行,过了一段时间之后,其他订阅用户可以通过SVOD或者TVOD访问内容。迪士尼的《花木兰》是典型的PVOD ,它最初作为 PVOD 电影发行,由于新冠疫情而跳过了影院,直接在线上放映。

Freemium VOD

通常情况下,Freemium VOD结合了AVOD和SVOD这两种商业模式。举个例子,一个用户可以免费观看插入广告的视频。但是,如果这个用户选择升级到付费订阅,那么就可以免广告。或者内容库中的一部分内容可以在插入广告的情况下免费观看,其他内容只向付费订阅用户开放。

2、多媒体容器文件

什么是 MP4?

MP4 是一种多媒体文件存储格式,最常用于存储视频。MP4 用途广泛,适用于多种设备。从技术上讲,MP4 是一种多媒体容器文件,包含压缩的视频数据和播放视频所需的其他相关数据,但 MP4 只是视频的包装,而不是视频本身。

MP4 文件的压缩率通常比其他视频文件类型更高,因此也更小。MP4 文件内的视频内容使用 MPEG-4(一种常见的编码标准)进行编码

什么是 MOV?

MOV 是视频和其他多媒体的另一种多媒体容器文件。Apple 开发了 MOV 供 Apple QuickTime Player 使用。与 MP4 文件一样,MOV 视频使用 MPEG-4 编解码器进行编码。

MOV 和 MP4 有什么区别?

这两种容器格式的主要区别在于:

  1. MOV 用于 QuickTime 的专有 Apple 文件格式;
  2. MP4 是国际标准

大多数流媒体平台建议使用 MP4 文件而非 MOV,因为 MP4 文件兼容更多流媒体协议。

MP4 通常压缩程度较高且文件较小,而 MOV 文件通常质量较高且大小较大。MOV 文件是专为 QuickTime 设计的,因此更适合用于 Mac 上的视频编辑。

什么是多媒体容器文件?

我们熟悉的mp4,rmvb,mkv,avi... ...都是多媒体容器文件格式(或称多媒体封装格式),所谓容器是指将不同的数据流(视频流音频流字幕流等)封装在一个文件(载体)中。

[多媒体容器格式变迁史](多媒体容器格式变迁史 - 知乎 (zhihu.com))

3、什么是视频编解码

不得不说的 MPEG 与 H.26x

先来熟悉几个组织

  • ITU,国际电报联盟(International Telegraph Union) ,1865年成立
  • IEC,国际电工委员会(The International Electrotechnical Commission) ,1906年成立
  • ISO,国际标准化组织(International Organization for Standardization) ,1947年成立,就是推出ISO9001质量认证的那个
  • MPEG,动态图像专家组(Moving Picture Expert Group) ,1988年由ISO和IEC联合成立的一个专家组,负责开发电视图像数据和声音数据的编码、解码和它们的同步等标准。
  • JVT,视频联合工作组(oint Video Team) ,由ITU和ISO/IEC联合成立

世界上主流的视频编码标准,基本上都是它们提出来的。

  • ITU提出了H.261H.262H.263H.263+H.263++,这些统称为H.26X系列,主要应用于实时视频通信领域,如会议电视、可视电话等。

  • ISO/IEC联合专家组MPEG提出了MPEG1MPEG2MPEG4 ...,统称为MPEG系列。 其中:

  • MPEG-1(制定于1992年,常用于VCD制作格式)

  • MPEG-2(制定于1994年,常用于DVD制作格式)与 H.262标准一致。

  • MPEG-4(制定于1998年,常用于 DVD 和早期蓝光光盘的标准编解码器,它不常用于流媒体视频。)

H.264则是由两个组织联合组建的联合视频组(JVT)共同制定的新多媒体视频编码标准

  • 它既是ITU-T的H.264

  • 又是ISO/IEC的MPEG-4高级视频编码(Advanced Video Coding,AVC)的第10 部分。

因此,不论是以下哪种名称都是指H.264

  • MPEG-4 AVC
  • MPEG-4 Part 10
  • ISO/IEC 14496-10

ITU和ISO/IEC一开始是各自捣鼓,后来,两边成立了一个联合小组,名叫JVT(Joint Video Team,视频联合工作组)

JVT致力于新一代视频编码标准的制定,后来推出了包括H.264在内的一系列标准,如H.265等...,因现在互联网上兼容最高的是H.264,而H.265的兼容性并不高,所以里就不展开说了,有兴趣的可以自行查阅相关内容。

image.png 「完全理解」video 标签到底能播放什么 - 知乎 (zhihu.com)

H.264如何成为主流标准的

因为苹果公司当初毅然决然抛弃了Adobe的VP6编码,选择了H.264,这个标准也就随着数亿台iPad和iPhone走入了千家万户,成为了目前视频编码领域的绝对霸主,占有超过80%的份额。

随着互联网视频服务的快速崛起,各类智能电子设备都陆续支持视频网络下载及播放。H.264标准一直是网络视频的主要压缩技术之一,且在又有逐步取代Flash视频格式的发展趋势。其主要支持者,是微软的IE浏览器和苹果公司的系列产品,前者保证了H.264在桌面设备市场的优势,后者保证了H.264在便携设备市场的优势。

Chrome 52版本增强了WebRTC H.264和DTLS

浏览器支持WebRTC H.264是IETF所要求的,并且对浏览器的互操作性以及和传统视频系统的连接性都十分的重要。

在Chrome中支持H.264最早是Google在Chrome 50版本中提出的,但是那时有很多的限制,一些限制在Chrome 52版本中的H.264实现中得到了解决。

从简单来说H.264就是一种视频编码技术

一般来说,如果动态图像数据未经压缩就使用的话,数据量非常大,容易造成通信线路障数据存储容量紧张。因此,在发送动态图像时、或者把影像内容保存在DVD上时、以及使用存储介质容量较小的数码相机或手机时,就必须使用编解码器虽然编解码器许多种类,但DVD-Video就是DVD)与微波数字电视等使用的主要是MPEG-2,数码相机等摄像时主要使用MPEG-4。

H.264视频编码标准的技术特点与优势>>>

ffmpeg

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec。

FFmpeg在Linux平台下开发,但它同样也可以在其它操作系统环境中编译运行,包括Windows、Mac OS X等。这个项目最早由Fabrice Bellard(法布里斯·贝拉是一位著名的计算机程序员)发起,2004年至2015年间由Michael Niedermayer(也是一个程序员吧)主要负责维护。许多FFmpeg的开发人员都来自MPlayer项目,而且当前FFmpeg也是放在MPlayer项目组的服务器上。项目的名称来自MPEG视频编码标准,前面的"FF"代表"Fast Forward"。

mac 电脑安装

brew install ffmpeg

安装之后

FFmpeg几个静态库的介绍

  1. libavformat:用于各种音视频封装格式的生成和解析。
  2. libavutil:核心工具库,做一些基本音视频处理操作。
  3. libavcodec:音视频各种格式的编解码。
  4. libswscale:图像进行格式转换模块。
  5. libavfilter:音视频滤镜库。
  6. libpostproc:后期处理模块。
  7. libswresample:用于音频重采样。
  8. libadvice:用于硬件的音视频采集。
  9. libavresample:这个是老版本下编译出来,新版本用libswresample代替。

将获得可执行文件:

  1. ffmpeg 用于转码、推流、dump媒体文件
  2. ffplay 用于播放媒体文件
  3. ffprobe 用于获取媒体文件信息
  4. ffserver 用于简单流媒体服务器
ffmpeg \
-i 视频源.m3u8 \
-c:v libx264 \
-c:a copy \
-f mp4 视频.mp4

如果brew install ffmpeg 安装困难 可以使用docker镜像

docker 镜像地址

jrottenberg/ffmpeg - Docker Image | Docker Hub

安装完成后

其中 /Users/11/video 是我电脑存放视频的文件路径,替换成你的路径就好

docker run -v /Users/11/video:/tmp/workdir jrottenberg/ffmpeg \
            -i 视频源.m3u8 \
            -c:v libx264 \
            -c:a copy \
            -f mp4 视频.mp4
?如何获得xxx.m3u8

我里我给大家推荐一款浏览器插件,可用于提取网页中.m3u8链接

ffprobe

ffprobe是FFmpeg项目提供的用于分析视频信息的命令行工具。

ffprobe \
-v quiet \
-print_format json \
-show_format \
-show_streams \
/files/影片名称.mp4

docker 镜像地址

sjourdan/ffprobe - Docker Image | Docker Hub

使用docker镜象进行测试使用如下命令

其中 /Users/11/video 是我电脑存放视频的文件路径,替换成你的路径就好

docker run -it --rm -v /Users/11/video:/files sjourdan/ffprobe \
    -v quiet \
    -print_format json \
    -show_format \
    -show_streams \
    /files/影片名称.mp4

执行之后结果如下:

{

    "streams": [

        {

            "index": 0,

            "codec_name": "h264",

            "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10",

            "profile": "High",

            "codec_type": "video",

            "codec_time_base": "1/60",

            "codec_tag_string": "avc1",

            "codec_tag": "0x31637661",

            "width": 1280,

            "height": 720,

            "coded_width": 1280,

            "coded_height": 720,

            "has_b_frames": 2,

            "sample_aspect_ratio": "1:1",

            "display_aspect_ratio": "16:9",

            "pix_fmt": "yuv420p",

            "level": 31,

            "chroma_location": "left",

            "refs": 4,

            "is_avc": "true",

            "nal_length_size": "4",

            "r_frame_rate": "30/1",

            "avg_frame_rate": "30/1",

            "time_base": "1/15360",

            "start_pts": 0,

            "start_time": "0.000000",

            "duration_ts": 1420800,

            "duration": "92.500000",

            "bit_rate": "4945736",

            "bits_per_raw_sample": "8",

            "nb_frames": "2775",

            "disposition": {

                "default": 1,

                "dub": 0,

                "original": 0,

                "comment": 0,

                "lyrics": 0,

                "karaoke": 0,

                "forced": 0,

                "hearing_impaired": 0,

                "visual_impaired": 0,

                "clean_effects": 0,

                "attached_pic": 0

            },

            "tags": {

                "language": "und",

                "handler_name": "VideoHandler"

            }

        },

        {

            "index": 1,

            "codec_name": "aac",

            "codec_long_name": "AAC (Advanced Audio Coding)",

            "profile": "LC",

            "codec_type": "audio",

            "codec_time_base": "1/48000",

            "codec_tag_string": "mp4a",

            "codec_tag": "0x6134706d",

            "sample_fmt": "fltp",

            "sample_rate": "48000",

            "channels": 2,

            "channel_layout": "stereo",

            "bits_per_sample": 0,

            "r_frame_rate": "0/0",

            "avg_frame_rate": "0/0",

            "time_base": "1/48000",

            "start_pts": -1024,

            "start_time": "-0.021333",

            "duration_ts": 4445192,

            "duration": "92.608167",

            "bit_rate": "128859",

            "max_bit_rate": "128859",

            "nb_frames": "4341",

            "disposition": {

                "default": 1,

                "dub": 0,

                "original": 0,

                "comment": 0,

                "lyrics": 0,

                "karaoke": 0,

                "forced": 0,

                "hearing_impaired": 0,

                "visual_impaired": 0,

                "clean_effects": 0,

                "attached_pic": 0

            },

            "tags": {

                "language": "und",

                "handler_name": "SoundHandler"

            }

        }

    ],

    "format": {

        "filename": "/files/test.mp4",

        "nb_streams": 2,

        "nb_programs": 0,

        "format_name": "mov,mp4,m4a,3gp,3g2,mj2",

        "format_long_name": "QuickTime / MOV",

        "start_time": "-0.021333",

        "duration": "92.609000",

        "size": "58778229",

        "bit_rate": "5077539",

        "probe_score": 100,

        "tags": {

            "major_brand": "isom",

            "minor_version": "512",

            "compatible_brands": "isomiso2avc1mp41",

            "encoder": "Lavf58.45.100",

            "description": "Codec by Bilibili XCode Worker v4.8.52(fixed_gap:False)"

        }

    }

}

4、HLS是什么

HTTP Live Streaming(缩写是HLS)是一个由苹果公司提出的基于HTTP的流媒体网络传输协议。​是苹果公司QuickTime X和iPhone软件系统的一部分。 它的工作原理是把整个流分成一个个小的基于HTTP的文件来下载,每次只下载一些。当媒体流正在播放时,客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源,允许流媒体会话适应不同的数据速率。

在开始一个流媒体会话时,客户端会下载一个包含元数据的extended M3U (m3u8)playlist文件,用于寻找可用的媒体流。HLS只请求基本的HTTP报文,与实时传输协议(RTP)不同,HLS可以穿过任何允许HTTP数据通过的防火墙或者代理服务器。​它也很容易使用内容分发网络来传输媒体流。

RTMP指Adobe的RTMP(Realtime Message Protocol),广泛应用于低延时直播,也是编码器和服务器对接的实际标准协议,在PC(Flash)上有最佳观看体验和最佳稳定性。

HLS指Apple的HLS(Http Live Streaming),本身就是Live(直播)的,不过Vod(点播)也能支持。HLS是Apple平台的标准流媒体协议,和RTMP在PC上一样支持得天衣无缝。

二、HLS主要的应用场景

跨平台:PC主要的直播方案是RTMP,也有一些库能播放HLS,譬如jwplayer,基于osmf的hls插件也一大堆。所以实际上如果选一种协议能跨 PC/Android/IOS,那就是HLS。

IOS上苛刻的稳定性要求:IOS上最稳定的当然是HLS,稳定性不差于RTMP在PC-flash上的表现。

友好的CDN分发方式:目前CDN对于RTMP也是基本协议,但是HLS分发的基础是HTTP,所以CDN的接入和分发会比RTMP更加完善。能在各种CDN之间切换,RTMP也能,只是可能需要对接测试。

简单:HLS作为流媒体协议非常简单,apple支持得也很完善。Android对HLS的支持也会越来越完善。

三、HLS协议详解

HLS是提供一个m3u8地址,Apple的Safari浏览器直接就能打开m3u8地址

Android则不行,需要使用html5的video标签,然后在浏览器中打开这个页面即可,譬如:

<!-- livestream.html -->
<video width="640" height="360"
    autoplay controls autobuffer
    src="http://demo.srs.com/live/livestream.m3u8"
    type="application/vnd.apple.mpegurl">
</video>

HLS协议规定 视频的封装格式是TS。

视频的编码格式为H264,音频编码格式为MP3AAC或者AC-3

除了TS视频文件本身,还定义了用来控制播放的m3u8文件(文本文件)。

HLS协议说明 HLS的m3u8,是一个ts的列表,也就是告诉浏览器可以播放这些ts文件,譬如:x.m3u8

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-ALLOW-CACHE:YES
#EXT-X-TARGETDURATION:13
#EXT-X-MEDIA-SEQUENCE:430
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:11.800
news-430.ts
#EXTINF:10.120
news-431.ts
#EXT-X-DISCONTINUITY
#EXTINF:11.952
news-430.ts
#EXTINF:12.640
news-431.ts
#EXTINF:11.160
news-432.ts
#EXT-X-DISCONTINUITY
#EXTINF:11.751
news-430.ts
#EXTINF:2.040
news-431.ts
#EXT-X-ENDLIST

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

EXT-X-VERSION 用以标示协议版本。这里是3, 那么这里用的就是HLS协议第三个版本,此标签只能有0或1个,不写代表使用版本1

EXT-X-TARGETDURATION 所有切片的最大时长,有些Apple设备这个参数不正确会无法播放。

EXT-X-MEDIA-SEQUENCE 切片的开始序号。每一个切片都有唯一的序号,相邻之间序号+1。这个编号会继续增长,保证流的连续性。

EXTINF ts 切片的实际时长。duration : 媒体持续时间

#EXTINF <duration>

EXT-X-PLAYLIST-TYPE 标记提供有关播放列表文件的可变性信息, vod 表示点播。

EXT-X-ENDLIST 文件结束符号。表示不再向播放列表文件添加媒体文件。

关于 EXT-X-PLAYLIST-TYPE

有以下两个值

  • VOD
  • EVENT

#EXT-X-PLAYLIST-TYPE: VOD

点播 playlist HLS中点播playlist是静态的文件,生成之后一般不允许修改,server端可以预先生成切片文件。

#EXT-X-PLAYLIST-TYPE: EVENT

Event playlist 通常用于晚会或体育赛事

用于为用户提供当前时间到开播时间任意点的seek。 Event playlist特征字段是:#EXT-X-PLAYLIST-TYPE字段是EVENT。其中并不包含EXT-X-ENDLIST字段,后续结束是会自动添加。这里EVENT字段含义是可以改动playlist内容,但是只能在m3u8文件末尾添加新的分片信息。

实时播放列表

对于直播playlist,其特征字段就是没有EXT-X-ENDLIST标签,并且不存在EXT-X-PLAYLIST-TYPE标签。 直播playlist是一个典型的滑动窗口,server端会对源格式做实时转码(存在一点延时),并定期清理已发布的分片信息。典型的滑动窗口大小为3-5个分片。其m3u8格式如下:

#EXTM3U 
#EXT-X-TARGETDURATION:10 
#EXT-X-VERSION:3 
#EXT-X-MEDIA-SEQUENCE:1 
#EXTINF:10, 
fileSequence1.ts 
#EXTINF:10, 
fileSequence2.ts 
#EXTINF:10, 
fileSequence3.ts

对于任意一个分片URI被移除该playlist,必须更新EXT-X-MEDIA-SEQUENCE字段(+1即可)。移除URI必须按照顺序,并保证客户端通过滑动窗口拿到连续的分片信息。按照这样更新之后的playlist如下:

#EXTM3U 
#EXT-X-TARGETDURATION:10 
#EXT-X-VERSION:3 
#EXT-X-MEDIA-SEQUENCE:2 
#EXTINF:10, 
fileSequence2.ts 
#EXTINF:10, 
fileSequence3.ts 
#EXTINF:10, 
fileSequence4.ts 
#EXTINF:10,

5、最后

更多HLS内容请参考 -----> Apple HTTP Live Streaming 官方说明 Technical Note TN2288: Example Playlist Files for use with HTTP Live Streaming (apple.com)

(FFmpeg视频处理 - -Finley- - 博客园 (cnblogs.com))

(ffmpeg Documentation)

另外: 给大家推荐一款集短视频批量剪辑、文案、字幕、语音合成等短视频运营功能于一体的智能软件,绑定我的邀请码(5048)送你300积分,快来体验吧!