mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-10-03 13:53:53 +02:00
Add InputTrack.number
This commit is contained in:
@@ -306,8 +306,8 @@ const conversion = await Conversion.init({
|
|||||||
output,
|
output,
|
||||||
|
|
||||||
// Function gets invoked for each video track:
|
// Function gets invoked for each video track:
|
||||||
video: (videoTrack, n) => {
|
video: (videoTrack) => {
|
||||||
if (n > 1) {
|
if (videoTrack.number > 1) {
|
||||||
// Keep only the first video track
|
// Keep only the first video track
|
||||||
return { discard: true };
|
return { discard: true };
|
||||||
}
|
}
|
||||||
@@ -319,7 +319,7 @@ const conversion = await Conversion.init({
|
|||||||
},
|
},
|
||||||
|
|
||||||
// Async functions work too:
|
// Async functions work too:
|
||||||
audio: async (audioTrack, n) => {
|
audio: async (audioTrack) => {
|
||||||
if (audioTrack.languageCode !== 'rus') {
|
if (audioTrack.languageCode !== 'rus') {
|
||||||
// Keep only Russian audio tracks
|
// Keep only Russian audio tracks
|
||||||
return { discard: true };
|
return { discard: true };
|
||||||
|
|||||||
@@ -556,14 +556,16 @@ const output = new Output(...);
|
|||||||
const conversion = await Conversion.init({
|
const conversion = await Conversion.init({
|
||||||
input,
|
input,
|
||||||
output,
|
output,
|
||||||
video: {
|
video: track => ({
|
||||||
width: 480,
|
width: 480,
|
||||||
bitrate: QUALITY_LOW,
|
bitrate: QUALITY_LOW,
|
||||||
},
|
discard: track.number > 1, // Keep only the first video track
|
||||||
audio: {
|
}),
|
||||||
|
audio: track => ({
|
||||||
numberOfChannels: 1,
|
numberOfChannels: 1,
|
||||||
bitrate: QUALITY_LOW,
|
bitrate: QUALITY_LOW,
|
||||||
},
|
discard: track.number > 1, // Keep only the first audio track
|
||||||
|
}),
|
||||||
trim: {
|
trim: {
|
||||||
// Let's keep only the first 60 seconds
|
// Let's keep only the first 60 seconds
|
||||||
start: 0,
|
start: 0,
|
||||||
|
|||||||
@@ -98,6 +98,10 @@ Once you have an `InputTrack`, you can start extracting metadata from it.
|
|||||||
// Get a unique ID for this track in the input file:
|
// Get a unique ID for this track in the input file:
|
||||||
track.id; // => number
|
track.id; // => number
|
||||||
|
|
||||||
|
// Get the 1-based index of this track among all tracks of the same type
|
||||||
|
// (e.g., first video track is 1, second video track is 2, etc.):
|
||||||
|
track.number; // => number
|
||||||
|
|
||||||
// Check the track's type:
|
// Check the track's type:
|
||||||
track.type; // => 'video' | 'audio' | 'subtitle';
|
track.type; // => 'video' | 'audio' | 'subtitle';
|
||||||
|
|
||||||
|
|||||||
@@ -62,13 +62,15 @@ const compressFile = async (resource: File | string) => {
|
|||||||
currentConversion = await Conversion.init({
|
currentConversion = await Conversion.init({
|
||||||
input,
|
input,
|
||||||
output,
|
output,
|
||||||
video: {
|
video: track => ({
|
||||||
width: 320, // Height will be deduced automatically to retain aspect ratio
|
width: 320, // Height will be deduced automatically to retain aspect ratio
|
||||||
bitrate: QUALITY_VERY_LOW,
|
bitrate: QUALITY_VERY_LOW,
|
||||||
},
|
discard: track.number > 1, // Keep only the first video track
|
||||||
audio: {
|
}),
|
||||||
|
audio: track => ({
|
||||||
bitrate: 32e3,
|
bitrate: 32e3,
|
||||||
},
|
discard: track.number > 1, // Keep only the first audio track
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Keep track of progress
|
// Keep track of progress
|
||||||
|
|||||||
@@ -146,6 +146,10 @@ class AdtsAudioTrackBacking implements InputAudioTrackBacking {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNumber() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
async getFirstTimestamp() {
|
async getFirstTimestamp() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-2
@@ -66,7 +66,8 @@ export type ConversionOptions = {
|
|||||||
* Video-specific options. When passing an object, the same options are applied to all video tracks. When passing a
|
* Video-specific options. When passing an object, the same options are applied to all video tracks. When passing a
|
||||||
* function, it will be invoked for each video track and is expected to return or resolve to the options
|
* function, it will be invoked for each video track and is expected to return or resolve to the options
|
||||||
* for that specific track. The function is passed an instance of {@link InputVideoTrack} as well as a number `n`,
|
* for that specific track. The function is passed an instance of {@link InputVideoTrack} as well as a number `n`,
|
||||||
* which is the 1-based index of the track in the list of all video tracks.
|
* which is the 1-based index of the track in the list of all video tracks. Using `n` is deprecated, prefer the
|
||||||
|
* identical `track.number` instead.
|
||||||
*/
|
*/
|
||||||
video?: ConversionVideoOptions
|
video?: ConversionVideoOptions
|
||||||
| ((track: InputVideoTrack, n: number) => MaybePromise<ConversionVideoOptions | undefined>);
|
| ((track: InputVideoTrack, n: number) => MaybePromise<ConversionVideoOptions | undefined>);
|
||||||
@@ -75,7 +76,8 @@ export type ConversionOptions = {
|
|||||||
* Audio-specific options. When passing an object, the same options are applied to all audio tracks. When passing a
|
* Audio-specific options. When passing an object, the same options are applied to all audio tracks. When passing a
|
||||||
* function, it will be invoked for each audio track and is expected to return or resolve to the options
|
* function, it will be invoked for each audio track and is expected to return or resolve to the options
|
||||||
* for that specific track. The function is passed an instance of {@link InputAudioTrack} as well as a number `n`,
|
* for that specific track. The function is passed an instance of {@link InputAudioTrack} as well as a number `n`,
|
||||||
* which is the 1-based index of the track in the list of all audio tracks.
|
* which is the 1-based index of the track in the list of all audio tracks. Using `n` is deprecated, prefer the
|
||||||
|
* identical `track.number` instead.
|
||||||
*/
|
*/
|
||||||
audio?: ConversionAudioOptions
|
audio?: ConversionAudioOptions
|
||||||
| ((track: InputAudioTrack, n: number) => MaybePromise<ConversionAudioOptions | undefined>);
|
| ((track: InputAudioTrack, n: number) => MaybePromise<ConversionAudioOptions | undefined>);
|
||||||
|
|||||||
@@ -529,6 +529,10 @@ class FlacAudioTrackBacking implements InputAudioTrackBacking {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNumber() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
getCodec() {
|
getCodec() {
|
||||||
return 'flac' as const;
|
return 'flac' as const;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ export type PacketStats = {
|
|||||||
|
|
||||||
export interface InputTrackBacking {
|
export interface InputTrackBacking {
|
||||||
getId(): number;
|
getId(): number;
|
||||||
|
getNumber(): number;
|
||||||
getCodec(): MediaCodec | null;
|
getCodec(): MediaCodec | null;
|
||||||
getInternalCodecId(): string | number | Uint8Array | null;
|
getInternalCodecId(): string | number | Uint8Array | null;
|
||||||
getName(): string | null;
|
getName(): string | null;
|
||||||
@@ -94,6 +95,15 @@ export abstract class InputTrack {
|
|||||||
return this._backing.getId();
|
return this._backing.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The 1-based index of this track among all tracks of the same type in the input file. For example, the first
|
||||||
|
* video track has number 1, the second video track has number 2, and so on. The index refers to the order in
|
||||||
|
* which the tracks are returned by {@link Input.getTracks()}.
|
||||||
|
*/
|
||||||
|
get number() {
|
||||||
|
return this._backing.getNumber();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The identifier of the codec used internally by the container. It is not homogenized by Mediabunny
|
* The identifier of the codec used internally by the container. It is not homogenized by Mediabunny
|
||||||
* and depends entirely on the container format.
|
* and depends entirely on the container format.
|
||||||
|
|||||||
@@ -2335,6 +2335,25 @@ abstract class IsobmffTrackBacking implements InputTrackBacking {
|
|||||||
return this.internalTrack.id;
|
return this.internalTrack.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNumber() {
|
||||||
|
const demuxer = this.internalTrack.demuxer;
|
||||||
|
const inputTrack = this.internalTrack.inputTrack!;
|
||||||
|
const trackType = inputTrack.type;
|
||||||
|
|
||||||
|
let number = 0;
|
||||||
|
for (const track of demuxer.tracks) {
|
||||||
|
if (track.inputTrack!.type === trackType) {
|
||||||
|
number++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (track === this.internalTrack) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
getCodec(): MediaCodec | null {
|
getCodec(): MediaCodec | null {
|
||||||
throw new Error('Not implemented on base class.');
|
throw new Error('Not implemented on base class.');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1859,6 +1859,27 @@ abstract class MatroskaTrackBacking implements InputTrackBacking {
|
|||||||
return this.internalTrack.id;
|
return this.internalTrack.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNumber() {
|
||||||
|
const demuxer = this.internalTrack.demuxer;
|
||||||
|
const inputTrack = this.internalTrack.inputTrack!;
|
||||||
|
const trackType = inputTrack.type;
|
||||||
|
|
||||||
|
let number = 0;
|
||||||
|
for (const segment of demuxer.segments) {
|
||||||
|
for (const track of segment.tracks) {
|
||||||
|
if (track.inputTrack!.type === trackType) {
|
||||||
|
number++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (track === this.internalTrack) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
getCodec(): MediaCodec | null {
|
getCodec(): MediaCodec | null {
|
||||||
throw new Error('Not implemented on base class.');
|
throw new Error('Not implemented on base class.');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -217,6 +217,10 @@ class Mp3AudioTrackBacking implements InputAudioTrackBacking {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNumber() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
async getFirstTimestamp() {
|
async getFirstTimestamp() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -746,6 +746,25 @@ export abstract class MpegTsTrackBacking implements InputTrackBacking {
|
|||||||
return this.elementaryStream.pid;
|
return this.elementaryStream.pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNumber() {
|
||||||
|
const demuxer = this.elementaryStream.demuxer;
|
||||||
|
const trackType = this.elementaryStream.info.type;
|
||||||
|
|
||||||
|
let number = 0;
|
||||||
|
for (const track of demuxer.tracks) {
|
||||||
|
if (track.type === trackType) {
|
||||||
|
number++;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(track._backing instanceof MpegTsTrackBacking);
|
||||||
|
if (track._backing.elementaryStream === this.elementaryStream) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
getCodec(): MediaCodec | null {
|
getCodec(): MediaCodec | null {
|
||||||
throw new Error('Not implemented on base class.');
|
throw new Error('Not implemented on base class.');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -428,6 +428,16 @@ class OggAudioTrackBacking implements InputAudioTrackBacking {
|
|||||||
return this.bitstream.serialNumber;
|
return this.bitstream.serialNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNumber() {
|
||||||
|
// All Ogg tracks are audio, so the track's index + 1 is its number
|
||||||
|
const index = this.demuxer.tracks.findIndex(
|
||||||
|
t => (t._backing as OggAudioTrackBacking).bitstream === this.bitstream,
|
||||||
|
);
|
||||||
|
assert(index !== -1);
|
||||||
|
|
||||||
|
return index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
getNumberOfChannels() {
|
getNumberOfChannels() {
|
||||||
return this.bitstream.numberOfChannels;
|
return this.bitstream.numberOfChannels;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -356,6 +356,10 @@ class WaveAudioTrackBacking implements InputAudioTrackBacking {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getNumber() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
getCodec() {
|
getCodec() {
|
||||||
return this.demuxer.getCodec();
|
return this.demuxer.getCodec();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user