MSE (Media Source Extension) 扩展了浏览器的媒体播放功能,允许用JS动态构造媒体流MediaSource对象,然后喂给和标签进行更精细化的播放控制。也可以用JS把一些不支持的视频流格式转封装为支持的格式,B站开源的flv.js就是这个技术的一个典型实现,使用MSE技术将FLV源用JS实时转封装成HTML5支持的视频格式。更多信息会在下一节播放场景和解决方案中介绍。
- 网络音频 API
Web Audio API 用于处理和合成Web应用程序中的音频,允许开发者进行声音合成、添加音频特效、音频可视化等,使用Web Audio API 我们几乎可以完成一个专业的Web音频处理软件(如节拍器、调音器等)。
- 媒体捕获和流媒体API
Media Stream API 让开发者可以使用本地摄像头和麦克风来采集录制音视频,或者捕获电脑屏幕,或者读取本地视频做合成,常用于Web摄像头、拍照、录屏、视频通话等,下文视频剪辑章节也有1688使用该技术实现web视频剪辑的案例。MediaStream 是连接 WebRTC API 和底层物理流的中间层,WebRTC将音视频经过Vocie / Video engine进行处理后,再通过MediaStream API暴露给上层使用。
- WebRTC
WebRTC 是一套支持浏览器进行实时音视频对话的 W3C Javascript API,它包括了音视频的采集、编解码、网络传输、显示等功能,使互联网上任意两位用户在无需服务器的情况下实现实时的音频、视频和任意数据的通信。在2010年左右,实时通信只能使用专有软件、插件或Adobe Flash进行;2013年,Chrome 和 Firefox 之间进行了首次跨浏览器视频通话,开启浏览器之间无插件化的音视频通话的序幕。现在WebRTC的使用场景非常丰富,在音视频通信、直播推流、云剪辑、云游戏等场景都可以看到WebRTC的使用。
除了这些媒体API,还有一些技术通常与媒体API共同使用:
与媒体 API 共同使用的技术
- Canvas API
Canvas API 允许在 上绘画、操纵并改变图像内容。这样可以与媒体以多种方式使用,包括设置 元素作为视频播放或摄像头捕获的节点以捕获或操纵视频帧。
- WebGL
WebGL 在已存在的 Canvas API 上提供了与 OpenGL ES 兼容的 API,使得在 Web 上制作强大的 3D 图像成为可能。通过一张画布,用于为媒体内容添加 3D 图像。
- WebVR
Web Virtual Reality API 支持虚拟现实 (VR) 设备,使开发人员能够将用户的位置和移动转换为 3D 场景中的移动,然后在设备上显示。WebVR 有望逐渐被 WebXR 所取代,后者涵盖了更广泛的用例。
- WebXR
WebXR 旨在最终取代 WebVR,是一种支持创建虚拟现实 (VR) 和增强现实 (AR) 内容的技术。混合现实内容可以显示在设备的屏幕上,或者是显示在眼镜或耳机内。
播放场景和解决方案
前文提到浏览器里通过就能实现视频播放了,那还需要我们前端做些什么呢?其实也存在很多限制,我们要先从媒体内容的封装格式和编码格式说起。
媒体内容源文件都是比较大的,为了便于传输和存储,需要对原视频文件通过编码来压缩文件大小,再通过容器封装将压缩后的视音频、字幕组合到一个容器内,这就是 编码 和 容器封装 的过程(可以用 压缩饼干 和 封袋包装 来理解,会出现很多不同的压缩工艺和包装规格)。
那么在播放端进行播放时,就要进行相应的 解封装 和 解码 (先拆开包装拿出饼干,享用饼干可以直接吃、也可以碾碎了吃、也可以泡着牛奶吃)。浏览器自带的播放器标签拥有解封装和解码功能,但对媒体内容的格式是有所限制的(浏览器只会拆开特定的包装方式,只能消化特定的饼干吃法)。那浏览器碰到“不会拆、不消化的饼干”,我们要怎么喂给呢?
除了容器格式、编码格式,还有流媒体协议、渲染容器、多实例播放等等问题需要多媒体前端一一解决,下面来分别介绍:
▐ 多协议、多容器格式
随着流媒体业务发展,出现了很多新的传输协议,媒体内容进一步包含在一层传输协议中(以HLS协议为例,增加了m3u8索引文件,并将源文件内容分片后封装到了一个个 TS 容器格式中),这样就无法识别了。要支持多协议、多容器格式的播放,开发者可以通过 MSE 来帮助浏览器识别并处理,将媒体内容 转封装 成可识别的容器格式(如MP4),这样就可以识别并播放各种媒体内容了。
上文提到的B站的flv.js以及社区的hls.js都是利用 MSE 来解决多协议、多容器格式的播放器库。
- flv.js
flv.js是Bilibili网站开源的HTML5 flv播放器,基于HTTP-FLV流媒体协议,通过纯JS实现FLV转封装,使flv格式文件能在Web上进行播放。
但是flv.js也不是所有的flv格式视频都能播放,并且对浏览器环境也有一定的要求,以下是flv.js的使用限制:
-
视频必须是AVC(H.264)编码,音频必须为AAC或者MP3编码
-
浏览器环境必须支持MSE,查看支持列表:https://caniuse.com/#feat=mediasource,值得注意的是,ie浏览器中,ie11以上才能正常使用,而ie11浏览器必须在win8系统以上才能运行;移动端上,ios仅支持在iPadOS 13以上系统,ios手机端完全不可运行;android则要求4.4以上系统
-
浏览器必须支持video,fetch api、xhr和websocket支持其一便可
- hls.js
hls.js是基于Http Live Stream协议开发,利用Media Source Extension,用于实现HLS在web上播放的一款js播放库。
由于HLS协议由苹果提出,并且在移动端设备上广泛支持,因此可以被广泛应用于直播场景。而hls.js在pc端只需要支持MSE便可以应用,移动端使用原生video标签设置src便可完成播放。hls.js会先请求m3u8文件,然后读取到文件的分片列表,以及视频的编码格式、时长等。随后会按照顺序去对TS分片进行请求,然后借助MSE将二进制buffer内容进行合流,组成一个可播的媒体资源文件。
阿里内部也有多个团队有类似播放器产品,如阿里云的Aliplayer、淘系的VideoX、优酷的KPlayer,实现思路都基本一致。
- 阿里云 Aliplayer
Aliplayer 经过几个版本的迭代演进,整个架构更加合理,赋予本身和用户更多的扩展能力,具有独立增加播放类型和功能的能力,比如要h5支持flv的播放能力,只需要新增Flv Extend功能扩展模块,而不用修改其他模块的代码,比如HLS Extend等等,确保不影响其他功能的正常工作,保持每个版本发布的稳定性。
- 淘系 VideoX
Videox 底层的播放层也经历了几次变化,从最开始简单的 标签,到通过MSE来扩展各种格式的标签,到通过WebAssembly来对编解码格式进行扩展的 + Web Audio API的方式,未来可能还有底层通信的扩展及上层互动能力的增强。
- 优酷 KPlayer
KPlayer 目前的方案拆分的较细,包括多个库和组件,主要有KMux 转封装库、KDRM WebDRM插件、KCTRL 播放器控制行为的核心抽象、MediaEngine 解码&渲染&播放的核心抽象、KUI 嵌入式UI框架。KPlayer播放核心设计如下:
▐ 多编码格式
上一小节解决了浏览器不支持的协议和格式(不会拆饼干包装)的问题,那遇到不支持的编码格式(不能消化的压缩工艺)该怎么办呢?
新的视频编码标准H.265、AV1等比传统H.264拥有更高压缩率,但浏览器本身并不支持,而业务为了降低成本都全链路切换新的编码格式如H.265,那多媒体前端就要自己实现浏览器端的JS播放器。由于Javascript是一种动态解释型语言,性能比C++等语言差很多,处理多媒体数据时性能短板就体现出来,WebAssembly的出现解决了Javascript的性能短板,极大扩展浏览器端的多媒体处理能力和场景。
对于Web端H.265播放器,阿里内部有多个团队都进行了相应的尝试,包括优酷、阿里云、淘系、ICBU等,思路基本一致,都是通过FFmpeg + Webassembly来实现一个JS播放器,使用JS拉流、解封装,将FFmpeg的265解码能力编译成wasm模块供JS调用,视频经过FFmpeg解码出来YUV帧数据,通过WebGL绘制图像帧数据,而音频方面因为浏览器支持AAC、MP3等主流音频格式,音频数据直接通过Web Audio API进行播放。设计思路如下:
▐ 多渲染容器
上面描述的场景主要是PC的Web浏览器,但我们更多的业务场景在移动端,面向消费者的场景对播放的体验和性能要求非常高,于是引入了播放器的跨端支持问题,尤其是跨渲染容器(Webview/Weex/小程序)。端侧的播放器主要使用Native播放器,前端封装成Weex/同层渲染组件,在各渲染容器中运行。
在端侧如果采用原生video方案,存在兼容性及性能问题,播放器本身占用内存高,业务不规范使用会带来稳定性风险,甚至导致APP Crash。以端内H5为例,采用的是和Rax团队、客户端基础团队、客户端播放器团队一起打造的同层渲染方案:
-
Native播放器:负责播放器的基础能力,播放器内核fetch流地址后,解封装(demux)后解码(decode),然后输出到上层Naitve同层组件层,Native播放器提供了点播/直播能力
-
Native同层组件:为底层播放器实例封装,主要负责联通通信连接层,并控制渲染
-
通信连接层:通过windmix管理渲染通道,再通过windvane绑定事件,传递属性,api能力调动,连接到前端播放器
-
前端播放器核心:担任前端播放器输出,将下层提供的事件/api/属性抹平成W3C制定的播放器标准,同时负责播放器稳定性相关能力
-
业务播放器封装:对下层的前端播放器核心封装播控协议,通过事件中心,管理各个播放器播放能力;同时从业务角度出发,对网络和设备性能进行监测,判断是否降级
▐ 多实例控制****
前面提到的都是单个视频播放的场景,实际业务中还有同一个页面中多个播放器的场景,比如列表流、版头等,这时候就引入了播放器多实例控制的问题,需要保证页面内只有一个播放器播放(播放甜区)、内存管理等。
播放器需要具备强大的播控能力,即播放调度能力:
- 事件中心驱动
-
播放器内部维护一份待播放队列,由rax-view的onAppear和onDisappear实现,当执行onAppear时,待播放队列将对应播放器唯一id存入到队列中,当对应播放器执行onDisappear时,从队列中剔除
-
队列中的播放形式主要分为3种:1,滚动播放;2,指定id播放;3,onAppear场景播放;均由事件管控。再由事件中心分发到不同播放器,告知哪个播放器可播放,哪个不可播放
-
播放器存在于pcom库,无论是对于会场场景或是源码开发场景,均可保证事件中心通知到所有播放器
-
播控调度
-
播放器实例内存占用大概在20-40MB,对于一个H5页面来说,内存占用过高,极容易引发页面内存占用过大,导致crash等严重问题。所以在事件驱动播放同时,事件中心会保证有且仅有一个播放器实例正在播放
面向消费:直播视频里的业务体系
前面提到的都是单纯的播放功能,但实际的业务场景是直播间或者短视频全屏页,从播放器到直播间/短视频,还有很重要的一个部分就是用户互动层,这就引入了直播视频里的业务体系。
以直播为例,对于观众有两个诉求:观看直播、参与互动。一般直播的设计如下:
通常的直播间架构分为三种:Web直播间、Hybrid直播间、小程序直播间,比如钉钉公开课直播采用的是Web直播间架构,蚂蚁、天猫精灵等采用的是小程序直播间架构,其他绝大多数的业务采用的是Hybrid直播间架构。
▐ Web 直播间架构
纯Web直播间,是指主要运行在Web浏览器上的H5直播间,主要包括H5播放器、事件通道、UI组件等。但移动端浏览器兼容性较差,移动端播放延时较高,所以一般对体验和性能要求高的业务场景,都会选择Hybrid直播间架构。
Hybrid直播间使用原生的播放器能力,兼容性更好,体验更流畅;同时事件通道是Native通道,相对于Web直播间 websocket更安全。
▐ Hybrid 直播间架构
Hybrid直播间的宿主是Native,使用原生播放器,互动玩法是在播放器上面盖了一层互动层(Webview或WEEX容器),并且能够和播放器通信。
Hybrid架构中互动层方案也经历了几个阶段的演变,从最开始的每个玩法组件一个独立层,到所有玩法组件打包到一个层,再到定义出直播容器来动态加载组件:
直播容器具有以下几个特征:
-
统一规范的组件消息协议:包括组件包名、组件行为、业务自定义字段等
-
支持动态加载:直播间不同于其他详情页,互动的发送依赖主播操作,也依赖用户进入直播间的时机,每个用户参与到的互动可能都不一样,所以互动组件的动态加载对首屏性能很关键
-
缓存及依赖去重:同一个互动,主播可以多次推送,各个互动依赖的基础库(rax-xxx、universal-xxx)也存在较多重复,所以设计合理的缓存和依赖去重机制对性能提升也很重要
-
HOC高阶组件:直播间里的业务开发不同于其他独立的源码页面,比如直播间数据获取、消息和事件监听、横竖屏状态获取、带小窗跳转、直播观看时长等等都依赖直播间环境或者客户端API,业务组件都需要这些基础能力,需要通过HOC来增强业务组件
在Hybrid架构下开发调试组件,需要一个完整的直播间环境和直播容器才能开发调试,没有配套的工程体系,组件开发很低效。所以这种架构下还需要配套的工程体系,主要包含以下几个部分:
-
def 套件:直播间组件开发脚手架,增强调试能力,包括直播间模拟、调试代理、热更新、编译检测等功能
-
直播间 Debug 工具:基于直播容器开发一个Debug组件,提供日志调试、容器化API调用、数据Mock、消息Mock等功能
-
VS Code 插件:直播间Debug工具在PC端的同等方案,结合模拟器可以独立在PC端开发调试
多媒体前端团队通过打造直播容器和工程体系,才能高效、稳定的构建出直播视频里的业务体系。
当然Hybrid架构因为其联合Native和前端带来了架构上的复杂度,特别是在直播和视频上下滑时直播间的状态管理、播放器实例和webview实例管理等,会导致一些状态问题,比如某直播平台曾出现过“神奇三串”bug:薇娅 直播间里播放的是 李佳琦 的直播流,但展示的是 叶一茜 的商品:
基于Hybrid架构我们可以考虑进一步升级,让播放器和互动层更加融合,形成「超级Video」,或者叫可交互的Video方案,甚至定义新的 标准。
▐ 小程序直播间架构
随着跨端业务的出现,尤其是跨APP的场景,Hybrid直播间架构就像个大胖子,天然没有跨端优势(客户端集成、维护SDK成本极高),在这个背景下小程序直播间架构出现了。小程序直播间设计上分为以下几层:
-
直播插件:插件里除了包含最基本的播放器、无限列表、官方组件,还封装了组件布局规则、事件中心、容器api模块等基础能力
-
跨端通信层:由于插件和小程序宿主实例之间的js上下文完全隔离,因此@alipay/armer-x借助了appx对特定函数的声明不做序列化的特性进行了插件和宿主小程序之间的通信桥接,如给插件
-
赋予函数onConnectEmitter,在appx里是不做会做序列化的,因此数据可以通过该函数给予插件通知信息
-
小程序组件:二方、三方定制的小程序组件,满足特定的接入规则就可以借助直播间的容器能力进行定制
-
小程序实例:在拥有了二方组件、直播插件后,我们可以将二者进行整合、打包构建,生成一个新的小程序实例,实例的生成方式可以通过IDE构建,也可以通过搭建平台,如:「闪蝶」,目前的策略是支付宝侧通过闪蝶的方式构建生成实例,而百川侧,则通过IDE上传,并且借助淘宝开发平台进行百川投放
由蚂蚁和淘宝直播联合打造的小程序直播方案,在多个APP端(包括外部媒体APP)得到了广泛应用。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
最后
本人分享一下这次字节跳动、美团、头条等大厂的面试真题涉及到的知识点,以及我个人的学习方法、学习路线等,当然也整理了一些学习文档资料出来是附赠给大家的。知识点涉及比较全面,包括但不限于前端基础,HTML,CSS,JavaScript,Vue,ES6,HTTP,浏览器,算法等等
详细大厂面试题答案、学习笔记、学习视频等资料领取,点击资料领取直通车免费领取!
前端视频资料:
5%以上前端开发知识点,真正体系化!**
[外链图片转存中…(img-qNc897UA-1713761956695)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
[外链图片转存中…(img-Vy7Hh6YR-1713761956696)]
最后
本人分享一下这次字节跳动、美团、头条等大厂的面试真题涉及到的知识点,以及我个人的学习方法、学习路线等,当然也整理了一些学习文档资料出来是附赠给大家的。知识点涉及比较全面,包括但不限于前端基础,HTML,CSS,JavaScript,Vue,ES6,HTTP,浏览器,算法等等
详细大厂面试题答案、学习笔记、学习视频等资料领取,点击资料领取直通车免费领取!
[外链图片转存中…(img-mrSWrX1V-1713761956696)]
前端视频资料: