关于解决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

相关推荐
程序铺子3 小时前
如何使用 npm 安装 sqlite3 和 canvas 这些包
javascript·npm·node.js
通往曙光的路上3 小时前
day9_elementPlus2
javascript·vue.js·elementui
一只小风华~3 小时前
Vue Router 的三种历史模式详解
前端·javascript·vue.js·笔记·学习·前端框架·ecmascript
一只小风华~3 小时前
Vue Router 导航守卫
java·前端·javascript·vue.js·笔记·html
Niuguangshuo3 小时前
音频特征提取算法介绍
算法·音视频
呼叫69454 小时前
理解 JavaScript 中的 this 上下文保存
javascript
召摇4 小时前
JavaScript字符串填充:padStart()方法
前端·javascript·面试
用户9422443570244 小时前
JSAR 空间小程序开发全指南:从环境搭建到跨场景应用落地
javascript