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

相关推荐
程序员Sunday4 小时前
JavaScript 事件循环面试题,宏任务与微任务怎么执行|Sunday面试指南
开发语言·javascript·面试·校招·事件循环·程序员sunday
默_笙5 小时前
🌊 向量库和 ES 都查不出"关系",我只好给奶茶建了一张人脉网
前端·javascript
思无邪666 小时前
用 AI 做 JS 逆向:从抓包到复现的完整方法论
开发语言·javascript·人工智能
揽秀亭长6 小时前
视频转脚本有哪些方法?5种方案技术拆解
人工智能·音视频
福兮说7 小时前
浏览器里把 iPhone 的 HEIC 转成 JPG:Chrome 解不开、转完大了七成、拍摄时间全丢,六个坑实测
前端·javascript·图像处理·chrome·ios·iphone·heic
Android系统攻城狮8 小时前
Linux Gstreamer深度解析之gst_audio_sink_get_type调用流程与实战(六十五)
linux·运维·服务器·音视频·gstreamer音视频·音视频进阶·gstreamer音视频进阶
可乐鸡翅yeah_8 小时前
video.js 集成 hls.js 开发 M3U8 播放器,新手高频踩坑
开发语言·前端·javascript·后端·ecmascript·m3u8·音视频在线播放
程序猿追9 小时前
HarmonyOS 6 音视频实战:用 AVPlayer 做一个本地音乐播放器
华为·音视频·harmonyos
用户1179536547810 小时前
TRAE vs Claude Code 性能对比:从代码生成、多文件重构到底层吞吐,谁更适合你的日常开发?
javascript
kill52211 小时前
useRef
前端·javascript·react.js