Web 视频流处理
现在视频网站有很多,为了补全这块知识,我就通过 PHP 实现读取视频流返回浏览器的功能。这是为了达到隐藏真实链接的目的,但又发现了一些问题,视频无法快进,加载速度慢。通过搜索得到视频是当静态资源一样一次性返回的。而且每次请求都是从头开始的读取视频文件,但是可以使用断点续传的方式来处理快进失败的问题。下面简单的梳理下相关的知识点:
视频流的请求及响应
无处理的请求 mp4 过程
请求头说明
range: bytes=0-
响应头说明
Accept-Ranges: none
: 不支持范围请求status: 200 OK
: 完全返回,一次性返回content-type: video/mp4
: 视频类型Content-Length: 554058
: 返回内容大小
断点续传式请求 mp4 过程
初次请求
请求头
Content-Type: video/mp4
Range: bytes=0-1023
: 请求 1024 byte 大小的视频流
响应头
status: 206 Partial Content
: 支持范围请求Accept-Ranges: bytes
: 内容单位Content-Length: 1024
: 内容大小Content-Range: bytes 0-1023/146515
: 返回内容范围
后续请求
请求头
Content-Type: video/mp4
Range: bytes=1024-2047
响应头
status: 206 Partial Content
:合适的请求范围status: 416 Requested Range Not Satisfiable
:超出内容范围的状态Content-Length: 1024
: 内容大小Content-Range: bytes 1024-2047/146515
: 返回内容范围
程序实现方式
- 读取客户端请求头的 Range 要获取的范围
- 打开目标文件,获取要读取的范围内容文件流
- 组装 206 状态、内容类型、响应范围、响应大小、内容 响应体并返回
扩展
编解码器
音视频通常是以 mp4、avi、mp3等格式展示的,但是这和编解码器没有太大的关联。可以把他当作一个文件夹,文件夹中包含了音频、视频,也可以理解当作承载音频、视频的媒体容器。而音视频又是用编码器实现的。
- 封装格式、媒体容器、多媒体封装格式都表示文件后缀
- h.264、h.265 是编码器的编码
- FPS 帧率(一秒里切换的画面数),24以上比较平滑,30 或 60 是理解的目标
WEB 视频播放原理
媒体资源扩展(Media Source Extensions 简称 “MSE”, 是一个现今多数浏览器都遵守的规范。它创建来是为了让 HTML 和 JavaScript 允许那些复杂的媒体用例。在 HTML5 之前网站如果想支持音视频就得在客户端中安装想关辅助软件,如 Flash 插件。官方推出的规范和 Flash 的停止维护让这个推广更快速。
浏览器都有了解析视频的能力,所以 http 请求到视频流就能进行解析播放。
应用场景
- 视频平台是怎么处理视频的
视频平台除了要注意用户上传的视频内容是否合法外,还需要处理对视频进行处理,如获取视频封面,生成不同的质量的视频。平台一般都有自己研发的工具上传视频,我认识是一种利用用户资源来做视频初始化的方法之一。上传成功就是截取生成不同质量的视频,通常通过 ffmpeg 来实现。
- 视频通过程序返回会占用带宽
视频一般都会存储在第三方的云存储中,加密以及防盗都由第三方提供。如果仅仅自己使用的话,可以使用断点续传的方式来实现,本地或内网都不需要考虑带宽问题。
- 直播推流平台
通常使用第三方云服务,自己搭建的话可以参考玩转直播系列之从 0 到 1 构建简单直播系统(1)
FFMPEG 转码
视频网站中我们能看到 360P、480P、720P、1080P 等不同的清晰度,能让用户根据网络情况和流量情况来选择。用户上传的视频有可能使用了奇奇怪怪的视频宽高比例,但是视频比较也不太标准。
常用设置
- 宽高比
- 4:3
- 16:9
- 360P = 640 * 360 = (40 * 16) * (40 * 9)
- 720P = 1280 * 720 = (80 * 16) * (80 * 9)
- 1080P = 1920 * 1080 = (120 * 16) * (120 * 9)
1 | 截取视频第1帧当封面 |
- 通过
Stream #0:0[0x1](und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p(tv, smpte170m/smpte170m/bt709, progressive), 320x240, 80 kb/s, 29.65 fps, 29.97 tbr, 90k tbn (default)
得到当前是视频项,使用 h264 编码器,320x240 宽高比,29.65帧(约等于30帧)等重要信息。 - 通过
Stream #0:1[0x2](und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 115 kb/s (default)
得到当前为音频项,使用 aac 格式