Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add external vhs properties and deprecate hls and dash references #859

Merged
merged 14 commits into from
Jun 15, 2020
Merged
123 changes: 62 additions & 61 deletions README.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/bitrate-switching.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,4 @@ If you'd like your player to use a different set of priorities, it's
possible to completely replace the rendition selection logic. For
instance, you could always choose the most appropriate rendition by
resolution, even though this might mean more stalls during playback.
See the documentation on `player.hls.selectPlaylist` for more details.
See the documentation on `player.vhs.selectPlaylist` for more details.
6 changes: 3 additions & 3 deletions scripts/index-demo-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,8 @@
saveState();

window.videojs.options = window.videojs.options || {};
window.videojs.options.hls = window.videojs.options.hls || {};
window.videojs.options.hls.handlePartialData = event.target.checked;
window.videojs.options.vhs = window.videojs.options.vhs || {};
window.videojs.options.vhs.handlePartialData = event.target.checked;

if (window.player) {
window.player.src(window.player.currentSource());
Expand Down Expand Up @@ -255,7 +255,7 @@
},
liveui: stateEls.liveui.checked,
html5: {
hls: {
vhs: {
overrideNative: true
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/dash-playlist-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,12 @@ export default class DashPlaylistLoader extends EventTarget {
// DashPlaylistLoader must accept either a src url or a playlist because subsequent
// playlist loader setups from media groups will expect to be able to pass a playlist
// (since there aren't external URLs to media playlists with DASH)
constructor(srcUrlOrPlaylist, hls, options = { }, masterPlaylistLoader) {
constructor(srcUrlOrPlaylist, vhs, options = { }, masterPlaylistLoader) {
super();

const { withCredentials = false, handleManifestRedirects = false } = options;

this.hls_ = hls;
this.vhs_ = vhs;
this.withCredentials = withCredentials;
this.handleManifestRedirects = handleManifestRedirects;

Expand Down Expand Up @@ -435,7 +435,7 @@ export default class DashPlaylistLoader extends EventTarget {
this,
playlist.sidx,
playlist,
this.hls_.xhr,
this.vhs_.xhr,
{ handleManifestRedirects: this.handleManifestRedirects },
this.sidxRequestFinished_(playlist, oldMaster, startingState, (newMaster, sidx) => {
if (!newMaster || !sidx) {
Expand Down Expand Up @@ -524,7 +524,7 @@ export default class DashPlaylistLoader extends EventTarget {
}

// request the specified URL
this.request = this.hls_.xhr({
this.request = this.vhs_.xhr({
uri: this.srcUrl,
withCredentials: this.withCredentials
}, (error, req) => {
Expand Down Expand Up @@ -586,7 +586,7 @@ export default class DashPlaylistLoader extends EventTarget {
return done();
}

this.request = this.hls_.xhr({
this.request = this.vhs_.xhr({
uri: resolveUrl(this.srcUrl, utcTiming.value),
method: utcTiming.method,
withCredentials: this.withCredentials
Expand Down Expand Up @@ -677,7 +677,7 @@ export default class DashPlaylistLoader extends EventTarget {
refreshXml_() {
// The srcUrl here *may* need to pass through handleManifestsRedirects when
// sidx is implemented
this.request = this.hls_.xhr({
this.request = this.vhs_.xhr({
uri: this.srcUrl,
withCredentials: this.withCredentials
}, (error, req) => {
Expand Down Expand Up @@ -734,7 +734,7 @@ export default class DashPlaylistLoader extends EventTarget {
this,
playlist.sidx,
playlist,
this.hls_.xhr,
this.vhs_.xhr,
{ handleManifestRedirects: this.handleManifestRedirects },
this.sidxRequestFinished_(playlist, master, this.state, (newMaster, sidx) => {
if (!newMaster || !sidx) {
Expand Down
39 changes: 25 additions & 14 deletions src/master-playlist-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import logger from './util/logger';

const ABORT_EARLY_BLACKLIST_SECONDS = 60 * 2;

let Hls;
let Vhs;

// SegmentLoader stats that need to have each loader's
// values summed to calculate the final value
Expand Down Expand Up @@ -105,7 +105,7 @@ export class MasterPlaylistController extends videojs.EventTarget {
withCredentials,
tech,
bandwidth,
externHls,
externVhs,
useCueTags,
blacklistDuration,
enableLowInitialPlaylist,
Expand All @@ -118,11 +118,11 @@ export class MasterPlaylistController extends videojs.EventTarget {
throw new Error('A non-empty playlist URL or JSON manifest string is required');
}

Hls = externHls;
Vhs = externVhs;

this.withCredentials = withCredentials;
this.tech_ = tech;
this.hls_ = tech.hls;
this.vhs_ = tech.vhs;
this.sourceType_ = sourceType;
this.useCueTags_ = useCueTags;
this.blacklistDuration = blacklistDuration;
Expand Down Expand Up @@ -171,7 +171,7 @@ export class MasterPlaylistController extends videojs.EventTarget {
this.timelineChangeController_ = new TimelineChangeController();

const segmentLoaderSettings = {
hls: this.hls_,
vhs: this.vhs_,
mediaSource: this.mediaSource,
currentTime: this.tech_.currentTime.bind(this.tech_),
seekable: () => this.seekable(),
Expand All @@ -195,8 +195,8 @@ export class MasterPlaylistController extends videojs.EventTarget {
// manifest object (instead of a URL). In the case of vhs-json, the default
// PlaylistLoader should be used.
this.masterPlaylistLoader_ = this.sourceType_ === 'dash' ?
new DashPlaylistLoader(src, this.hls_, this.requestOptions_) :
new PlaylistLoader(src, this.hls_, this.requestOptions_);
new DashPlaylistLoader(src, this.vhs_, this.requestOptions_) :
new PlaylistLoader(src, this.vhs_, this.requestOptions_);
this.setupMasterPlaylistLoaderListeners_();

// setup segment loaders
Expand Down Expand Up @@ -274,7 +274,7 @@ export class MasterPlaylistController extends videojs.EventTarget {
tech: this.tech_,
requestOptions: this.requestOptions_,
masterPlaylistLoader: this.masterPlaylistLoader_,
hls: this.hls_,
vhs: this.vhs_,
master: this.master(),
mediaTypes: this.mediaTypes_,
blacklistCurrentPlaylist: this.blacklistCurrentPlaylist.bind(this)
Expand Down Expand Up @@ -384,9 +384,11 @@ export class MasterPlaylistController extends videojs.EventTarget {
});

this.masterPlaylistLoader_.on('renditiondisabled', () => {
this.tech_.trigger({type: 'usage', name: 'vhs-rendition-disabled'});
this.tech_.trigger({type: 'usage', name: 'hls-rendition-disabled'});
});
this.masterPlaylistLoader_.on('renditionenabled', () => {
this.tech_.trigger({type: 'usage', name: 'vhs-rendition-enabled'});
this.tech_.trigger({type: 'usage', name: 'hls-rendition-enabled'});
});
}
Expand Down Expand Up @@ -444,23 +446,28 @@ export class MasterPlaylistController extends videojs.EventTarget {
}

if (defaultDemuxed) {
this.tech_.trigger({type: 'usage', name: 'vhs-demuxed'});
this.tech_.trigger({type: 'usage', name: 'hls-demuxed'});
}

if (Object.keys(mediaGroups.SUBTITLES).length) {
this.tech_.trigger({type: 'usage', name: 'vhs-webvtt'});
this.tech_.trigger({type: 'usage', name: 'hls-webvtt'});
}

if (Hls.Playlist.isAes(media)) {
if (Vhs.Playlist.isAes(media)) {
this.tech_.trigger({type: 'usage', name: 'vhs-aes'});
this.tech_.trigger({type: 'usage', name: 'hls-aes'});
}

if (audioGroupKeys.length &&
Object.keys(mediaGroups.AUDIO[audioGroupKeys[0]]).length > 1) {
this.tech_.trigger({type: 'usage', name: 'vhs-alternate-audio'});
this.tech_.trigger({type: 'usage', name: 'hls-alternate-audio'});
}

if (this.useCueTags_) {
this.tech_.trigger({type: 'usage', name: 'vhs-playlist-cue-tags'});
this.tech_.trigger({type: 'usage', name: 'hls-playlist-cue-tags'});
}
}
Expand Down Expand Up @@ -511,6 +518,7 @@ export class MasterPlaylistController extends videojs.EventTarget {
});

this.mainSegmentLoader_.on('timestampoffset', () => {
this.tech_.trigger({type: 'usage', name: 'vhs-timestamp-offset'});
this.tech_.trigger({type: 'usage', name: 'hls-timestamp-offset'});
});
this.audioSegmentLoader_.on('syncinfoupdate', () => {
Expand Down Expand Up @@ -540,13 +548,15 @@ export class MasterPlaylistController extends videojs.EventTarget {

this.mainSegmentLoader_.on('fmp4', () => {
if (!this.triggeredFmp4Usage) {
this.tech_.trigger({type: 'usage', name: 'vhs-fmp4'});
this.tech_.trigger({type: 'usage', name: 'hls-fmp4'});
this.triggeredFmp4Usage = true;
}
});

this.audioSegmentLoader_.on('fmp4', () => {
if (!this.triggeredFmp4Usage) {
this.tech_.trigger({type: 'usage', name: 'vhs-fmp4'});
this.tech_.trigger({type: 'usage', name: 'hls-fmp4'});
this.triggeredFmp4Usage = true;
}
Expand Down Expand Up @@ -826,7 +836,7 @@ export class MasterPlaylistController extends videojs.EventTarget {

// does not use the safe live end to calculate playlist end, since we
// don't want to say we are stuck while there is still content
const absolutePlaylistEnd = Hls.Playlist.playlistEnd(playlist, expired);
const absolutePlaylistEnd = Vhs.Playlist.playlistEnd(playlist, expired);
const currentTime = this.tech_.currentTime();
const buffered = this.tech_.buffered();

Expand Down Expand Up @@ -925,6 +935,7 @@ export class MasterPlaylistController extends videojs.EventTarget {
// Blacklist this playlist
currentPlaylist.excludeUntil = Date.now() + (blacklistDuration * 1000);
this.tech_.trigger('blacklistplaylist');
this.tech_.trigger({type: 'usage', name: 'vhs-rendition-blacklisted'});
this.tech_.trigger({type: 'usage', name: 'hls-rendition-blacklisted'});

// Select a new playlist
Expand Down Expand Up @@ -1046,7 +1057,7 @@ export class MasterPlaylistController extends videojs.EventTarget {
return this.mediaSource.duration;
}

return Hls.Playlist.duration(media);
return Vhs.Playlist.duration(media);
}

/**
Expand Down Expand Up @@ -1079,7 +1090,7 @@ export class MasterPlaylistController extends videojs.EventTarget {
}

const suggestedPresentationDelay = this.masterPlaylistLoader_.master.suggestedPresentationDelay;
const mainSeekable = Hls.Playlist.seekable(media, expired, suggestedPresentationDelay);
const mainSeekable = Vhs.Playlist.seekable(media, expired, suggestedPresentationDelay);

if (mainSeekable.length === 0) {
return;
Expand All @@ -1093,7 +1104,7 @@ export class MasterPlaylistController extends videojs.EventTarget {
return;
}

audioSeekable = Hls.Playlist.seekable(media, expired, suggestedPresentationDelay);
audioSeekable = Vhs.Playlist.seekable(media, expired, suggestedPresentationDelay);

if (audioSeekable.length === 0) {
return;
Expand Down Expand Up @@ -1184,7 +1195,7 @@ export class MasterPlaylistController extends videojs.EventTarget {
}

const buffered = this.tech_.buffered();
let duration = Hls.Playlist.duration(this.masterPlaylistLoader_.media());
let duration = Vhs.Playlist.duration(this.masterPlaylistLoader_.media());

if (buffered.length > 0) {
duration = Math.max(duration, buffered.end(buffered.length - 1));
Expand Down
25 changes: 13 additions & 12 deletions src/media-groups.js
Original file line number Diff line number Diff line change
Expand Up @@ -360,7 +360,7 @@ export const initialize = {
*/
'AUDIO': (type, settings) => {
const {
hls,
vhs,
sourceType,
segmentLoaders: { [type]: segmentLoader },
requestOptions,
Expand Down Expand Up @@ -397,19 +397,19 @@ export const initialize = {
if (sourceType === 'vhs-json' && properties.playlists) {
playlistLoader = new PlaylistLoader(
properties.playlists[0],
hls,
vhs,
requestOptions
);
} else if (properties.resolvedUri) {
playlistLoader = new PlaylistLoader(
properties.resolvedUri,
hls,
vhs,
requestOptions
);
} else if (properties.playlists && sourceType === 'dash') {
playlistLoader = new DashPlaylistLoader(
properties.playlists[0],
hls,
vhs,
requestOptions,
masterPlaylistLoader
);
Expand Down Expand Up @@ -458,7 +458,7 @@ export const initialize = {
'SUBTITLES': (type, settings) => {
const {
tech,
hls,
vhs,
sourceType,
segmentLoaders: { [type]: segmentLoader },
requestOptions,
Expand Down Expand Up @@ -496,11 +496,11 @@ export const initialize = {

if (sourceType === 'hls') {
playlistLoader =
new PlaylistLoader(properties.resolvedUri, hls, requestOptions);
new PlaylistLoader(properties.resolvedUri, vhs, requestOptions);
} else if (sourceType === 'dash') {
playlistLoader = new DashPlaylistLoader(
properties.playlists[0],
hls,
vhs,
requestOptions,
masterPlaylistLoader
);
Expand All @@ -509,7 +509,7 @@ export const initialize = {
// if the vhs-json object included the media playlist, use the media playlist
// as provided, otherwise use the resolved URI to load the playlist
properties.playlists ? properties.playlists[0] : properties.resolvedUri,
hls,
vhs,
requestOptions
);
}
Expand Down Expand Up @@ -703,8 +703,8 @@ export const activeTrack = {
* XHR request options used by the segment loaders
* @param {PlaylistLoader} settings.masterPlaylistLoader
* PlaylistLoader for the master source
* @param {HlsHandler} settings.hls
* HLS SourceHandler
* @param {VhsHandler} settings.vhs
* VHS SourceHandler
* @param {Object} settings.master
* The parsed master manifest
* @param {Object} settings.mediaTypes
Expand All @@ -722,7 +722,7 @@ export const setupMediaGroups = (settings) => {
mediaTypes,
masterPlaylistLoader,
tech,
hls
vhs
} = settings;

// setup active group and track getters and change event handlers
Expand All @@ -748,6 +748,7 @@ export const setupMediaGroups = (settings) => {
// custom audio track change event handler for usage event
const onAudioTrackChanged = () => {
mediaTypes.AUDIO.onTrackChanged();
tech.trigger({ type: 'usage', name: 'vhs-audio-change' });
tech.trigger({ type: 'usage', name: 'hls-audio-change' });
};

Expand All @@ -757,7 +758,7 @@ export const setupMediaGroups = (settings) => {
mediaTypes.SUBTITLES.onTrackChanged
);

hls.on('dispose', () => {
vhs.on('dispose', () => {
tech.audioTracks().removeEventListener('change', onAudioTrackChanged);
tech.remoteTextTracks().removeEventListener(
'change',
Expand Down
4 changes: 4 additions & 0 deletions src/playback-watcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ export default class PlaybackWatcher {
'playback by seeking to the current time.');

// unknown waiting corrections may be useful for monitoring QoS
this.tech_.trigger({type: 'usage', name: 'vhs-unknown-waiting'});
this.tech_.trigger({type: 'usage', name: 'hls-unknown-waiting'});
return;
}
Expand Down Expand Up @@ -435,6 +436,7 @@ export default class PlaybackWatcher {
this.tech_.setCurrentTime(livePoint);

// live window resyncs may be useful for monitoring QoS
this.tech_.trigger({type: 'usage', name: 'vhs-live-resync'});
this.tech_.trigger({type: 'usage', name: 'hls-live-resync'});
return true;
}
Expand All @@ -451,6 +453,7 @@ export default class PlaybackWatcher {
this.tech_.setCurrentTime(currentTime);

// video underflow may be useful for monitoring QoS
this.tech_.trigger({type: 'usage', name: 'vhs-video-underflow'});
this.tech_.trigger({type: 'usage', name: 'hls-video-underflow'});
return true;
}
Expand Down Expand Up @@ -552,6 +555,7 @@ export default class PlaybackWatcher {
// only seek if we still have not played
this.tech_.setCurrentTime(nextRange.start(0) + Ranges.TIME_FUDGE_FACTOR);

this.tech_.trigger({type: 'usage', name: 'vhs-gap-skip'});
this.tech_.trigger({type: 'usage', name: 'hls-gap-skip'});
}

Expand Down
Loading