shaka-player
Version:
DASH/EME video player library
170 lines (146 loc) • 5.9 kB
JavaScript
/*! @license
* Shaka Player
* Copyright 2016 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
describe('Transmuxer', () => {
const ContentType = shaka.util.ManifestParserUtils.ContentType;
const videoSegmentUri = '/base/test/test/assets/video.ts';
const audioSegmentUri = '/base/test/test/assets/audio.ts';
const mp4MimeType = 'video/mp4; codecs="avc1.42E01E"';
const transportStreamVideoMimeType = 'video/mp2t; codecs="avc1.42E01E"';
const transportStreamAudioMimeType = 'video/mp2t; codecs="mp4a.40.2"';
/** @type {!ArrayBuffer} */
let videoSegment;
/** @type {!ArrayBuffer} */
let audioSegment;
/** @type {!ArrayBuffer} */
let emptySegment;
/** @type {!shaka.media.Transmuxer} */
let transmuxer;
beforeAll(async () => {
const responses = await Promise.all([
shaka.test.Util.fetch(videoSegmentUri),
shaka.test.Util.fetch(audioSegmentUri),
]);
videoSegment = responses[0];
audioSegment = responses[1];
emptySegment = new ArrayBuffer(0);
});
beforeEach(() => {
transmuxer = new shaka.media.Transmuxer();
});
afterEach(async () => {
await transmuxer.destroy();
});
describe('isSupported', () => {
const Transmuxer = shaka.media.Transmuxer;
it('returns whether the content type is supported', () => {
expect(Transmuxer.isSupported(
mp4MimeType, ContentType.VIDEO)).toBe(false);
expect(Transmuxer.isSupported(
transportStreamVideoMimeType, ContentType.VIDEO)).toBe(true);
});
// Issue #1991
it('handles upper-case MIME types', () => {
const mimeType = transportStreamVideoMimeType.replace('mp2t', 'MP2T');
expect(Transmuxer.isSupported(mimeType, ContentType.VIDEO)).toBe(true);
});
});
describe('convertTsCodecs', () => {
const convertTsCodecs =
(type, codecs) => shaka.media.Transmuxer.convertTsCodecs(type, codecs);
it('returns converted codecs', () => {
const convertedVideoCodecs =
convertTsCodecs(ContentType.VIDEO, transportStreamVideoMimeType);
const convertedAudioCodecs =
convertTsCodecs(ContentType.AUDIO, transportStreamAudioMimeType);
const expectedVideoCodecs = 'video/mp4; codecs="avc1.42E01E"';
const expectedAudioCodecs = 'audio/mp4; codecs="mp4a.40.2"';
expect(convertedVideoCodecs).toBe(expectedVideoCodecs);
expect(convertedAudioCodecs).toBe(expectedAudioCodecs);
});
it('converts legacy avc1 codec strings', () => {
expect(
convertTsCodecs(
ContentType.VIDEO, 'video/mp2t; codecs="avc1.100.42"'))
.toBe('video/mp4; codecs="avc1.64002a"');
expect(
convertTsCodecs(ContentType.VIDEO, 'video/mp2t; codecs="avc1.77.80"'))
.toBe('video/mp4; codecs="avc1.4d0050"');
expect(
convertTsCodecs(ContentType.VIDEO, 'video/mp2t; codecs="avc1.66.1"'))
.toBe('video/mp4; codecs="avc1.420001"');
});
// Issue #1991
it('handles upper-case MIME types', () => {
expect(convertTsCodecs(
ContentType.VIDEO, 'video/MP2T; codecs="avc1.420001"'))
.toBe('video/mp4; codecs="avc1.420001"');
});
});
describe('transmuxing', () => {
it('transmux video from TS to MP4', async () => {
let sawMDAT = false;
const transmuxedData = await transmuxer.transmux(videoSegment);
expect(transmuxedData.data).toEqual(jasmine.any(Uint8Array));
expect(transmuxedData.data.length).toBeGreaterThan(0);
expect(transmuxedData.captions).toEqual(jasmine.any(Array));
new shaka.util.Mp4Parser()
.box('mdat', shaka.util.Mp4Parser.allData((data) => {
sawMDAT = true;
expect(data.byteLength).toBeGreaterThan(0);
}))
.parse(transmuxedData.data);
expect(sawMDAT).toBeTruthy();
});
it('transmux audio from TS to MP4', async () => {
let sawMDAT = false;
const transmuxedData = await transmuxer.transmux(audioSegment);
expect(transmuxedData.data).toEqual(jasmine.any(Uint8Array));
expect(transmuxedData.data.length).toBeGreaterThan(0);
expect(transmuxedData.captions).toEqual(jasmine.any(Array));
new shaka.util.Mp4Parser()
.box('mdat', shaka.util.Mp4Parser.allData((data) => {
sawMDAT = true;
expect(data.byteLength).toBeGreaterThan(0);
}))
.parse(transmuxedData.data);
expect(sawMDAT).toBeTruthy();
});
it('transmux empty video from TS to MP4', async () => {
let sawMDAT = false;
const transmuxedData = await transmuxer.transmux(emptySegment);
expect(transmuxedData.data).toEqual(jasmine.any(Uint8Array));
expect(transmuxedData.captions).toEqual([]);
new shaka.util.Mp4Parser()
.box('mdat', shaka.util.Mp4Parser.allData((data) => {
sawMDAT = true;
}))
.parse(transmuxedData.data);
expect(sawMDAT).toBeFalsy();
});
it('passes through true timestamps', async () => {
let parsed = false;
const expectedMp4Timestamp = 5166000; // in timescale units
let mp4Timestamp;
const transmuxedData = await transmuxer.transmux(videoSegment);
const Mp4Parser = shaka.util.Mp4Parser;
new Mp4Parser()
.box('moof', Mp4Parser.children)
.box('traf', Mp4Parser.children)
.fullBox('tfdt', (box) => {
goog.asserts.assert(
box.version == 0 || box.version == 1,
'TFDT version can only be 0 or 1');
const parsedTFDTBox = shaka.util.Mp4BoxParsers.parseTFDT(
box.reader, box.version);
mp4Timestamp = parsedTFDTBox.baseMediaDecodeTime;
parsed = true;
})
.parse(transmuxedData.data);
expect(parsed).toBe(true);
expect(mp4Timestamp).toBe(expectedMp4Timestamp);
});
});
});