Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion demo/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,8 @@ shakaDemo.Config = class {
.addTextInput_('Preferred Audio Language', 'preferredAudioLanguage')
.addTextInput_('Preferred Audio Label', 'preferredAudioLabel')
.addTextInput_('Preferred Video Label', 'preferredVideoLabel')
.addTextInput_('Preferred Variant Role', 'preferredVariantRole')
.addTextInput_('Preferred Audio Role', 'preferredAudioRole')
.addTextInput_('Preferred Video Role', 'preferredVideoRole')
.addTextInput_('Preferred Text Language', 'preferredTextLanguage')
.addTextInput_('Preferred Text Role', 'preferredTextRole')
.addSelectInput_('Auto-Show Text',
Expand Down
1 change: 1 addition & 0 deletions docs/tutorials/upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ application:
- `streaming.forceHTTPS` has been renamed to `networking.forceHTTPS` (deprecated in v4.15.0)
- `streaming.minBytesForProgressEvents` has been renamed to `networking.minBytesForProgressEvents` (deprecated in v4.15.0)
- `manifest.dash.enableAudioGroups` has been renamed to `manifest.enableAudioGroups`
- `preferredVariantRole` has been renamed to `preferredAudioRole` (deprecated in v4.16.0)

- Plugin changes:
- `TextDisplayer` plugins must implement the `configure()` method.
Expand Down
28 changes: 24 additions & 4 deletions externs/shaka/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ shaka.extern.BufferedInfo;
*
* language: string,
* label: ?string,
* videoLabel: ?string,
* kind: ?string,
* width: ?number,
* height: ?number,
Expand All @@ -269,6 +270,7 @@ shaka.extern.BufferedInfo;
* primary: boolean,
* roles: !Array<string>,
* audioRoles: Array<string>,
* videoRoles: Array<string>,
* accessibilityPurpose: ?shaka.media.ManifestParser.AccessibilityPurpose,
* forced: boolean,
* videoId: ?number,
Expand Down Expand Up @@ -311,6 +313,9 @@ shaka.extern.BufferedInfo;
* i.e. <code>'en-US'</code>.
* @property {?string} label
* The track label, which is unique text that should describe the track.
* @property {?string} videoLabel
* The video track label, which is unique text that should describe the video
* track.
* @property {?string} kind
* (only for text tracks) The kind of text track, either
* <code>'caption'</code> or <code>'subtitle'</code>.
Expand Down Expand Up @@ -353,6 +358,10 @@ shaka.extern.BufferedInfo;
* The roles of the audio in the track, e.g. <code>'main'</code> or
* <code>'commentary'</code>. Will be null for text tracks or variant tracks
* without audio.
* @property {Array<string>} videoRoles
* The roles of the video in the track, e.g. <code>'main'</code> or
* <code>'sign'</code>. Will be null for text tracks or variant tracks
* without video.
* @property {?shaka.media.ManifestParser.AccessibilityPurpose
* } accessibilityPurpose
* The DASH accessibility descriptor, if one was provided for this track.
Expand Down Expand Up @@ -552,7 +561,9 @@ shaka.extern.TextTrack;
* colorGamut: ?string,
* videoLayout: ?string,
* mimeType: ?string,
* codecs: ?string
* codecs: ?string,
* roles: !Array<string>,
* label: ?string,
* }}
*
* @description
Expand Down Expand Up @@ -582,6 +593,10 @@ shaka.extern.TextTrack;
* The video MIME type of the content provided in the manifest.
* @property {?string} codecs
* The video codecs string provided in the manifest, if present.
* @property {!Array<string>} roles
* The roles of the track, e.g. <code>'main'</code>, <code>'sign'</code>.
* @property {?string} label
* The track label, which is unique text that should describe the track.
* @exportDoc
*/
shaka.extern.VideoTrack;
Expand Down Expand Up @@ -2747,7 +2762,8 @@ shaka.extern.TextDisplayerConfiguration;
* preferredAudioLanguage: string,
* preferredAudioLabel: string,
* preferredTextLanguage: string,
* preferredVariantRole: string,
* preferredAudioRole: string,
* preferredVideoRole: string,
* preferredTextRole: string,
* preferredVideoCodecs: !Array<string>,
* preferredAudioCodecs: !Array<string>,
Expand Down Expand Up @@ -2826,8 +2842,12 @@ shaka.extern.TextDisplayerConfiguration;
* Changing this during playback will not affect the current playback.
* <br>
* Defaults to <code>''</code>.
* @property {string} preferredVariantRole
* The preferred role to use for variants.
* @property {string} preferredAudioRole
* The preferred audio role to use for variants.
* <br>
* Defaults to <code>''</code>.
* @property {string} preferredVideoRole
* The preferred video role to use for variants.
* <br>
* Defaults to <code>''</code>.
* @property {string} preferredTextRole
Expand Down
5 changes: 4 additions & 1 deletion lib/media/adaptation_set_criteria.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ shaka.media.AdaptationSetCriteria.Factory;
* @typedef {{
* language: string,
* role: string,
* videoRole: string,
* channelCount: number,
* hdrLevel: string,
* spatialAudio: boolean,
Expand All @@ -75,7 +76,9 @@ shaka.media.AdaptationSetCriteria.Factory;
* @property {string} language
* The language used to filter variants.
* @property {string} role
* The adaptation role used to filter variants.
* The adaptation audio role used to filter variants.
* @property {string} videoRole
* The adaptation video role used to filter variants.
* @property {string} channelCount
* The audio channel count used to filter variants.
* @property {string} hdrLevel
Expand Down
27 changes: 26 additions & 1 deletion lib/media/gap_jumping_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ shaka.media.GapJumpingController = class {
/** @private {number} */
this.startTime_ = 0;

/** @private {boolean} */
this.isJumpingGap_ = false;

/** @private {number} */
this.gapsJumped_ = 0;

Expand Down Expand Up @@ -178,6 +181,15 @@ shaka.media.GapJumpingController = class {
return this.stallsDetected_;
}

/**
* Returns whether the player is currently jumping a gap.
*
* @return {boolean}
*/
getIsJumpingGap() {
return this.isJumpingGap_;
}


/**
* Called on a recurring timer to check for gaps in the media. This is also
Expand Down Expand Up @@ -273,7 +285,7 @@ shaka.media.GapJumpingController = class {
buffered.end(gapIndex - 1), 'and ending at', jumpTo);
}

this.video_.currentTime = jumpTo;
this.seek_(jumpTo);
// This accounts for the possibility that we jump a gap at the start
// position but we jump _into_ another gap. By setting the start
// position to the new jumpTo we ensure that the check above will
Expand All @@ -286,6 +298,19 @@ shaka.media.GapJumpingController = class {
new shaka.util.FakeEvent(shaka.util.FakeEvent.EventName.GapJumped));
}

/**
* Seek to a specific time in the video.
* @param {number} time The time to seek to, in seconds.
* @private
*/
seek_(time) {
this.isJumpingGap_ = true;
this.eventManager_.listenOnce(this.video_, 'seeked', () => {
this.isJumpingGap_ = false;
});
this.video_.currentTime = time;
}

/**
* Create and configure a stall detector using the player's streaming
* configuration settings. If the player is configured to have no stall
Expand Down
17 changes: 17 additions & 0 deletions lib/media/playhead.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ shaka.media.Playhead = class {
*/
getStallsDetected() {}

/**
* Get whether the playhead is currently jumping a gap.
*
* @return {boolean}
*/
getIsJumpingGap() {}

/**
* Get the number of playback gaps jumped by the GapJumpingController.
*
Expand Down Expand Up @@ -209,6 +216,11 @@ shaka.media.SrcEqualsPlayhead = class {
return 0;
}

/** @override */
getIsJumpingGap() {
return false;
}

/** @override */
notifyOfBufferingChange() {}

Expand Down Expand Up @@ -401,6 +413,11 @@ shaka.media.MediaSourcePlayhead = class {
return this.gapController_.getGapsJumped();
}

/** @override */
getIsJumpingGap() {
return this.gapController_.getIsJumpingGap();
}

/**
* Gets the playhead's initial position in seconds.
*
Expand Down
6 changes: 4 additions & 2 deletions lib/media/playhead_observer.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,11 @@ shaka.media.PlayheadObserverManager = class {

/**
* Notify all the observers that we just seeked.
*
* @param {boolean} seeking
*/
notifyOfSeek() {
this.pollAllObservers_(/* seeking= */ true);
notifyOfSeek(seeking) {
this.pollAllObservers_(seeking);
}

/**
Expand Down
51 changes: 43 additions & 8 deletions lib/media/preference_based_criteria.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,26 @@ shaka.media.PreferenceBasedCriteria = class {
}
}

// Now refine the choice based on role preference. Even the empty string
// works here, and will match variants without any roles.
const byRole = Class.filterVariantsByRole_(current, this.config_.role);
if (byRole.length) {
current = byRole;
// Now refine the choice based on audio role preference. Even the empty
// string works here, and will match variants without any roles.
const byAudioRole =
Class.filterVariantsByAudioRole_(current, this.config_.role);
if (byAudioRole.length) {
current = byAudioRole;
} else {
shaka.log.warning('No exact match for variant role could be found.');
shaka.log.warning(
'No exact match for variant audio role could be found.');
}

// Now refine the choice based on video role preference. Even the empty
// string works here, and will match variants without any roles.
const byVideoRole =
Class.filterVariantsByVideoRole_(current, this.config_.videoRole);
if (byVideoRole.length) {
current = byVideoRole;
} else {
shaka.log.warning(
'No exact match for variant video role could be found.');
}

if (this.config_.videoLayout) {
Expand Down Expand Up @@ -210,14 +223,14 @@ shaka.media.PreferenceBasedCriteria = class {
}

/**
* Filter Variants by role.
* Filter Variants by audio role.
*
* @param {!Array<shaka.extern.Variant>} variants
* @param {string} preferredRole
* @return {!Array<shaka.extern.Variant>}
* @private
*/
static filterVariantsByRole_(variants, preferredRole) {
static filterVariantsByAudioRole_(variants, preferredRole) {
return variants.filter((variant) => {
if (!variant.audio) {
return false;
Expand All @@ -231,6 +244,28 @@ shaka.media.PreferenceBasedCriteria = class {
});
}

/**
* Filter Variants by video role.
*
* @param {!Array<shaka.extern.Variant>} variants
* @param {string} preferredRole
* @return {!Array<shaka.extern.Variant>}
* @private
*/
static filterVariantsByVideoRole_(variants, preferredRole) {
return variants.filter((variant) => {
if (!variant.video) {
return false;
}

if (preferredRole) {
return variant.video.roles.includes(preferredRole);
} else {
return variant.video.roles.length == 0;
}
});
}

/**
* Filter Variants by audio label.
*
Expand Down
3 changes: 2 additions & 1 deletion lib/media/preload_manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,8 @@ shaka.media.PreloadManager = class extends shaka.util.FakeEventTarget {
this.config_.adaptationSetCriteriaFactory();
this.currentAdaptationSetCriteria_.configure({
language: this.config_.preferredAudioLanguage,
role: this.config_.preferredVariantRole,
role: this.config_.preferredAudioRole,
videoRole: this.config_.preferredVideoRole,
channelCount: this.config_.preferredAudioChannelCount,
hdrLevel: this.config_.preferredVideoHdrLevel,
spatialAudio: this.config_.preferSpatialAudio,
Expand Down
Loading