mirror of
https://github.com/arcodange-org/mediabunny.git
synced 2026-09-27 02:43:48 +02:00
Fix tenc fallback for encrypted ISOBMFF files (#470)
* fix tenc fallback * Add test case --------- Co-authored-by: Vanilagy <[email protected]>
This commit is contained in:
@@ -3151,9 +3151,10 @@ abstract class IsobmffTrackBacking implements InputTrackBacking {
|
|||||||
|
|
||||||
data = readBytes(slice, sampleInfo.sampleSize);
|
data = readBytes(slice, sampleInfo.sampleSize);
|
||||||
|
|
||||||
if (this.internalTrack.encryptionAuxInfo) {
|
if (this.internalTrack.encryptionInfo) {
|
||||||
assert(this.internalTrack.encryptionInfo);
|
let sampleEncryption: SampleEncryptionInfo | null = null;
|
||||||
|
|
||||||
|
if (this.internalTrack.encryptionAuxInfo) {
|
||||||
const entries = await resolveEncryptionAuxInfo(
|
const entries = await resolveEncryptionAuxInfo(
|
||||||
this.internalTrack.demuxer.reader,
|
this.internalTrack.demuxer.reader,
|
||||||
this.internalTrack.encryptionInfo,
|
this.internalTrack.encryptionInfo,
|
||||||
@@ -3161,7 +3162,13 @@ abstract class IsobmffTrackBacking implements InputTrackBacking {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (sampleIndex < entries.length) {
|
if (sampleIndex < entries.length) {
|
||||||
data = await decryptSample(this.internalTrack, entries[sampleIndex]!, data, null);
|
sampleEncryption = entries[sampleIndex]!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sampleEncryption ??= getDefaultSampleEncryption(this.internalTrack.encryptionInfo);
|
||||||
|
if (sampleEncryption) {
|
||||||
|
data = await decryptSample(this.internalTrack, sampleEncryption, data, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3207,8 +3214,12 @@ abstract class IsobmffTrackBacking implements InputTrackBacking {
|
|||||||
|
|
||||||
data = readBytes(slice, fragmentSample.byteSize);
|
data = readBytes(slice, fragmentSample.byteSize);
|
||||||
|
|
||||||
if (fragmentSample.encryption) {
|
if (this.internalTrack.encryptionInfo) {
|
||||||
data = await decryptSample(this.internalTrack, fragmentSample.encryption, data, fragment);
|
const sampleEncryption = fragmentSample.encryption
|
||||||
|
?? getDefaultSampleEncryption(this.internalTrack.encryptionInfo);
|
||||||
|
if (sampleEncryption) {
|
||||||
|
data = await decryptSample(this.internalTrack, sampleEncryption, data, fragment);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3779,6 +3790,17 @@ const resolveEncryptionAuxInfo = async (
|
|||||||
return entries;
|
return entries;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getDefaultSampleEncryption = (encryptionInfo: TrackEncryptionInfo): SampleEncryptionInfo | null => {
|
||||||
|
if (!encryptionInfo.defaultConstantIv) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
iv: encryptionInfo.defaultConstantIv,
|
||||||
|
subsamples: null,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const decryptSample = async (
|
const decryptSample = async (
|
||||||
track: InternalTrack,
|
track: InternalTrack,
|
||||||
sampleEncryption: SampleEncryptionInfo,
|
sampleEncryption: SampleEncryptionInfo,
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { expect, test } from 'vitest';
|
||||||
|
import { Input } from '../../src/input.js';
|
||||||
|
import { UrlSource } from '../../src/source.js';
|
||||||
|
import { ALL_FORMATS } from '../../src/input-format.js';
|
||||||
|
import { AudioSampleSink } from '../../src/media-sink.js';
|
||||||
|
import { assert } from '../../src/misc.js';
|
||||||
|
|
||||||
|
test('Encrypted MP4 without senc', async () => {
|
||||||
|
using input = new Input({
|
||||||
|
source: new UrlSource('/639955605-b752f7ad-7ce8-43c2-8ae9-88e74c6ae696.mp4'),
|
||||||
|
formats: ALL_FORMATS,
|
||||||
|
formatOptions: {
|
||||||
|
isobmff: {
|
||||||
|
resolveKeyId: () => 'aabbccddeeff00112233445566778899',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const audioTrack = await input.getPrimaryAudioTrack();
|
||||||
|
assert(audioTrack);
|
||||||
|
|
||||||
|
// Test that it can decode
|
||||||
|
const sink = new AudioSampleSink(audioTrack);
|
||||||
|
using firstSample = await sink.getSample(0);
|
||||||
|
assert(firstSample);
|
||||||
|
expect(firstSample.timestamp).toBe(0);
|
||||||
|
});
|
||||||
Binary file not shown.
Reference in New Issue
Block a user