关于解决js中MediaRecorder录制的webm视频没有进度条的问题

最近写项目的时候有一个关于视频录制需求,js视频录制通常使用MediaRecorder来实现,使用起来也非常的简单,MediaRecorder的MDN文档

但是录制视频之后出现了一个问题是录制的视频是不能操作进度条的。去网上搜索发现是因为MediaRecorder录制的视频文件缺少视频总时长等信息导致的,有很多种解决方案,我试了其中的三种,效果最好的是ebmljs。

1,使用:fix-webm-duration;

地址:fix-webm-duration,README上有安装和使用的教程。

使用这个方法后录制的视频在浏览器或者其他播放器上打开是可以操作进度条的,但是在window系统自带的播放器上仍然不能操作进度条。

2,使用:ebmljs

关于ebmljs,我并没有找到他的github仓库是什么,网上有很多的js文件,但是很多是有问题的。我使用的是文章中的这个文件,目前使用下来没有遇到什么问题。

创建一个ebml.util.js文件,用来放置处理视频blob数据的工具函数getSeekableBlob:

复制代码
// ebml.util.js

/**
 * @param {Blob} file - File or Blob object.
 * @param {function} callback - Callback function.
 * @example
 * getSeekableBlob(blob or file, callback);
 * @see {@link https://github.com/muaz-khan/RecordRTC|RecordRTC Source Code}
 */
export function getSeekableBlob(inputBlob, callback) {
    const reader = new window.EBML.Reader()
    const decoder = new window.EBML.Decoder()
    const tool = window.EBML.tools

    const fileReader = new FileReader()
    fileReader.onload = function (e) {
        const ebmlElms = decoder.decode(this.result)
        ebmlElms.forEach(function (element) {
            reader.read(element)
        })
        reader.stop()
        const refinedMetadataBuf = tool.makeMetadataSeekable(
            reader.metadatas,
            reader.duration,
            reader.cues
        )
        const body = this.result.slice(reader.metadataSize)
        const newBlob = new Blob([refinedMetadataBuf, body], {
            type: 'video/webm'
        })

        callback(newBlob)
    }
    fileReader.readAsArrayBuffer(inputBlob)
}
关于EBML.js的引入方式:

将EBML.js文件放到项目的public目录的js目录下,并在项目的index.html中引入:

最开始我在vue项目中是在ebml.util.js文件中通过import的方式导入EBML.js中的方法的,但是出现了报错:

import导入:

复制代码
// ebml.util.js

import {Reader,Decoder,tools} from './EBML'

报错:

复制代码
Router error: SyntaxError: The requested module '/src/utils/video/EBML.js' does not provide an export named 'Decoder' 
//请求的模块"/src/utils/video/EBML.js"没有提供名为"Decoder"的导出。
(at ebml.util.js:2:16)

原因是:在EBML.js中的开头有一段很长的判断,作用是通过检测不同的javaScript环境,然后将内部的方法使用不同的方式对外暴露,供外部使用。而在vue中是属于浏览器环境,于是EBML.js中的方法被挂载到了window对象上。下面一段是验证的方法(蓝色字体)。

引入方式:

复制代码
// ebml.util.js

import './EBML';//在ebml.util.js直接导入EBML.js文件

在ebml.util.js中的getSeekableBlob函数中打印window,调用getSeekableBlob后,浏览器控制台显示:

可以看到EBML.js中的方法被挂载到了window对象的EBML属性上。

然后在需要使用的地方导入getSeekableBlob并使用:

复制代码
// 引入ebml.util.js用来处理blob给webm视频添加进度条
import { getSeekableBlob } from "./video/ebml.util.js";    
//参数blob是webm视频的blob数据
getSeekableBlob(blob, function(fixedBlob) {
  //fixedBlob就是处理好之后的视频blob,你可以用它来做后续的操作
});

使用ebmljs处理好之后的webm视频就可以在window系统自带的播放器以及浏览器上操作进度条了。

3.转换视频格式为MP4

看网上还有使用 ffmpeg.wasm将webm转为MP4格式的方式来修复进度条,在一些在线转换视频格式的网站将webm视频转换成MP4后确实有进度条了,但是在项目中使用 ffmpeg.wasm将webm视频转为MP4后却没有什么作用,可能在线网站使用的是其他的方式转换视频格式的。(关于使用ffmpeg.wasm转换好像还有问题,记得使用 ffmpeg.wasm还要把MediaRecorder中的mimeType设置为mp4否则转换不了好像,写这一块过去挺久了,不确定是不是有这个问题,如果有使用 ffmpeg.wasm将MediaRecorder录制的视频转为mp4格式,遇到转换不了的情况可以试一下这个)

转换视频的在线网站:​​​​​​免费在线将 WEBM 转换为 MP4。

ffmpeg.wasm:ffmpeg.wasm

vue项目使用 ffmpeg.wasm的实例:ffmpeg.wasm/apps/vue-vite-app at main · ffmpegwasm/ffmpeg.wasm · GitHub

相关推荐
盼哥PyAI实验室20 小时前
从搭建到打磨:我的纯前端个人博客开发复盘
前端·javascript
嘉琪00120 小时前
vue3+ts面试题(一)JSX,SFC
前端·javascript·react.js
何贤21 小时前
🪐 行星科技概念官网!Hero Section 回归!(Three.js ✨)
前端·javascript·three.js
拉不动的猪21 小时前
深入理解 JavaScript 中的静态属性、原型属性与实例属性
前端·javascript·面试
linda261821 小时前
链接形式与跳转逻辑总览
前端·javascript
前端付豪21 小时前
如何使用 Vuex 设计你的数据流
前端·javascript·vue.js
咖啡の猫1 天前
Vue消息订阅与发布
前端·javascript·vue.js
下一站丶1 天前
【JavaScript性能优化实战】
开发语言·javascript·性能优化
GIS好难学1 天前
Three.js 粒子特效实战③:粒子重组效果
开发语言·前端·javascript
刺客_Andy1 天前
React 第四十七节 Router 中useLinkClickHandler使用详解及开发注意事项案例
前端·javascript·react.js