Reputation: 1
Multiple small video files are played like a single video in video tag using mediasource buffer. I would like to create them as a single video file if export option is desired. For that I would like to use WebCodecs API. Help is appreciated.
Tried much but getting different errors in different browsers. (like "encoder is undefined" in firefox, "Failed to execute 'decode' on 'VideoDecoder': A key frame is required after configure() or flush()." in chrome.
async function fetchVideoData(videoUrl) {
const response = await fetch(videoUrl);
if (!response.ok) {
throw new Error(`Failed to fetch video: ${response.statusText}`);
}
return response.arrayBuffer();
}
async function mergeWebMVideos(videoUrls) {
const encodedChunks = [];
let encoder;
const initEncoder = (width, height) => {
encoder = new VideoEncoder({
output: (chunk) => {
encodedChunks.push(chunk);
},
error: (e) => {
console.error('Encoder error:', e);
}
});
const config = {
codec: 'vp8',
width: width,
height: height,
bitrate: 4_000_000,
};
encoder.configure(config);
};
for (const videoUrl of videoUrls) {
const videoData = await fetchVideoData(videoUrl);
const decoder = new VideoDecoder({
output: (frame) => {
if (!encoder) {
initEncoder(frame.codedWidth, frame.codedHeight);
} else {
if (frame.codedWidth !== encoder.width || frame.codedHeight !== encoder.height) {
encoder.configure({
codec: 'vp8',
width: frame.codedWidth,
height: frame.codedHeight,
bitrate: 4_000_000,
});
}
}
encoder.encode(frame);
frame.close();
},
error: (e) => {
console.error('Decoder error:', e);
}
});
const stream = new ReadableStream({
start(controller) {
controller.enqueue(new Uint8Array(videoData));
controller.close();
}
});
const reader = stream.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) break;
decoder.configure({
codec: 'vp8'
});
const encodedChunk = new EncodedVideoChunk({
type: 'key',
timestamp: 0,
byteLength: value.byteLength,
data: value
});
decoder.decode(encodedChunk);
}
decoder.close();
}
encoder.close();
const mergedVideoBlob = new Blob(encodedChunks, { type: 'video/webm' });
return mergedVideoBlob;
}
Upvotes: 0
Views: 51