You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MediaRecorderAPI录制WebM视频下载后缺失时长元数据求助

问题:WebM录制文件缺失时长元数据,无需FFmpeg解决

我使用MediaRecorder API开发了前端录屏功能,支持添加多路音视频流并录制,完成后生成可下载的压缩包。目前MP3音频文件下载后时长元数据正常,但WebM视频文件虽能正常播放,却缺失时长元数据。后续需要实现多路音视频流同步,不想通过本地FFmpeg重新导出视频来补全时长,求可行解决方案。

相关代码

RecordHandler 父类

class RecordHandler {

    mediaStream = null;
    chunks = [];
    exportMediaType = '';
    static zip;
    deviceName = "";

    constructor(exportMediaType) {
        this.exportMediaType = exportMediaType;
    }

    startRecording() {
        this.mediaRecorder = new MediaRecorder(this.mediaStream);
        this.mediaRecorder.ondataavailable = this.handleMediaDataAvailable.bind(this);
        this.mediaRecorder.onstop = this.handleMediaStop.bind(this);
        this.mediaRecorder.start(200);
    }

    stopRecording() {
        if (this.mediaRecorder.state == 'inactive') return;
        this.mediaRecorder.stop();
    }

    handleMediaDataAvailable(e) {
        this.chunks.push(e.data);
    }

    handleMediaStop(e) {
        const blob = new Blob(this.chunks, {
            type: this.exportMediaType
        });
        const type = this.exportMediaType.includes('video') ? '_video.webm' : '_audio.mp3';
        this.chunks = [];
        const name = this.deviceName.replace(/\s/g, '-').replace(/\(|\)|:/g, '');
        RecordHandler.zip.file(`${getDateString()}_${name}${type}`, blob);
    }
}

VideoHandler 子类

class VideoHandler extends RecordHandler {

    //other stuff

    constructor() {
        super('video/webm');
    }

    async createVideoInputStream() {
        this.mediaStream = await navigator.mediaDevices.getUserMedia({ video: { deviceId: this.inputDeviceId, frameRate: 30 } });
    }

    //other stuff   

}

MicrophoneHandler 子类

class MicrophoneHandler extends RecordHandler {

    //other stuff

    constructor() {
        super('audio/mpeg');
        this.audioCtx = new (window.AudioContext || window.webkitAudioContext)();
        this.analyser = this.audioCtx.createAnalyser();
    }
 
    async init(audioDeviceId, outputDeviceId) {
        this.mediaStream = await navigator.mediaDevices.getUserMedia({ video: false, audio: { deviceId: audioDeviceId } });
    }

    //other stuff
}

补充说明

  • 父类中的deviceName在其他方法中定义,且名称唯一。
  • 曾尝试通过加载录制后的媒体文件,监听ontimeupdate事件来获取时长,但该事件从未触发,audio.duration始终显示Infinity,即便实际音频文件存在有效时长。

内容的提问来源于stack exchange,提问作者Tabea

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 19:18:17