diff --git a/src/codec.ts b/src/codec.ts index a396e70..b9414fd 100644 --- a/src/codec.ts +++ b/src/codec.ts @@ -337,6 +337,7 @@ export const extractVideoCodecString = (trackInfo: { codec: VideoCodec | null; codecDescription: Uint8Array | null; colorSpace: VideoColorSpaceInit | null; + avcType: 1 | 3 | null; avcCodecInfo: AvcDecoderConfigurationRecord | null; hevcCodecInfo: HevcDecoderConfigurationRecord | null; vp9CodecInfo: Vp9CodecInfo | null; @@ -345,6 +346,8 @@ export const extractVideoCodecString = (trackInfo: { const { codec, codecDescription, colorSpace, avcCodecInfo, hevcCodecInfo, vp9CodecInfo, av1CodecInfo } = trackInfo; if (codec === 'avc') { + assert(trackInfo.avcType !== null); + if (avcCodecInfo) { const bytes = new Uint8Array([ avcCodecInfo.avcProfileIndication, @@ -352,14 +355,14 @@ export const extractVideoCodecString = (trackInfo: { avcCodecInfo.avcLevelIndication, ]); - return `avc1.${bytesToHexString(bytes)}`; + return `avc${trackInfo.avcType}.${bytesToHexString(bytes)}`; } if (!codecDescription || codecDescription.byteLength < 4) { throw new TypeError('AVC decoder description is not provided or is not at least 4 bytes long.'); } - return `avc1.${bytesToHexString(codecDescription.subarray(1, 4))}`; + return `avc${trackInfo.avcType}.${bytesToHexString(codecDescription.subarray(1, 4))}`; } else if (codec === 'hevc') { let generalProfileSpace: number; let generalProfileIdc: number; diff --git a/src/isobmff/isobmff-demuxer.ts b/src/isobmff/isobmff-demuxer.ts index e1d047c..124c7b1 100644 --- a/src/isobmff/isobmff-demuxer.ts +++ b/src/isobmff/isobmff-demuxer.ts @@ -126,6 +126,7 @@ type InternalTrack = { codec: VideoCodec | null; codecDescription: Uint8Array | null; colorSpace: VideoColorSpaceInit | null; + avcType: 1 | 3 | null; avcCodecInfo: AvcDecoderConfigurationRecord | null; hevcCodecInfo: HevcDecoderConfigurationRecord | null; vp9CodecInfo: Vp9CodecInfo | null; @@ -836,6 +837,7 @@ export class IsobmffDemuxer extends Demuxer { codec: null, codecDescription: null, colorSpace: null, + avcType: null, avcCodecInfo: null, hevcCodecInfo: null, vp9CodecInfo: null, @@ -890,8 +892,9 @@ export class IsobmffDemuxer extends Demuxer { const lowercaseBoxName = sampleBoxInfo.name.toLowerCase(); if (track.info.type === 'video') { - if (lowercaseBoxName === 'avc1') { + if (lowercaseBoxName === 'avc1' || lowercaseBoxName === 'avc3') { track.info.codec = 'avc'; + track.info.avcType = lowercaseBoxName === 'avc1' ? 1 : 3; } else if (lowercaseBoxName === 'hvc1' || lowercaseBoxName === 'hev1') { track.info.codec = 'hevc'; } else if (lowercaseBoxName === 'vp08') { diff --git a/src/matroska/matroska-demuxer.ts b/src/matroska/matroska-demuxer.ts index e964bef..1992205 100644 --- a/src/matroska/matroska-demuxer.ts +++ b/src/matroska/matroska-demuxer.ts @@ -2319,6 +2319,7 @@ class MatroskaVideoTrackBacking extends MatroskaTrackBacking implements InputVid codec: this.internalTrack.info.codec, codecDescription: this.internalTrack.info.codecDescription, colorSpace: this.internalTrack.info.colorSpace, + avcType: 1, // We don't know better (or do we?) so just assume 'avc1' avcCodecInfo: this.internalTrack.info.codec === 'avc' && firstPacket ? extractAvcDecoderConfigurationRecord(firstPacket.data) : null,