Skip to content

Commit

Permalink
Merge branch 'main' into feat-ie
Browse files Browse the repository at this point in the history
  • Loading branch information
misteroneill authored Feb 23, 2023
2 parents 0cbe68f + 343f682 commit 9fb1bef
Show file tree
Hide file tree
Showing 14 changed files with 492 additions and 112 deletions.
73 changes: 73 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,76 @@
<a name="3.0.1"></a>
## [3.0.1](https://github.com/videojs/http-streaming/compare/v3.0.0...v3.0.1) (2023-01-24)

### Bug Fixes

* Linear DASH multiperiod label issue ([#1352](https://github.com/videojs/http-streaming/issues/1352)) ([d7e8713](https://github.com/videojs/http-streaming/commit/d7e8713))
* In-manifest VTT iOS MSE issue ([#1360](https://github.com/videojs/http-streaming/issues/1360)) ([6ba70e0](https://github.com/videojs/http-streaming/commit/6ba70e0))

<a name="3.0.0"></a>
# [3.0.0](https://github.com/videojs/http-streaming/compare/v2.14.2...v3.0.0) (2022-11-21)

### Features

* add compatibility layer for video.js 7 and 8 ([#1322](https://github.com/videojs/http-streaming/issues/1322)) ([b9d26e5](https://github.com/videojs/http-streaming/commit/b9d26e5))
* add frameRate property to the representation class. ([#1289](https://github.com/videojs/http-streaming/issues/1289)) ([fd2898f](https://github.com/videojs/http-streaming/commit/fd2898f))
* enable LLHLS support by default and remove experimental prefix on options ([#1301](https://github.com/videojs/http-streaming/issues/1301)) ([02c3c77](https://github.com/videojs/http-streaming/commit/02c3c77))
* remove handleManifestRedirects and always use XHR.responseURL if available ([#1226](https://github.com/videojs/http-streaming/issues/1226)) ([3ad3120](https://github.com/videojs/http-streaming/commit/3ad3120))
* rename many things to `main` ([#1309](https://github.com/videojs/http-streaming/issues/1309)) ([54cbab3](https://github.com/videojs/http-streaming/commit/54cbab3))
* Skip gaps immediately ([#1267](https://github.com/videojs/http-streaming/issues/1267)) ([f85c153](https://github.com/videojs/http-streaming/commit/f85c153))
* update tooling to remove ie 11 transpiling, update tests ([#1306](https://github.com/videojs/http-streaming/issues/1306)) ([206f099](https://github.com/videojs/http-streaming/commit/206f099))

### Bug Fixes

* add Video.js 8 to the dep version range ([#1307](https://github.com/videojs/http-streaming/issues/1307)) ([325a98e](https://github.com/videojs/http-streaming/commit/325a98e))
* cache aes keys for text tracks ([#973](https://github.com/videojs/http-streaming/issues/973)) ([#1228](https://github.com/videojs/http-streaming/issues/1228)) ([66a5b17](https://github.com/videojs/http-streaming/commit/66a5b17))
* output-restricted event handling for unplayable streams ([#1305](https://github.com/videojs/http-streaming/issues/1305)) ([1c62a98](https://github.com/videojs/http-streaming/commit/1c62a98))
* remove deprecation hls options, properties, and events; add migration guide ([#1229](https://github.com/videojs/http-streaming/issues/1229)) ([43fce26](https://github.com/videojs/http-streaming/commit/43fce26))
* Restart mainPlaylistLoader after media change ([#1339](https://github.com/videojs/http-streaming/issues/1339)) ([cf340f2](https://github.com/videojs/http-streaming/commit/cf340f2))
* resume loading on segment timeout for `bufferBasedABR` ([#1333](https://github.com/videojs/http-streaming/issues/1333)) ([969589e](https://github.com/videojs/http-streaming/commit/969589e))

### Chores

* **docs:** Remove outdated information in collaborators' guide ([#1271](https://github.com/videojs/http-streaming/issues/1271)) ([6100750](https://github.com/videojs/http-streaming/commit/6100750))
* **package:** update dependencies to use new ES6 builds ([#1320](https://github.com/videojs/http-streaming/issues/1320)) ([9ae6695](https://github.com/videojs/http-streaming/commit/9ae6695))
* **package:** update m3u8-parser to v6.0.0 ([#1330](https://github.com/videojs/http-streaming/issues/1330)) ([fe15751](https://github.com/videojs/http-streaming/commit/fe15751))
* remove old-index since IE is no longer supported ([#1308](https://github.com/videojs/http-streaming/issues/1308)) ([5ba3a77](https://github.com/videojs/http-streaming/commit/5ba3a77))
* update karma-config to 8 to drop ie11 and older browsers ([#1227](https://github.com/videojs/http-streaming/issues/1227)) ([44c12ea](https://github.com/videojs/http-streaming/commit/44c12ea))
* update mpd-parser ([#1337](https://github.com/videojs/http-streaming/issues/1337)) ([7ff95b9](https://github.com/videojs/http-streaming/commit/7ff95b9))
* update package-lock ([1806b46](https://github.com/videojs/http-streaming/commit/1806b46))
* update package-lock.json ([#1319](https://github.com/videojs/http-streaming/issues/1319)) ([c7aa9c1](https://github.com/videojs/http-streaming/commit/c7aa9c1))

### Code Refactoring

* clean up parameters of excludePlaylist ([#1304](https://github.com/videojs/http-streaming/issues/1304)) ([ca3162b](https://github.com/videojs/http-streaming/commit/ca3162b))
* Remove deprecated smooth quality change ([#1268](https://github.com/videojs/http-streaming/issues/1268)) ([6041014](https://github.com/videojs/http-streaming/commit/6041014))
* rename 'blacklist' to 'exclude' ([#1274](https://github.com/videojs/http-streaming/issues/1274)) ([d79d783](https://github.com/videojs/http-streaming/commit/d79d783))

### Tests

* change source for live DASH playback test to fix test failures ([#1303](https://github.com/videojs/http-streaming/issues/1303)) ([128b3d7](https://github.com/videojs/http-streaming/commit/128b3d7))
* fix IE11 encrypted VTT tests by using an actual encrypted VTT segment ([#1291](https://github.com/videojs/http-streaming/issues/1291)) ([57c0e72](https://github.com/videojs/http-streaming/commit/57c0e72))


### BREAKING CHANGES

* **package:** manifests with tags lacking colons (:) are no longer supported
* **package:** This updates bundled libraries to no longer be transpiled to ES5, which means IE will no longer be supported.
* This changes the arguments for the `PlaylistController#excludePlaylist` method to take a single object instead of multiple arguments.
* This renames four experimental options to no longer be experimental and enables Low Latency HLS support by default (`llhls: false` will still disable it, if desired).
* rename PlaylistController
* rename HAVE_MASTER to HAVE_MAIN_MANIFEST
* playlist loaders updateMain and .main prop rename
* manifest.js exports mainForMedia and addPropertiesToMain
* rename media groups prop to isMainPlaylist
* rename property to mainPlaylistLoader_
* rename to PlaylistController#main()
* This removes support entirely for IE11 (and older) as well as any other platforms that do not support ES6.
* remove ^6 from the dependency version ranges.
* Skips detected gaps immediately instead of waiting the duration of the gap before skipping
* Removes deprecated `smoothQualityChange` option
* remove deprecated options, properties, events.
* remove handleManifestRedirects option. Now XHR.responseURL will always be used when available.

<a name="3.0.0-2"></a>
# [3.0.0-2](https://github.com/videojs/http-streaming/compare/v3.0.0-1...v3.0.0-2) (2022-09-30)

Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@videojs/http-streaming",
"version": "3.0.0-2",
"version": "3.0.1",
"description": "Play back HLS and DASH with Video.js, even where it's not natively supported",
"main": "dist/videojs-http-streaming.cjs.js",
"module": "dist/videojs-http-streaming.es.js",
Expand Down
41 changes: 40 additions & 1 deletion src/dash-playlist-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,19 @@ const dashPlaylistUnchanged = function(a, b) {
return true;
};

/**
* Use the representation IDs from the mpd object to create groupIDs, the NAME is set to mandatory representation
* ID in the parser. This allows for continuous playout across periods with the same representation IDs
* (continuous periods as defined in DASH-IF 3.2.12). This is assumed in the mpd-parser as well. If we want to support
* periods without continuous playback this function may need modification as well as the parser.
*/
const dashGroupId = (type, group, label, playlist) => {
// If the manifest somehow does not have an ID (non-dash compliant), use the label.
const playlistId = playlist.attributes.NAME || label;

return `placeholder-uri-${type}-${group}-${playlistId}`;
};

/**
* Parses the main XML string and updates playlist URI references.
*
Expand Down Expand Up @@ -116,11 +129,27 @@ export const parseMainXml = ({
previousManifest
});

addPropertiesToMain(manifest, srcUrl);
addPropertiesToMain(manifest, srcUrl, dashGroupId);

return manifest;
};

/**
* Removes any mediaGroup labels that no longer exist in the newMain
*
* @param {Object} update
* The previous mpd object being updated
* @param {Object} newMain
* The new mpd object
*/
const removeOldMediaGroupLabels = (update, newMain) => {
forEachMediaGroup(update, (properties, type, group, label) => {
if (!(label in newMain.mediaGroups[type][group])) {
delete update.mediaGroups[type][group][label];
}
});
};

/**
* Returns a new main manifest that is the result of merging an updated main manifest
* into the original version.
Expand Down Expand Up @@ -170,13 +199,23 @@ export const updateMain = (oldMain, newMain, sidxMapping) => {

if (playlistUpdate) {
update = playlistUpdate;

// add new mediaGroup label if it doesn't exist and assign the new mediaGroup.
if (!(label in update.mediaGroups[type][group])) {
update.mediaGroups[type][group][label] = properties;
}

// update the playlist reference within media groups
update.mediaGroups[type][group][label].playlists[0] = update.playlists[id];

noChanges = false;
}
}
});

// remove mediaGroup labels and references that no longer exist in the newMain
removeOldMediaGroupLabels(update, newMain);

if (newMain.minimumUpdatePeriod !== oldMain.minimumUpdatePeriod) {
noChanges = false;
}
Expand Down
12 changes: 9 additions & 3 deletions src/manifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ export const createPlaylistID = (index, uri) => {
return `${index}-${uri}`;
};

// default function for creating a group id
const groupID = (type, group, label) => {
return `placeholder-uri-${type}-${group}-${label}`;
};

/**
* Parses a given m3u8 playlist
*
Expand Down Expand Up @@ -265,8 +270,10 @@ export const mainForMedia = (media, uri) => {
* main manifest object
* @param {string} uri
* The source URI
* @param {function} createGroupID
* A function to determine how to create the groupID for mediaGroups
*/
export const addPropertiesToMain = (main, uri) => {
export const addPropertiesToMain = (main, uri, createGroupID = groupID) => {
main.uri = uri;

for (let i = 0; i < main.playlists.length; i++) {
Expand All @@ -282,8 +289,6 @@ export const addPropertiesToMain = (main, uri) => {
const audioOnlyMain = isAudioOnly(main);

forEachMediaGroup(main, (properties, mediaType, groupKey, labelKey) => {
const groupId = `placeholder-uri-${mediaType}-${groupKey}-${labelKey}`;

// add a playlist array under properties
if (!properties.playlists || !properties.playlists.length) {
// If the manifest is audio only and this media group does not have a uri, check
Expand All @@ -303,6 +308,7 @@ export const addPropertiesToMain = (main, uri) => {
}

properties.playlists.forEach(function(p, i) {
const groupId = createGroupID(mediaType, groupKey, labelKey, p);
const id = createPlaylistID(i, groupId);

if (p.uri) {
Expand Down
54 changes: 41 additions & 13 deletions src/playlist-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,24 @@ export class PlaylistController extends videojs.EventTarget {
this.subtitleSegmentLoader_ =
new VTTSegmentLoader(merge(segmentLoaderSettings, {
loaderType: 'vtt',
featuresNativeTextTracks: this.tech_.featuresNativeTextTracks
featuresNativeTextTracks: this.tech_.featuresNativeTextTracks,
loadVttJs: () => new Promise((resolve, reject) => {
function onLoad() {
tech.off('vttjserror', onError);
resolve();
}

function onError() {
tech.off('vttjsloaded', onLoad);
reject();
}

tech.one('vttjsloaded', onLoad);
tech.one('vttjserror', onError);

// safe to call multiple times, script will be loaded only once:
tech.addWebVttScript_();
})
}), options);

this.setupSegmentLoaderListeners_();
Expand Down Expand Up @@ -364,14 +381,14 @@ export class PlaylistController extends videojs.EventTarget {
/**
* Run selectPlaylist and switch to the new playlist if we should
*
* @param {string} [reason=abr] a reason for why the ABR check is made
* @private
*
*/
checkABR_() {
checkABR_(reason = 'abr') {
const nextPlaylist = this.selectPlaylist();

if (nextPlaylist && this.shouldSwitchToMedia_(nextPlaylist)) {
this.switchMedia_(nextPlaylist, 'abr');
this.switchMedia_(nextPlaylist, reason);
}
}

Expand Down Expand Up @@ -615,6 +632,8 @@ export class PlaylistController extends videojs.EventTarget {
this.requestOptions_.timeout = requestTimeout;
}

this.mainPlaylistLoader_.load();

// TODO: Create a new event on the PlaylistLoader that signals
// that the segments have changed in some way and use that to
// update the SegmentLoader instead of doing it twice here and
Expand Down Expand Up @@ -766,17 +785,26 @@ export class PlaylistController extends videojs.EventTarget {
* @private
*/
setupSegmentLoaderListeners_() {
if (!this.bufferBasedABR) {
this.mainSegmentLoader_.on('bandwidthupdate', () => {
const nextPlaylist = this.selectPlaylist();

if (this.shouldSwitchToMedia_(nextPlaylist)) {
this.switchMedia_(nextPlaylist, 'bandwidthupdate');
}
this.mainSegmentLoader_.on('bandwidthupdate', () => {
// Whether or not buffer based ABR or another ABR is used, on a bandwidth change it's
// useful to check to see if a rendition switch should be made.
this.checkABR_('bandwidthupdate');
this.tech_.trigger('bandwidthupdate');
});

this.tech_.trigger('bandwidthupdate');
});
this.mainSegmentLoader_.on('timeout', () => {
if (this.bufferBasedABR) {
// If a rendition change is needed, then it would've be done on `bandwidthupdate`.
// Here the only consideration is that for buffer based ABR there's no guarantee
// of an immediate switch (since the bandwidth is averaged with a timeout
// bandwidth value of 1), so force a load on the segment loader to keep it going.
this.mainSegmentLoader_.load();
}
});

// `progress` events are not reliable enough of a bandwidth measure to trigger buffer
// based ABR.
if (!this.bufferBasedABR) {
this.mainSegmentLoader_.on('progress', () => {
this.trigger('progress');
});
Expand Down
1 change: 1 addition & 0 deletions src/segment-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -2635,6 +2635,7 @@ export default class SegmentLoader extends videojs.EventTarget {
this.bandwidth = 1;
this.roundTrip = NaN;
this.trigger('bandwidthupdate');
this.trigger('timeout');
}

/**
Expand Down
23 changes: 16 additions & 7 deletions src/videojs-http-streaming.js
Original file line number Diff line number Diff line change
Expand Up @@ -1221,16 +1221,25 @@ const VhsSourceHandler = {
tech.vhs.src(source.src, source.type);
return tech.vhs;
},
canPlayType(type, options = {}) {
const {
vhs: { overrideNative = !videojs.browser.IS_ANY_SAFARI } = {}
} = merge(videojs.options, options);
canPlayType(type, options) {
const simpleType = simpleTypeFromSourceType(type);

const supportedType = simpleTypeFromSourceType(type);
const canUseMsePlayback = supportedType &&
(!Vhs.supportsTypeNatively(supportedType) || overrideNative);
if (!simpleType) {
return '';
}

const overrideNative = VhsSourceHandler.getOverrideNative(options);
const supportsTypeNatively = Vhs.supportsTypeNatively(simpleType);
const canUseMsePlayback = !supportsTypeNatively || overrideNative;

return canUseMsePlayback ? 'maybe' : '';
},
getOverrideNative(options = {}) {
const { vhs = {} } = options;
const defaultOverrideNative = !(videojs.browser.IS_ANY_SAFARI || videojs.browser.IS_IOS);
const { overrideNative = defaultOverrideNative } = vhs;

return overrideNative;
}
};

Expand Down
Loading

0 comments on commit 9fb1bef

Please sign in to comment.