Add media conversion utility function, fix fragment/cluster reading issues, expand color space logic, add qualitative bitrates, & many other fixes and improvements

This commit is contained in:
Vanilagy
2025-01-19 18:55:12 +01:00
parent d323c2be8e
commit 70b88332b2
19 changed files with 1504 additions and 217 deletions
+28
View File
@@ -1,9 +1,11 @@
import { AudioCodec, MediaCodec, VideoCodec } from './codec';
import { EncodedAudioSampleSink, EncodedVideoSampleSink, SampleRetrievalOptions } from './media-sink';
import { Rotation } from './misc';
import { TrackType } from './output';
import { EncodedAudioSample, EncodedVideoSample } from './sample';
export interface InputTrackBacking {
getId(): number;
getCodec(): Promise<MediaCodec | null>;
getFirstTimestamp(): Promise<number>;
computeDuration(): Promise<number>;
@@ -20,6 +22,7 @@ export abstract class InputTrack {
this._backing = backing;
}
abstract getType(): TrackType;
abstract getCodec(): Promise<MediaCodec | null>;
abstract getCodecMimeType(): Promise<string | null>;
abstract canDecode(): Promise<boolean>;
@@ -33,6 +36,10 @@ export abstract class InputTrack {
return this instanceof InputAudioTrack;
}
getId() {
return this._backing.getId();
}
getFirstTimestamp() {
return this._backing.getFirstTimestamp();
}
@@ -51,6 +58,7 @@ export interface InputVideoTrackBacking extends InputTrackBacking {
getCodedWidth(): Promise<number>;
getCodedHeight(): Promise<number>;
getRotation(): Promise<Rotation>;
getColorSpace(): Promise<VideoColorSpaceInit>;
getDecoderConfig(): Promise<VideoDecoderConfig | null>;
getFirstSample(options: SampleRetrievalOptions): Promise<EncodedVideoSample | null>;
getSample(timestamp: number, options: SampleRetrievalOptions): Promise<EncodedVideoSample | null>;
@@ -71,6 +79,10 @@ export class InputVideoTrack extends InputTrack {
this._backing = backing;
}
getType(): TrackType {
return 'video';
}
getCodec(): Promise<VideoCodec | null> {
return this._backing.getCodec();
}
@@ -97,6 +109,18 @@ export class InputVideoTrack extends InputTrack {
return rotation % 180 === 0 ? this._backing.getCodedHeight() : this._backing.getCodedWidth();
}
getColorSpace() {
return this._backing.getColorSpace();
}
async hasHighDynamicRange() {
const colorSpace = await this._backing.getColorSpace();
return (colorSpace.primaries as string) === 'bt2020' || (colorSpace.primaries as string) === 'smpte432'
|| (colorSpace.transfer as string) === 'pg' || (colorSpace.transfer as string) === 'hlg'
|| (colorSpace.matrix as string) === 'bt2020-ncl';
}
getDecoderConfig() {
return this._backing.getDecoderConfig();
}
@@ -150,6 +174,10 @@ export class InputAudioTrack extends InputTrack {
this._backing = backing;
}
getType(): TrackType {
return 'audio';
}
getCodec(): Promise<AudioCodec | null> {
return this._backing.getCodec();
}