我正在创建一个利用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
秒后增加,这意味着它被追加到了数据库中,只是没有正确追加。
任何帮助都将不胜感激。
1条答案
按热度按时间e5nqia271#
为了可搜索,视频(至少谈论EBML)需要有SeekHead标签、Cues标签和Info标签中定义的持续时间。
要创建视频的新元数据,您可以使用ts-ebml的导出函数makeMetadataSeekable(usage example),然后将视频的开始部分切片并替换为新的元数据(就像示例中所做的那样),瞧!新的视频文件变为可搜索的