javascript 如何使用ts-ebml(即时)创建一个视频,该视频具有来自未知数量的传入视频blob/chunk的可查找时间戳?

lf3rwulv  于 2022-12-25  发布在  Java
关注(0)|答案(1)|浏览(304)

我正在创建一个利用videojs-record组件的直播流组件。每隔x毫秒,该组件就会触发一个返回blob的事件。如图所示,blob包含来自视频录制的数据。它不是完整的录制,而是一个片段,因为它在录制后的x秒内返回
保存在后端并回放后,我发现无法跳过视频;它是不可搜索。
因为这是一个我试图保留在前端的任务,所以我必须使用ts-ebml在浏览器中注入这个元数据,在注入元数据之后,修改后的blob被发送到后端。
接收this blob的函数如下所示:

timestampHandler(player) {
    const { length: recordedDataLength } = player.recordedData;
    if (recordedDataLength != 0) {
        const { convertStream } = this.converter;
        convertStream(player.recordedData[recordedDataLength - 1]).then((blob) => {
        console.log(blob);
        blob.arrayBuffer().then(async response => {
            const bytes = new Uint8Array(response);
            let binary = '';
            let len = bytes.byteLength;
            for (let i = 0; i < len; i++) {
                binary += String.fromCharCode(bytes[i]);
        }
            this.$backend.videoDataSendToServer({ bytes: window.btoa(binary), id: this.videoId })
        })
            .catch(error => {
            console.log('Error Converting:\t', error);
            })
        })
    }
}

convertStream是一个位于TsEBMLEngine类中的函数。该类如下所示:

import videojs from "video.js/dist/video";

import { Buffer } from "buffer";
window.Buffer = Buffer;

import { Decoder, tools, Reader } from "ts-ebml";

class TsEBMLEngine {
    //constructor(){
        //this.chunkDecoder = new Decoder();
        //this.chunkReader = new Reader();
    //}

    convertStream = (data) => {

        const chunkDecoder = new Decoder();
        const chunkReader = new Reader();

        chunkReader.logging = false;
        chunkReader.drop_default_duration = false;

        // save timestamp
        const timestamp = new Date();
        timestamp.setTime(data.lastModified);

        // load and convert blob
        return data.arrayBuffer().then((buffer) => {

            // decode
            const elms = chunkDecoder.decode(buffer);
            elms.forEach((elm) => {
                chunkReader.read(elm);
            });
            chunkReader.stop();

            // generate metadata
            let refinedMetadataBuf = tools.makeMetadataSeekable(
                chunkReader.metadatas,
                chunkReader.duration,
                chunkReader.cues
            );
            let body = buffer.slice(chunkReader.metadataSize);

            // create new blob
            let convertedData = new Blob([refinedMetadataBuf, body], { type: data.type });

            // store convertedData
            return convertedData;
        });
    }
}

// expose plugin
videojs.TsEBMLEngine = TsEBMLEngine;

export default TsEBMLEngine;

在录制超过10秒后,我停止录制,转到DB,并观看检索到的视频。在圆点到达可搜索线的最末端之前,视频在前3秒是可搜索的。当我在直播流中观看视频时,视频在前3秒后冻结。
当我查看DB中文件的大小时,它在x秒后增加,这意味着它被追加到了数据库中,只是没有正确追加。
任何帮助都将不胜感激。

e5nqia27

e5nqia271#

为了可搜索,视频(至少谈论EBML)需要有SeekHead标签、Cues标签和Info标签中定义的持续时间。
要创建视频的新元数据,您可以使用ts-ebml的导出函数makeMetadataSeekable(usage example),然后将视频的开始部分切片并替换为新的元数据(就像示例中所做的那样),瞧!新的视频文件变为可搜索的

相关问题