diff --git a/dev/demux.html b/dev/demux.html
index c86d370..091f7dd 100644
--- a/dev/demux.html
+++ b/dev/demux.html
@@ -46,10 +46,12 @@
const target = new Metamuxer.BufferTarget();
const output = new Metamuxer.Output({
- format: new Metamuxer.MovOutputFormat({ fastStart: undefined }),
+ format: new Metamuxer.MkvOutputFormat(),
target
});
+ console.log(await input.getFormat());
+
const audioTrack = await input.getPrimaryAudioTrack();
const videoTrack = await input.getPrimaryVideoTrack();
@@ -57,9 +59,9 @@
const decoderConfig = await audioTrack.getDecoderConfig();
const sampleSource = new Metamuxer.EncodedAudioSampleSource(await audioTrack.getCodec());
- const audioDataSource = new Metamuxer.AudioDataSource({ codec: 'alaw', bitrate: 128e3 });
+ const audioDataSource = new Metamuxer.AudioDataSource({ codec: 'pcm-s16', bitrate: 128e3 });
const videoSampleSource = new Metamuxer.EncodedVideoSampleSource(await videoTrack.getCodec());
- output.addAudioTrack(audioDataSource ?? sampleSource);
+ output.addAudioTrack(sampleSource);
output.addVideoTrack(videoSampleSource);
output.start();
@@ -67,18 +69,22 @@
const videoDecoderConfig = await videoTrack.getDecoderConfig();
- /*
+
+
for await (const sample of drain.samples()) {
+ //console.log(sample.timestamp);
//sample.timestamp *= 2;
//console.log(sample);
//console.log(sample)
await sampleSource.digest(sample, { decoderConfig });
}
- */
- for await (const { data } of new Metamuxer.AudioDataDrain(audioTrack).data()) {
+ /*
+ for await (const { data, timestamp } of new Metamuxer.AudioDataDrain(audioTrack).data()) {
+ //console.log("wow", data.timestamp);
//console.log(sample)
await audioDataSource.digest(data);
}
+ */
for await (const sample of new Metamuxer.EncodedVideoSampleDrain(videoTrack).samples()) {
//console.log(sample)
await videoSampleSource.digest(sample, { decoderConfig: videoDecoderConfig });
@@ -96,7 +102,7 @@
a.click();
URL.revokeObjectURL(url);
}
- download(new Blob([target.buffer]), 'converted.mov');
+ download(new Blob([target.buffer]), 'converted.mkv');
document.body.textContent = performance.now() - start;
diff --git a/src/input-format.ts b/src/input-format.ts
index c673d7c..9f4a44f 100644
--- a/src/input-format.ts
+++ b/src/input-format.ts
@@ -45,7 +45,7 @@ export class Mp4InputFormat extends IsobmffInputFormat {
/** @internal */
override async _canReadInput(input: Input) {
const majorBrand = await this._getMajorBrand(input);
- return majorBrand !== 'qt ';
+ return !!majorBrand && majorBrand !== 'qt ';
}
getName() {
diff --git a/src/matroska/matroska-muxer.ts b/src/matroska/matroska-muxer.ts
index 549ac6b..1c111fb 100644
--- a/src/matroska/matroska-muxer.ts
+++ b/src/matroska/matroska-muxer.ts
@@ -32,8 +32,11 @@ import {
} from '../subtitles';
import {
AudioCodec,
+ PCM_CODECS,
+ PcmAudioCodec,
SubtitleCodec,
VideoCodec,
+ parsePcmCodec,
validateAudioChunkMetadata,
validateSubtitleMetadata,
validateVideoChunkMetadata,
@@ -103,15 +106,27 @@ type MatroskaAudioTrackData = MatroskaTrackData & { type: 'audio' };
type MatroskaSubtitleTrackData = MatroskaTrackData & { type: 'subtitle' };
const CODEC_STRING_MAP: Partial> = {
- avc: 'V_MPEG4/ISO/AVC',
- hevc: 'V_MPEGH/ISO/HEVC',
- vp8: 'V_VP8',
- vp9: 'V_VP9',
- av1: 'V_AV1',
- aac: 'A_AAC', // TODO is this even correct
- opus: 'A_OPUS',
- vorbis: 'A_VORBIS',
- webvtt: 'S_TEXT/WEBVTT',
+ 'avc': 'V_MPEG4/ISO/AVC',
+ 'hevc': 'V_MPEGH/ISO/HEVC',
+ 'vp8': 'V_VP8',
+ 'vp9': 'V_VP9',
+ 'av1': 'V_AV1',
+
+ 'aac': 'A_AAC',
+ 'mp3': 'A_MPEG/L3',
+ 'opus': 'A_OPUS',
+ 'vorbis': 'A_VORBIS',
+ 'flac': 'A_FLAC',
+ 'pcm-u8': 'A_PCM/INT/LIT',
+ 'pcm-s16': 'A_PCM/INT/LIT',
+ 'pcm-s16be': 'A_PCM/INT/BIG',
+ 'pcm-s24': 'A_PCM/INT/LIT',
+ 'pcm-s24be': 'A_PCM/INT/BIG',
+ 'pcm-s32': 'A_PCM/INT/LIT',
+ 'pcm-s32be': 'A_PCM/INT/BIG',
+ 'pcm-f32': 'A_PCM/FLOAT/IEEE',
+
+ 'webvtt': 'S_TEXT/WEBVTT',
};
const TRACK_TYPE_MAP: Record = {
@@ -470,6 +485,10 @@ export class MatroskaMuxer extends Muxer {
}
private audioSpecificTrackInfo(trackData: MatroskaAudioTrackData) {
+ const pcmInfo = (PCM_CODECS as readonly string[]).includes(trackData.track.source._codec)
+ ? parsePcmCodec(trackData.track.source._codec as PcmAudioCodec)
+ : null;
+
return [
(trackData.info.decoderConfig.description
? {
@@ -480,7 +499,7 @@ export class MatroskaMuxer extends Muxer {
{ id: EBMLId.Audio, data: [
{ id: EBMLId.SamplingFrequency, data: new EBMLFloat32(trackData.info.sampleRate) },
{ id: EBMLId.Channels, data: trackData.info.numberOfChannels },
- // TODO Bit depth for when PCM is a thing
+ pcmInfo ? { id: EBMLId.BitDepth, data: 8 * pcmInfo.sampleSize } : null,
] },
];
}
diff --git a/src/media-drain.ts b/src/media-drain.ts
index 7d2c4ce..42242c1 100644
--- a/src/media-drain.ts
+++ b/src/media-drain.ts
@@ -995,7 +995,7 @@ class PcmAudioDecoderWrapper extends DecoderWrapper