mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-10-09 16:53:47 +02:00
Add compileSampleStats
This commit is contained in:
+5
-1
@@ -49,6 +49,10 @@
|
|||||||
const videoTrack = await input.getPrimaryVideoTrack();
|
const videoTrack = await input.getPrimaryVideoTrack();
|
||||||
const drain = new Metamuxer.EncodedVideoSampleDrain(videoTrack);
|
const drain = new Metamuxer.EncodedVideoSampleDrain(videoTrack);
|
||||||
|
|
||||||
|
console.log(await videoTrack.computeSampleStats())
|
||||||
|
document.body.textContent = performance.now() - start;
|
||||||
|
return;
|
||||||
|
|
||||||
const decoderConfig = await videoTrack.getDecoderConfig();
|
const decoderConfig = await videoTrack.getDecoderConfig();
|
||||||
const sampleSource = new Metamuxer.EncodedVideoSampleSource(await videoTrack.getCodec());
|
const sampleSource = new Metamuxer.EncodedVideoSampleSource(await videoTrack.getCodec());
|
||||||
output.addVideoTrack(sampleSource);
|
output.addVideoTrack(sampleSource);
|
||||||
@@ -65,7 +69,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
await output.finalize();
|
await output.finalize();
|
||||||
document.body.textContent = performance.now() - start;
|
|
||||||
|
|
||||||
console.log(target)
|
console.log(target)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -58,7 +58,7 @@ export {
|
|||||||
WEBM,
|
WEBM,
|
||||||
} from './input-format';
|
} from './input-format';
|
||||||
export { Input, InputOptions } from './input';
|
export { Input, InputOptions } from './input';
|
||||||
export { InputTrack, InputVideoTrack, InputAudioTrack } from './input-track';
|
export { InputTrack, InputVideoTrack, InputAudioTrack, SampleStats } from './input-track';
|
||||||
export {
|
export {
|
||||||
EncodedVideoSample,
|
EncodedVideoSample,
|
||||||
EncodedAudioSample,
|
EncodedAudioSample,
|
||||||
|
|||||||
+42
-1
@@ -1,10 +1,11 @@
|
|||||||
import { AudioCodec, MediaCodec, VideoCodec } from './codec';
|
import { AudioCodec, MediaCodec, VideoCodec } from './codec';
|
||||||
import { SampleRetrievalOptions } from './media-drain';
|
import { EncodedAudioSampleDrain, EncodedVideoSampleDrain, SampleRetrievalOptions } from './media-drain';
|
||||||
import { Rotation } from './misc';
|
import { Rotation } from './misc';
|
||||||
import { EncodedAudioSample, EncodedVideoSample } from './sample';
|
import { EncodedAudioSample, EncodedVideoSample } from './sample';
|
||||||
|
|
||||||
export interface InputTrackBacking {
|
export interface InputTrackBacking {
|
||||||
getCodec(): Promise<MediaCodec | null>;
|
getCodec(): Promise<MediaCodec | null>;
|
||||||
|
getFirstTimestamp(): Promise<number>;
|
||||||
computeDuration(): Promise<number>;
|
computeDuration(): Promise<number>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,6 +31,10 @@ export abstract class InputTrack {
|
|||||||
return this instanceof InputAudioTrack;
|
return this instanceof InputAudioTrack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getFirstTimestamp() {
|
||||||
|
return this._backing.getFirstTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
computeDuration() {
|
computeDuration() {
|
||||||
return this._backing.computeDuration();
|
return this._backing.computeDuration();
|
||||||
}
|
}
|
||||||
@@ -109,6 +114,10 @@ export class InputVideoTrack extends InputTrack {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
computeSampleStats() {
|
||||||
|
return computeSampleStats(new EncodedVideoSampleDrain(this));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InputAudioTrackBacking extends InputTrackBacking {
|
export interface InputAudioTrackBacking extends InputTrackBacking {
|
||||||
@@ -174,4 +183,36 @@ export class InputAudioTrack extends InputTrack {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
computeSampleStats() {
|
||||||
|
return computeSampleStats(new EncodedAudioSampleDrain(this));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @public */
|
||||||
|
export type SampleStats = {
|
||||||
|
sampleCount: number;
|
||||||
|
averageSampleRate: number;
|
||||||
|
averageBitrate: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const computeSampleStats = async (drain: EncodedVideoSampleDrain | EncodedAudioSampleDrain): Promise<SampleStats> => {
|
||||||
|
let startTimestamp = Infinity;
|
||||||
|
let endTimestamp = -Infinity;
|
||||||
|
let sampleCount = 0;
|
||||||
|
let totalSampleBytes = 0;
|
||||||
|
|
||||||
|
for await (const sample of drain.samples(undefined, undefined, { metadataOnly: true })) {
|
||||||
|
startTimestamp = Math.min(startTimestamp, sample.timestamp);
|
||||||
|
endTimestamp = Math.max(endTimestamp, sample.timestamp + sample.duration);
|
||||||
|
|
||||||
|
sampleCount++;
|
||||||
|
totalSampleBytes += sample.byteLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
sampleCount,
|
||||||
|
averageSampleRate: sampleCount ? Math.fround(sampleCount / (endTimestamp - startTimestamp)) : 0,
|
||||||
|
averageBitrate: sampleCount ? Math.fround(8 * totalSampleBytes / (endTimestamp - startTimestamp)) : 0,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
@@ -1673,6 +1673,11 @@ abstract class IsobmffTrackBacking<
|
|||||||
throw new Error('Not implemented on base class.');
|
throw new Error('Not implemented on base class.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getFirstTimestamp() {
|
||||||
|
const firstSample = await this.getFirstSample({ metadataOnly: true });
|
||||||
|
return firstSample?.timestamp ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
async computeDuration() {
|
async computeDuration() {
|
||||||
const lastSample = await this.getSample(Infinity, { metadataOnly: true });
|
const lastSample = await this.getSample(Infinity, { metadataOnly: true });
|
||||||
return (lastSample?.timestamp ?? 0) + (lastSample?.duration ?? 0);
|
return (lastSample?.timestamp ?? 0) + (lastSample?.duration ?? 0);
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
- Throw if edit list detected
|
- Throw if edit list detected
|
||||||
- Add the new audio codecs to muxers
|
- Add the new audio codecs to muxers
|
||||||
- Mov muxer!!! Only mov can hold PCM audio, MP4 cannot
|
- Mov muxer!!! Only mov can hold PCM audio, MP4 cannot
|
||||||
- Metadata methods for computing average fps and bitrate
|
|
||||||
- A stream source?? Or like a callback-driven source
|
- A stream source?? Or like a callback-driven source
|
||||||
- onRead callback for Source
|
- onRead callback for Source
|
||||||
- onHeader, etc callbacks for Matroska
|
- onHeader, etc callbacks for Matroska
|
||||||
- Add cslg box
|
- Add cslg box
|
||||||
|
- https://github.com/Vanilagy/mp4-muxer/issues/83 tell him it's possible now
|
||||||
Reference in New Issue
Block a user