mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-27 19:03:46 +02:00
336 lines
8.0 KiB
HTML
336 lines
8.0 KiB
HTML
<script src="../dist/metamuxer.js"></script>
|
|
|
|
<script type="module">
|
|
const fileInput = document.createElement('input');
|
|
fileInput.type = 'file';
|
|
document.body.append(fileInput);
|
|
|
|
/*
|
|
const encoder = new AudioEncoder({
|
|
output: console.log,
|
|
error: console.error
|
|
});
|
|
encoder.configure({
|
|
codec: 'vorbis',
|
|
numberOfChannels: 2,
|
|
sampleRate: 48000,
|
|
bitrate: 128000
|
|
});
|
|
|
|
let audioData = new AudioData({
|
|
format: 'f32',
|
|
numberOfChannels: 2,
|
|
sampleRate: 48000,
|
|
timestamp: 0,
|
|
data: new Float32Array(2 * 48000),
|
|
numberOfFrames: 48000
|
|
});
|
|
encoder.encode(audioData);
|
|
*/
|
|
|
|
fileInput.addEventListener('change', async () => {
|
|
const file = fileInput.files[0];
|
|
const source = new Metamuxer.BlobSource(file);
|
|
const input = new Metamuxer.Input({
|
|
formats: Metamuxer.ALL_FORMATS,
|
|
source
|
|
});
|
|
|
|
const audioTrack = await input.getPrimaryAudioTrack();
|
|
const drain = new Metamuxer.AudioBufferDrain(audioTrack);
|
|
|
|
const chunks = drain.buffers()
|
|
const a = chunks.next();
|
|
|
|
//chunks.return();
|
|
|
|
console.log(await a)
|
|
|
|
//console.log("Done")
|
|
|
|
/*
|
|
const videoTrack = await input.getPrimaryVideoTrack();
|
|
const drain = new Metamuxer.VideoFrameDrain(videoTrack);
|
|
|
|
const target = new Metamuxer.ArrayBufferTarget();
|
|
const format = new Metamuxer.Mp4OutputFormat();
|
|
const output = new Metamuxer.Output({ target, format });
|
|
|
|
const mediaSource = new Metamuxer.VideoFrameSource({
|
|
codec: 'av1',
|
|
bitrate: 1e6
|
|
});
|
|
output.addVideoTrack(mediaSource);
|
|
|
|
output.start();
|
|
|
|
for await (const frame of drain.frames(0, 10)) {
|
|
await mediaSource.digest(frame);
|
|
frame.close();
|
|
}
|
|
|
|
await output.finalize();
|
|
function download(blob, filename) {
|
|
const url = URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
a.href = url;
|
|
a.download = filename;
|
|
a.click();
|
|
URL.revokeObjectURL(url);
|
|
}
|
|
|
|
download(new Blob([target.buffer]), 'converted.mp4');
|
|
*/
|
|
|
|
/*
|
|
const videoTrack = await input.getPrimaryVideoTrack();
|
|
const drain = new Metamuxer.VideoFrameDrain(videoTrack);
|
|
|
|
async function* timestamps() {
|
|
const fromTime = 0;
|
|
const toTime = await videoTrack.computeDuration();
|
|
const extractDuration = toTime - fromTime;
|
|
const drain = new Metamuxer.EncodedVideoChunkDrain(videoTrack);
|
|
const thumbnailsNeeded = 16;
|
|
|
|
for (let i = 0; i < thumbnailsNeeded; i++) {
|
|
const startTime = (extractDuration * i) / thumbnailsNeeded + fromTime;
|
|
const endTime = Math.min(
|
|
(extractDuration * (i + 1)) / thumbnailsNeeded + fromTime,
|
|
toTime + 1,
|
|
);
|
|
|
|
const chunk = await drain.getChunk(startTime, { onlyMetadata: true });
|
|
|
|
let bestTimestamp = chunk.timestamp / 1e6;
|
|
if (chunk.type !== 'key') {
|
|
const nextKeyChunk = await drain.getNextKeyChunk(chunk, { onlyMetadata: true });
|
|
if (nextKeyChunk.timestamp / 1e6 < endTime) {
|
|
bestTimestamp = nextKeyChunk.timestamp / 1e6;
|
|
}
|
|
}
|
|
|
|
yield bestTimestamp;
|
|
}
|
|
}
|
|
|
|
for await (const frame of drain.framesAtTimestamps(timestamps())) {
|
|
const clone = structuredClone(frame);
|
|
frame.close();
|
|
console.log(clone)
|
|
}
|
|
console.log("done")
|
|
*/
|
|
|
|
/*
|
|
const videoTrack = await input.getPrimaryVideoTrack();
|
|
const drain = new Metamuxer.VideoFrameDrain(videoTrack);
|
|
const width = await videoTrack.getWidth();
|
|
const height = await videoTrack.getHeight();
|
|
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
document.body.append(canvas);
|
|
|
|
const context = canvas.getContext('2d');
|
|
|
|
// Top-level for await loop inside the event listener
|
|
for await (const frame of drain.frames()) {
|
|
context.drawImage(frame, 0, 0, width, height);
|
|
frame.close();
|
|
|
|
await new Promise(resolve => setTimeout(resolve, 1000 / 24));
|
|
}
|
|
*/
|
|
|
|
/*
|
|
const videoTrack = await input.getPrimaryVideoTrack();
|
|
const audioTrack = await input.getPrimaryAudioTrack();;
|
|
console.log(videoTrack.computeDuration());
|
|
console.log(await audioTrack.computeDuration());
|
|
*/
|
|
|
|
/*
|
|
const audioTrack = await input.getPrimaryAudioTrack();
|
|
const drain = new Metamuxer.AudioBufferDrain(audioTrack);
|
|
|
|
const context = new AudioContext();
|
|
const startTime = context.currentTime;
|
|
|
|
for await (const { buffer, timestamp } of drain.buffers()) {
|
|
const node = context.createBufferSource();
|
|
node.buffer = buffer;
|
|
node.connect(context.destination);
|
|
const start = startTime + timestamp
|
|
node.start(start);
|
|
|
|
if (start > context.currentTime + 5) {
|
|
await new Promise(resolve => {
|
|
const id = setInterval(() => {
|
|
if (start < context.currentTime + 5) {
|
|
clearInterval(id);
|
|
resolve();
|
|
}
|
|
}, 100);
|
|
});
|
|
}
|
|
}
|
|
*/
|
|
|
|
/*
|
|
const drain = new Metamuxer.AudioDataDrain(audioTrack);
|
|
|
|
console.time()
|
|
for await (const data of drain.data()) {
|
|
data.close();
|
|
}
|
|
console.timeEnd()
|
|
*/
|
|
|
|
|
|
/*
|
|
const drain = new Metamuxer.EncodedAudioChunkDrain(audioTrack);
|
|
|
|
for await (const chunk of drain.chunks()) {
|
|
console.log(chunk);
|
|
|
|
if (chunk.timestamp > 1e6) {
|
|
break;
|
|
}
|
|
}
|
|
*/
|
|
|
|
/*
|
|
const videoTrack = await input.getPrimaryVideoTrack();
|
|
const drain = new Metamuxer.VideoFrameDrain(videoTrack);
|
|
const width = await videoTrack.getWidth();
|
|
const height = await videoTrack.getHeight();
|
|
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
document.body.append(canvas);
|
|
|
|
const context = canvas.getContext('2d');
|
|
|
|
// Top-level for await loop inside the event listener
|
|
for await (const frame of drain.frames()) {
|
|
context.drawImage(frame, 0, 0, width, height);
|
|
frame.close();
|
|
}
|
|
*/
|
|
|
|
/*
|
|
const drain = new Metamuxer.EncodedVideoChunkDrain(videoTrack);
|
|
|
|
const startChunk = await drain.getFirstChunk();
|
|
for await (const chunk of drain.chunks(startChunk)) {
|
|
console.log(chunk.timestamp);
|
|
}
|
|
*/
|
|
|
|
|
|
/*
|
|
for (let i = 0; i < 2; i += 0.1) {
|
|
console.log(await drain.getChunk(i));
|
|
}
|
|
*/
|
|
|
|
/*
|
|
const drain = new Metamuxer.VideoFrameDrain(videoTrack);
|
|
|
|
for await (const frame of drain.frames()) {
|
|
// ...
|
|
}
|
|
|
|
console.log(await videoTrack.getDuration());
|
|
*/
|
|
|
|
/*
|
|
const drain = new Metamuxer.VideoFrameDrain(videoTrack);
|
|
|
|
|
|
const width = await videoTrack.getWidth();
|
|
const height = await videoTrack.getHeight();
|
|
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
document.body.append(canvas);
|
|
|
|
const context = canvas.getContext('2d');
|
|
|
|
// Top-level for await loop inside the event listener
|
|
for await (const frame of drain.frames()) {
|
|
context.drawImage(frame, 0, 0, width, height);
|
|
frame.close();
|
|
}
|
|
*/
|
|
|
|
/*
|
|
const videoTrack = await input.getPrimaryVideoTrack();
|
|
const drain = new Metamuxer.VideoFrameDrain(videoTrack);
|
|
|
|
for await (const frame of drain.frames(0.01)) {
|
|
console.log(frame)
|
|
frame.close()
|
|
|
|
if (frame.timestamp > 2e6) {
|
|
break;
|
|
}
|
|
}
|
|
*/
|
|
|
|
/*
|
|
const drain = new Metamuxer.EncodedVideoChunkDrain(videoTrack);
|
|
|
|
const decoder = new VideoDecoder({
|
|
output: console.log,
|
|
error: console.error
|
|
});
|
|
decoder.configure({
|
|
...await videoTrack.getDecoderConfig()
|
|
});
|
|
|
|
const firstChunk = await drain.getFirstChunk();
|
|
const secondChunk = await drain.getNextChunk(firstChunk);
|
|
const thirdChunk = await drain.getNextChunk(secondChunk);
|
|
|
|
console.log(firstChunk, secondChunk, thirdChunk);
|
|
|
|
decoder.decode(firstChunk);
|
|
decoder.decode(secondChunk);
|
|
decoder.decode(thirdChunk);
|
|
|
|
decoder.flush();
|
|
*/
|
|
|
|
|
|
/*
|
|
const drain = new Metamuxer.VideoFrameDrain(videoTrack);
|
|
|
|
const frame = await drain.getKeyFrame(69);
|
|
|
|
const canvas = document.createElement('canvas')
|
|
canvas.width = await videoTrack.getWidth();
|
|
canvas.height = await videoTrack.getHeight();
|
|
const context = canvas.getContext('2d');
|
|
context.drawImage(frame, 0, 0);
|
|
|
|
document.body.append(canvas);
|
|
*/
|
|
|
|
/*
|
|
const drain = new Metamuxer.EncodedVideoChunkDrain(videoTrack);
|
|
|
|
for await (const chunk of drain.chunks()) {
|
|
console.log(chunk);
|
|
|
|
if (chunk.timestamp > 1e6) {
|
|
break;
|
|
}
|
|
}
|
|
*/
|
|
});
|
|
</script> |