ffmpeg 实现 web 在线转码
前提: 公司项目中上传的视频编码格式不一,但是在浏览器播放中,却出现了黑屏(有声音)的情况,即使是 MP4 格式的视频,也存在无法播放,查询一番,了解到 chrome 浏览器的 video 标签仅对部分格式的视频支持播放
通常我们使用 MP4 格式,但是 MP4 又分为“1.MPEG4(DivX)”、“2.MPEG4(Xvid)”、“3.AVC(H264)”三种类型。其中只有 H264 类型的视频才能进行 html 播放
<video>标签所支持的视频格式和编码:
MP4 = MPEG 4 文件使用 H264 视频编解码器和 AAC 音频编解码器
WebM = WebM 文件使用 VP8 视频编解码器和 Vorbis 音频编解码器
Ogg = Ogg 文件使用 Theora 视频编解码器和 Vorbis 音频编解码器
注释:Internet Explorer 8 以及更早的版本不支持 video 标签。使用 FFMPEG 转码预览地址: https://642134542.github.io/vue-ffmpeg/
1、原理:
ffmpeg.wasm 是 FFmpeg 的纯 WebAssembly / JavaScript 端口。它支持在浏览器内录制、转换和流式传输视频和音频。Webassembly 的出现为前端转码提供可能
2、按照官网配置
npm 安装
js
3、结果
报错 ReferenceError: SharedArrayBuffer is not defined,
需要解决 SharedArrayBuffer 报错
经过一番百度和查看 issue, 是因为谷歌浏览器的安全策略机制改变了
2017.7 月(Chrome 60)引入 SharedArrayBuffer。
2021.7 月(Chrome 92)限制 SharedArrayBuffer 只能在 cross-origin isolated 页面使用。
Android Chrome 88 也进行了同样的限制。
所以在 60-91 的版本的浏览器是可以正常打开的那么 92 版本的呢我们可以再 vue.config.js 中配置 devServer: {headers: {"Cross-Origin-Opener-Policy": "same-origin","Cross-Origin-Embedder-Policy": "require-corp",},}
4、效果
在控制台中可以看到读取文件和转码进程,而且页面可以正常的显示视频并播放
5、优化:
1、createFFmpeg 中的 corePath 的地址是 cdn 在线的,这里我们需要换成自己的本地资源,使用 import 一直报错
估计是相关依赖并没有找到,npm install 还是不行
只好把包里的 ffmpeg-core.js、ffmpeg-core.wasm 和 ffmpeg-core.worker.js 放在 public 中
2、加载
读取文件和转码的时间比较长,所以我们需要增加加载层和进度条
6、部署:
使用 ip 或者域名访问,依旧会报错 SharedArrayBuffer is not defined,
所以我们需要代理中配置请求头
但是还是存在报错信息
解决办法:
1、使用 https 代替 http
2、使用 chrome 60-91 版本访问
7、FAQ
1、caught (in promise) Error: Oops, something went wrong in FS operation
解决办法: 不要使用中文名称,将 name 可以进行转义
2、Error: ffmpeg.FS('readFile', 'output.mp4') error. Check if the path exists
解决办法:同问题 1
3、github page 无法设置 header 请求头,预览地址是如何解决 SharedArrayBuffer
报错的在 Stack Overflow 这个问题中 有个回答提供了解决方案
https://github.com/gzuidhof/coi-serviceworker, 开发者只需要将 coi-serviceworker.js 在 index.html 引入即可
版权声明: 本文为 InfoQ 作者【lo】的原创文章。
原文链接:【http://xie.infoq.cn/article/64cb466bb3076251feebb4791】。文章转载请联系作者。
评论