Skip to content

Commit

Permalink
fix: export generateSidxKey add multiple audio/vtt playlists
Browse files Browse the repository at this point in the history
  • Loading branch information
brandonocasey committed Mar 15, 2021
1 parent 3910096 commit 85d24be
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 62 deletions.
9 changes: 4 additions & 5 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { version } from '../package.json';
import { toM3u8 } from './toM3u8';
import { toM3u8, generateSidxKey } from './toM3u8';
import { toPlaylists } from './toPlaylists';
import { inheritAttributes } from './inheritAttributes';
import { stringToMpdXml } from './stringToMpdXml';
import { parseUTCTimingScheme } from './parseUTCTimingScheme';
import {addSegmentsToPlaylist} from './segment/segmentBase.js';
import {addSidxSegmentsToPlaylist} from './segment/segmentBase.js';

const VERSION = version;

Expand All @@ -26,8 +26,6 @@ const parse = (manifestString, options = {}) => {
const parseUTCTiming = (manifestString) =>
parseUTCTimingScheme(stringToMpdXml(manifestString));

const addSidxSegmentsToPlaylist = addSegmentsToPlaylist;

export {
VERSION,
parse,
Expand All @@ -36,5 +34,6 @@ export {
inheritAttributes,
toPlaylists,
toM3u8,
addSidxSegmentsToPlaylist
addSidxSegmentsToPlaylist,
generateSidxKey
};
2 changes: 1 addition & 1 deletion src/segment/segmentBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ export const segmentsFromBase = (attributes) => {
* @param {Object} sidx the parsed sidx box
* @return {Object} the playlist object with the updated sidx information
*/
export const addSegmentsToPlaylist = (playlist, sidx, baseUrl) => {
export const addSidxSegmentsToPlaylist = (playlist, sidx, baseUrl) => {
// Retain init segment information
const initSegment = playlist.sidx.map ? playlist.sidx.map : null;
// Retain source duration from initial master manifest parsing
Expand Down
95 changes: 43 additions & 52 deletions src/toM3u8.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { values } from './utils/object';
import { findIndexes } from './utils/list';
import { addSegmentsToPlaylist } from './segment/segmentBase';
import { addSidxSegmentsToPlaylist as addSidxSegmentsToPlaylist_ } from './segment/segmentBase';
import { byteRangeToString } from './segment/urlType';

export const generateSidxKey = (sidx) => sidx &&
sidx.uri + '-' + byteRangeToString(sidx.byterange);

const mergeDiscontiguousPlaylists = playlists => {
const mergedPlaylists = values(playlists.reduce((acc, playlist) => {
// assuming playlist IDs are the same across periods
Expand Down Expand Up @@ -40,25 +43,24 @@ const mergeDiscontiguousPlaylists = playlists => {
});
};

const addSegmentInfoFromSidx = (playlists, sidxMapping = {}) => {
export const addSidxSegmentsToPlaylist = (playlist, sidxMapping) => {
const sidxKey = generateSidxKey(playlist.sidx);
const sidxMatch = sidxKey && sidxMapping[sidxKey] && sidxMapping[sidxKey].sidx;

if (sidxMatch) {
addSidxSegmentsToPlaylist_(playlist, sidxMatch, playlist.sidx.resolvedUri);
}

return playlist;
};

export const addSidxSegmentsToPlaylists = (playlists, sidxMapping = {}) => {
if (!Object.keys(sidxMapping).length) {
return playlists;
}

for (const i in playlists) {
const playlist = playlists[i];

if (!playlist.sidx) {
continue;
}

const sidxKey = playlist.sidx.uri + '-' +
byteRangeToString(playlist.sidx.byterange);
const sidxMatch = sidxMapping[sidxKey] && sidxMapping[sidxKey].sidx;

if (playlist.sidx && sidxMatch) {
addSegmentsToPlaylist(playlist, sidxMatch, playlist.sidx.resolvedUri);
}
playlists[i] = addSidxSegmentsToPlaylist(playlists[i], sidxMapping);
}

return playlists;
Expand Down Expand Up @@ -143,23 +145,17 @@ export const organizeAudioPlaylists = (playlists, sidxMapping = {}) => {
label = `${playlist.attributes.lang}${roleLabel}`;
}

// skip if we already have the highest quality audio for a language
if (a[label] &&
a[label].playlists[0].attributes.BANDWIDTH >
playlist.attributes.bandwidth) {
return a;
if (!a[label]) {
a[label] = {
language,
autoselect: true,
default: role === 'main',
playlists: [],
uri: ''
};
}

a[label] = {
language,
autoselect: true,
default: role === 'main',
playlists: addSegmentInfoFromSidx(
[formatAudioPlaylist(playlist)],
sidxMapping
),
uri: ''
};
a[label].playlists.push(addSidxSegmentsToPlaylist(formatAudioPlaylist(playlist), sidxMapping));

if (typeof mainPlaylist === 'undefined' && role === 'main') {
mainPlaylist = playlist;
Expand All @@ -183,21 +179,16 @@ export const organizeVttPlaylists = (playlists, sidxMapping = {}) => {
return playlists.reduce((a, playlist) => {
const label = playlist.attributes.lang || 'text';

// skip if we already have subtitles
if (a[label]) {
return a;
if (!a[label]) {
a[label] = {
language: label,
default: false,
autoselect: false,
playlists: [],
uri: ''
};
}

a[label] = {
language: label,
default: false,
autoselect: false,
playlists: addSegmentInfoFromSidx(
[formatVttPlaylist(playlist)],
sidxMapping
),
uri: ''
};
a[label].playlists.push(addSidxSegmentsToPlaylist(formatVttPlaylist(playlist), sidxMapping));

return a;
}, {});
Expand Down Expand Up @@ -237,6 +228,13 @@ export const formatVideoPlaylist = ({ attributes, segments, sidx }) => {
return playlist;
};

const videoOnly = ({ attributes }) =>
attributes.mimeType === 'video/mp4' || attributes.mimeType === 'video/webm' || attributes.contentType === 'video';
const audioOnly = ({ attributes }) =>
attributes.mimeType === 'audio/mp4' || attributes.mimeType === 'audio/webm' || attributes.contentType === 'audio';
const vttOnly = ({ attributes }) =>
attributes.mimeType === 'text/vtt' || attributes.contentType === 'text';

export const toM3u8 = (dashPlaylists, locations, sidxMapping = {}) => {
if (!dashPlaylists.length) {
return {};
Expand All @@ -250,13 +248,6 @@ export const toM3u8 = (dashPlaylists, locations, sidxMapping = {}) => {
minimumUpdatePeriod
} = dashPlaylists[0].attributes;

const videoOnly = ({ attributes }) =>
attributes.mimeType === 'video/mp4' || attributes.mimeType === 'video/webm' || attributes.contentType === 'video';
const audioOnly = ({ attributes }) =>
attributes.mimeType === 'audio/mp4' || attributes.mimeType === 'audio/webm' || attributes.contentType === 'audio';
const vttOnly = ({ attributes }) =>
attributes.mimeType === 'text/vtt' || attributes.contentType === 'text';

const videoPlaylists = mergeDiscontiguousPlaylists(dashPlaylists.filter(videoOnly)).map(formatVideoPlaylist);
const audioPlaylists = mergeDiscontiguousPlaylists(dashPlaylists.filter(audioOnly));
const vttPlaylists = dashPlaylists.filter(vttOnly);
Expand All @@ -274,7 +265,7 @@ export const toM3u8 = (dashPlaylists, locations, sidxMapping = {}) => {
},
uri: '',
duration,
playlists: addSegmentInfoFromSidx(videoPlaylists, sidxMapping)
playlists: addSidxSegmentsToPlaylists(videoPlaylists, sidxMapping)
};

if (minimumUpdatePeriod >= 0) {
Expand Down
6 changes: 3 additions & 3 deletions test/segment/segmentBase.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import QUnit from 'qunit';
import {
segmentsFromBase,
addSegmentsToPlaylist
addSidxSegmentsToPlaylist
} from '../../src/segment/segmentBase';
import errors from '../../src/errors';

Expand Down Expand Up @@ -151,7 +151,7 @@ QUnit.test('errors if no baseUrl exists', function(assert) {
assert.throws(() => segmentsFromBase({}), new Error(errors.NO_BASE_URL));
});

QUnit.module('segmentBase - addSegmentsToPlaylist');
QUnit.module('segmentBase - addSidxSegmentsToPlaylist');

QUnit.test('generates playlist from sidx references', function(assert) {
const baseUrl = 'http://www.example.com/i.fmp4';
Expand Down Expand Up @@ -181,7 +181,7 @@ QUnit.test('generates playlist from sidx references', function(assert) {
}]
};

assert.deepEqual(addSegmentsToPlaylist(playlist, sidx, baseUrl).segments, [{
assert.deepEqual(addSidxSegmentsToPlaylist(playlist, sidx, baseUrl).segments, [{
map: {
byterange: {
offset: 0,
Expand Down
21 changes: 20 additions & 1 deletion test/toM3u8.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { toM3u8 } from '../src/toM3u8';
import { toM3u8, generateSidxKey } from '../src/toM3u8';
import QUnit from 'qunit';

QUnit.module('toM3u8');
Expand Down Expand Up @@ -701,3 +701,22 @@ QUnit.test('dynamic playlists with suggestedPresentationDelay', function(assert)
assert.ok('suggestedPresentationDelay' in output);
assert.deepEqual(output.suggestedPresentationDelay, 18);
});

QUnit.module('generateSidxKey');

QUnit.test('generates correct key', function(assert) {
const sidxInfo = {
byterange: {
offset: 1,
length: 5
},
uri: 'uri'
};

assert.strictEqual(
generateSidxKey(sidxInfo),
'uri-1-5',
'the key byterange should have a inclusive end'
);
});

0 comments on commit 85d24be

Please sign in to comment.