mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-27 19:03:46 +02:00
Add support for live HLS streams, add playlist refresh logic, add live input tracks
This commit is contained in:
+46
-12
@@ -16,17 +16,19 @@
|
||||
progressElement.max = 1;
|
||||
document.body.append(progressElement);
|
||||
|
||||
fileInput.addEventListener('change', async () => {
|
||||
const file = fileInput.files[0];
|
||||
|
||||
const source = new Mediabunny.BlobSource(file);
|
||||
window.addEventListener('click', async () => {
|
||||
|
||||
const target = new Mediabunny.BufferTarget() ?? new Mediabunny.StreamTarget(new WritableStream({
|
||||
write: console.log
|
||||
}), {
|
||||
chunked: true,
|
||||
chunkSize: 2**20
|
||||
});
|
||||
const outputFormat = new Mediabunny.Mp4OutputFormat({fastStart: 'fragmented'});
|
||||
const outputFormat = new Mediabunny.Mp4OutputFormat();
|
||||
|
||||
const p = document.createElement('p');
|
||||
p.textContent = 'Capturing...';
|
||||
document.body.append(p);
|
||||
|
||||
const button = document.createElement('button');
|
||||
button.textContent = 'Cancel';
|
||||
@@ -50,14 +52,43 @@
|
||||
target
|
||||
});
|
||||
|
||||
let ctx = null;
|
||||
const conversion = await Mediabunny.Conversion.init({
|
||||
input: new Mediabunny.Input({
|
||||
let input;
|
||||
const tracks = [];
|
||||
let start = 0;
|
||||
|
||||
if (true) {
|
||||
input = new Mediabunny.Input({
|
||||
entryPath: 'https://zdf-hls-15.akamaized.net/hls/live/2016498/de/high/master.m3u8',
|
||||
source: ({ path }) => new Mediabunny.UrlSource(path),
|
||||
formats: Mediabunny.ALL_FORMATS,
|
||||
});
|
||||
|
||||
const videoTrack = await input.getPrimaryVideoTrack();
|
||||
const audioTrack = await input.getPrimaryAudioTrack();
|
||||
|
||||
if (videoTrack) tracks.push(videoTrack);
|
||||
if (audioTrack) tracks.push(audioTrack);
|
||||
|
||||
start = Math.min(...await Promise.all([
|
||||
videoTrack.computeDuration({ skipLiveWait: true }),
|
||||
audioTrack.computeDuration({ skipLiveWait: true }),
|
||||
]));
|
||||
} else {
|
||||
const file = fileInput.files[0];
|
||||
const source = new Mediabunny.BlobSource(file);
|
||||
|
||||
input = new Mediabunny.Input({
|
||||
formats: Mediabunny.ALL_FORMATS,
|
||||
source
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
let ctx = null;
|
||||
const conversion = await Mediabunny.Conversion.init({
|
||||
input,
|
||||
output,
|
||||
audio: (_, n) => ({
|
||||
audio: (track, n) => ({
|
||||
discard: !tracks.includes(track),
|
||||
//codec: 'eac3',
|
||||
//discard: true,
|
||||
//discard: n > 1,
|
||||
@@ -103,7 +134,8 @@
|
||||
bitrate: 320000
|
||||
},
|
||||
*/
|
||||
video: () => ({
|
||||
video: (track) => ({
|
||||
discard: !tracks.includes(track),
|
||||
//forceTranscode: true,
|
||||
//forceTranscode: true,
|
||||
//width: 1280,
|
||||
@@ -188,6 +220,8 @@
|
||||
}
|
||||
},
|
||||
trim: {
|
||||
start,
|
||||
end: start + 5,
|
||||
//start: 0,
|
||||
//end: 10
|
||||
},
|
||||
@@ -230,5 +264,5 @@
|
||||
a.click();
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
});
|
||||
}, { once: true });
|
||||
</script>
|
||||
+36
-8
@@ -11,6 +11,7 @@
|
||||
document.body.append(fileInput);
|
||||
|
||||
fileInput.addEventListener('change', async () => {
|
||||
/*
|
||||
const file = fileInput.files[0];
|
||||
const input = new Mediabunny.Input({
|
||||
formats: Mediabunny.ALL_FORMATS,
|
||||
@@ -20,13 +21,47 @@
|
||||
const audTrack = await input.getPrimaryAudioTrack();
|
||||
console.log((await audTrack.getDecoderConfig()).description.join(','));
|
||||
return;
|
||||
*/
|
||||
|
||||
const manifest = new Mediabunny.Input({
|
||||
entryPath: 'https://s3.amazonaws.com/qa.jwplayer.com/hlsjs/muxed-fmp4/hls.m3u8',
|
||||
entryPath: 'https://zdf-hls-15.akamaized.net/hls/live/2016498/de/high/master.m3u8',
|
||||
source: ({ path }) => new Mediabunny.UrlSource(path),
|
||||
formats: Mediabunny.ALL_FORMATS,
|
||||
});
|
||||
|
||||
const videoTrack = await manifest.getPrimaryVideoTrack();
|
||||
await videoTrack.hydrate();
|
||||
|
||||
const sink = new Mediabunny.EncodedPacketSink(videoTrack);
|
||||
const firstTimestamp = await videoTrack.getFirstTimestamp();
|
||||
|
||||
console.log("FIRST", firstTimestamp)
|
||||
|
||||
let last = -Infinity;
|
||||
for await (const packet of sink.packets()) {
|
||||
const rel = packet.timestamp - firstTimestamp;
|
||||
console.log(rel, rel - last);
|
||||
|
||||
last = rel;
|
||||
|
||||
if (rel >= 10) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
console.log("here")
|
||||
const lastPacket = await sink.getPacket(Infinity, { skipLiveWait: true });
|
||||
const other = await sink.getPacket(lastPacket.timestamp - 5);
|
||||
|
||||
for await (const packet of sink.packets(other)) {
|
||||
console.log(packet.timestamp);
|
||||
}
|
||||
|
||||
console.log("Done")
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
const tracks = await manifest.getTracks();
|
||||
//await input.hydrateAllTracks();
|
||||
@@ -34,11 +69,6 @@
|
||||
|
||||
return;
|
||||
*/
|
||||
|
||||
const videoTrack = await manifest.getPrimaryVideoTrack();
|
||||
const audioTrack = await manifest.getPrimaryAudioTrack();
|
||||
|
||||
console.log(await videoTrack.getFirstTimestamp(), await audioTrack.getFirstTimestamp());
|
||||
/*
|
||||
for await (using sample of sink.samples()) {
|
||||
console.log(sample.timestamp);
|
||||
@@ -105,8 +135,6 @@
|
||||
}
|
||||
*/
|
||||
|
||||
console.log("Done")
|
||||
|
||||
/*
|
||||
|
||||
//const secondPacket = await sink.getNextPacket(firstPacket);
|
||||
|
||||
Reference in New Issue
Block a user