diff --git a/build/types/core b/build/types/core
index 8a089c0c5..5ec800009 100644
--- a/build/types/core
+++ b/build/types/core
@@ -71,7 +71,6 @@
+../../lib/text/cue.js
+../../lib/text/cue_region.js
+../../lib/text/native_text_displayer.js
-+../../lib/text/simple_text_displayer.js
+../../lib/text/speech_to_text.js
+../../lib/text/stub_text_displayer.js
+../../lib/text/text_engine.js
@@ -95,7 +94,6 @@
+../../lib/util/error.js
+../../lib/util/event_manager.js
+../../lib/util/exp_golomb.js
-+../../lib/util/fairplay_utils.js
+../../lib/util/fake_event.js
+../../lib/util/fake_event_target.js
+../../lib/util/functional.js
diff --git a/docs/tutorials/manifest-parser.md b/docs/tutorials/manifest-parser.md
index 8d8f70974..eb2365711 100644
--- a/docs/tutorials/manifest-parser.md
+++ b/docs/tutorials/manifest-parser.md
@@ -75,9 +75,8 @@ destroyed.
#### registration
At the end of the file, you should register the parser with the library. This
-will allow it to be used by the `Player`. There are two methods:
-`registerParserByExtension` and `registerParserByMime`. They both add parsers
-to a registry of manifest parsers. When the Player gets a URI, it will
+will allow it to be used by the `Player`. Use `registerParserByMime` to add the
+parser to the registry of manifest parsers. When the Player gets a URI, it will
determine which parser to use. It will first try based on the file extension,
then it will make a HEAD request to the URI to get back a MIME type.
diff --git a/externs/shaka/ads.js b/externs/shaka/ads.js
index 478b29f0b..b357ddb7e 100644
--- a/externs/shaka/ads.js
+++ b/externs/shaka/ads.js
@@ -317,11 +317,6 @@ shaka.extern.IAdManager = class extends EventTarget {
*/
replaceServerSideAdTagParameters(adTagParameters) {}
- /**
- * @return {!Array}
- */
- getServerSideCuePoints() {}
-
/**
* @return {!Array}
*/
diff --git a/externs/shaka/player.js b/externs/shaka/player.js
index 4ca886444..587b000bd 100644
--- a/externs/shaka/player.js
+++ b/externs/shaka/player.js
@@ -921,7 +921,6 @@ shaka.extern.HLSInterstitial;
* endTime: number,
* id: string,
* timescale: number,
- * eventElement: Element,
* eventNode: ?shaka.extern.xml.Node
* }}
*
@@ -942,9 +941,6 @@ shaka.extern.HLSInterstitial;
* Specifies an identifier for this instance of the region.
* @property {number} timescale
* Provides the timescale, in ticks per second.
- * @property {Element} eventElement
- * DEPRECATED: Use eventNode instead.
- * The XML element that defines the Event.
* @property {?shaka.extern.xml.Node} eventNode
* The XML element that defines the Event.
* @exportDoc
@@ -1399,7 +1395,6 @@ shaka.extern.xml.Node;
* ignoreEmptyAdaptationSet: boolean,
* ignoreMaxSegmentDuration: boolean,
* keySystemsByURI: !Object,
- * manifestPreprocessor: function(!Element),
* manifestPreprocessorTXml: function(!shaka.extern.xml.Node),
* sequenceMode: boolean,
* useStreamOnceInPeriodFlattening: boolean,
@@ -1459,11 +1454,6 @@ shaka.extern.xml.Node;
* @property {Object} keySystemsByURI
* A map of scheme URI to key system name. Defaults to default key systems
* mapping handled by Shaka.
- * @property {function(!Element)} manifestPreprocessor
- * DEPRECATED: Use manifestPreprocessorTXml instead.
- * Called immediately after the DASH manifest has been parsed into an
- * XMLDocument. Provides a way for applications to perform efficient
- * preprocessing of the manifest.
* @property {function(!shaka.extern.xml.Node)} manifestPreprocessorTXml
* Called immediately after the DASH manifest has been parsed into an
* XMLDocument. Provides a way for applications to perform efficient
@@ -1602,17 +1592,11 @@ shaka.extern.HlsManifestConfiguration;
/**
* @typedef {{
- * manifestPreprocessor: function(!Element),
* manifestPreprocessorTXml: function(!shaka.extern.xml.Node),
* sequenceMode: boolean,
* keySystemsBySystemId: !Object
* }}
*
- * @property {function(!Element)} manifestPreprocessor
- * DEPRECATED: Use manifestPreprocessorTXml instead.
- * Called immediately after the MSS manifest has been parsed into an
- * XMLDocument. Provides a way for applications to perform efficient
- * preprocessing of the manifest.
* @property {function(!shaka.extern.xml.Node)} manifestPreprocessorTXml
* Called immediately after the MSS manifest has been parsed into an
* XMLDocument. Provides a way for applications to perform efficient
diff --git a/lib/ads/ad_manager.js b/lib/ads/ad_manager.js
index 65245590a..5504d404e 100644
--- a/lib/ads/ad_manager.js
+++ b/lib/ads/ad_manager.js
@@ -8,7 +8,6 @@
goog.provide('shaka.ads.AdManager');
goog.require('goog.asserts');
-goog.require('shaka.Deprecate');
goog.require('shaka.Player');
goog.require('shaka.ads.AdsStats');
goog.require('shaka.ads.ClientSideAdManager');
@@ -736,19 +735,6 @@ shaka.ads.AdManager = class extends shaka.util.FakeEventTarget {
}
- /**
- * @return {!Array}
- * @override
- * @export
- */
- getServerSideCuePoints() {
- shaka.Deprecate.deprecateFeature(5,
- 'AdManager.getServerSideCuePoints',
- 'Please use getCuePoints function.');
- return this.getCuePoints();
- }
-
-
/**
* @return {!Array}
* @override
@@ -942,410 +928,6 @@ shaka.ads.AdManager = class extends shaka.util.FakeEventTarget {
}
};
-/**
- * The event name for when a sequence of ads has been loaded.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.ADS_LOADED = 'ads-loaded';
-
-/**
- * The event name for when an ad has started playing.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_STARTED = 'ad-started';
-
-
-/**
- * The event name for when an ad playhead crosses first quartile.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_FIRST_QUARTILE = 'ad-first-quartile';
-
-
-/**
- * The event name for when an ad playhead crosses midpoint.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_MIDPOINT = 'ad-midpoint';
-
-
-/**
- * The event name for when an ad playhead crosses third quartile.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_THIRD_QUARTILE = 'ad-third-quartile';
-
-
-/**
- * The event name for when an ad has completed playing.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_COMPLETE = 'ad-complete';
-
-
-/**
- * The event name for when an ad has finished playing
- * (played all the way through, was skipped, or was unable to proceed
- * due to an error).
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_STOPPED = 'ad-stopped';
-
-
-/**
- * The event name for when an ad is skipped by the user.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_SKIPPED = 'ad-skipped';
-
-
-/**
- * The event name for when the ad volume has changed.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_VOLUME_CHANGED = 'ad-volume-changed';
-
-
-/**
- * The event name for when the ad was muted.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_MUTED = 'ad-muted';
-
-
-/**
- * The event name for when the ad was paused.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_PAUSED = 'ad-paused';
-
-
-/**
- * The event name for when the ad was resumed after a pause.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_RESUMED = 'ad-resumed';
-
-
-/**
- * The event name for when the ad's skip status changes
- * (usually it becomes skippable when it wasn't before).
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_SKIP_STATE_CHANGED = 'ad-skip-state-changed';
-
-
-/**
- * The event name for when the ad's cue points (start/end markers)
- * have changed.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.CUEPOINTS_CHANGED = 'ad-cue-points-changed';
-
-
-/**
- * The event name for when the native IMA ad manager object has
- * loaded and become available.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.IMA_AD_MANAGER_LOADED = 'ima-ad-manager-loaded';
-
-
-/**
- * The event name for when the native IMA stream manager object has
- * loaded and become available.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.IMA_STREAM_MANAGER_LOADED = 'ima-stream-manager-loaded';
-
-
-/**
- * The event name for when the ad was clicked.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_CLICKED = 'ad-clicked';
-
-
-/**
- * The event name for when there is an update to the current ad's progress.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_PROGRESS = 'ad-progress';
-
-
-/**
- * The event name for when the ad is buffering.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_BUFFERING = 'ad-buffering';
-
-
-/**
- * The event name for when the ad's URL was hit.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_IMPRESSION = 'ad-impression';
-
-
-/**
- * The event name for when the ad's duration changed.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_DURATION_CHANGED = 'ad-duration-changed';
-
-
-/**
- * The event name for when the ad was closed by the user.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_CLOSED = 'ad-closed';
-
-
-/**
- * The event name for when the ad data becomes available.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_LOADED = 'ad-loaded';
-
-
-/**
- * The event name for when all the ads were completed.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.ALL_ADS_COMPLETED = 'all-ads-completed';
-
-
-/**
- * The event name for when the ad changes from or to linear.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_LINEAR_CHANGED = 'ad-linear-changed';
-
-
-/**
- * The event name for when the ad's metadata becomes available.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_METADATA = 'ad-metadata';
-
-
-/**
- * The event name for when the ad display encountered a recoverable
- * error.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_RECOVERABLE_ERROR = 'ad-recoverable-error';
-
-/**
- * The event name for when the ad manager dispatch errors.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_ERROR = 'ad-error';
-
-/**
- * The event name for when the client side SDK signalled its readiness
- * to play a VPAID ad or an ad rule.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_BREAK_READY = 'ad-break-ready';
-
-
-/**
- * The event name for when the interaction callback for the ad was
- * triggered.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_INTERACTION = 'ad-interaction';
-
-
-/**
- * The name of the event for when an ad requires the main content to be paused.
- * Fired when the platform does not support multiple media elements.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_CONTENT_PAUSE_REQUESTED = 'ad-content-pause-requested';
-
-
-/**
- * The name of the event for when an ad requires the main content to be resumed.
- * Fired when the platform does not support multiple media elements.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_CONTENT_RESUME_REQUESTED = 'ad-content-resume-requested';
-
-
-/**
- * The name of the event for when an ad requires the video of the main content
- * to be attached.
- *
- * Deprecated, please use {@link shaka.ads.Utils}
- *
- * @const {string}
- * @export
- * @deprecated
- */
-shaka.ads.AdManager.AD_CONTENT_ATTACH_REQUESTED = 'ad-content-attach-requested';
-
/**
* Set this is a default ad manager for the player.
diff --git a/lib/cast/cast_proxy.js b/lib/cast/cast_proxy.js
index 8112739ea..2f20c1f1f 100644
--- a/lib/cast/cast_proxy.js
+++ b/lib/cast/cast_proxy.js
@@ -11,6 +11,7 @@ goog.require('shaka.Player');
goog.require('shaka.cast.CastSender');
goog.require('shaka.cast.CastUtils');
goog.require('shaka.log');
+goog.require('shaka.util.ArrayUtils');
goog.require('shaka.util.Error');
goog.require('shaka.util.EventManager');
goog.require('shaka.util.FakeEvent');
@@ -463,7 +464,6 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
const initState = {
'video': {},
'player': {},
- 'playerAfterLoad': {},
'manifest': this.localPlayer_.getAssetUri(),
'startTime': null,
'addThumbnailsTrackCalls': this.addThumbnailsTrackCalls_,
@@ -492,14 +492,6 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
initState['player'][setter] = value;
}
- for (const pair of shaka.cast.CastUtils.PlayerInitAfterLoadState) {
- const getter = pair[0];
- const setter = pair[1];
- const value = /** @type {Object} */(this.localPlayer_)[getter]();
-
- initState['playerAfterLoad'][setter] = value;
- }
-
return initState;
}
@@ -564,9 +556,6 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
activeTextTrack = textTracks.find((t) => t.active);
}
- const isTextTrackVisible =
- this.sender_.get('player', 'isTextTrackVisible')();
-
// Now load the manifest, if present.
if (assetUri) {
// Don't autoplay the content until we finish setting up initial state.
@@ -601,19 +590,16 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
this.localVideo_[name] = videoState[name];
}
- for (const pair of shaka.cast.CastUtils.PlayerInitAfterLoadState) {
- const getter = pair[0];
- const setter = pair[1];
- const value = this.sender_.get('player', getter)();
- /** @type {Object} */(this.localPlayer_)[setter](value);
- }
-
- this.localPlayer_.setTextTrackVisibility(isTextTrackVisible);
if (activeTextTrack) {
- this.localPlayer_.selectTextLanguage(
- activeTextTrack.language,
- activeTextTrack.roles,
- activeTextTrack.forced);
+ const newTextTracks = this.localPlayer_.getTextTracks();
+ const trackToSelect = newTextTracks.find((t) => {
+ return t.language == activeTextTrack.language &&
+ shaka.util.ArrayUtils.equal(t.roles, activeTextTrack.roles) &&
+ t.forced == activeTextTrack.forced;
+ });
+ this.localPlayer_.selectTextTrack(trackToSelect);
+ } else {
+ this.localPlayer_.selectTextTrack();
}
// Restore the original autoplay setting.
@@ -819,16 +805,6 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
return Promise.resolve();
};
}
-
- if (name == 'getChapters') {
- // This does not follow our standard pattern (takes an arguments), and
- // therefore can't be proactively proxied and cached the way other
- // synchronous getters can.
- return () => {
- shaka.log.alwaysWarn(name + '() does not work while casting!');
- return [];
- };
- }
} // if (this.sender_.isCasting())
// If we are casting, but the first update has not come in yet, use local
diff --git a/lib/cast/cast_receiver.js b/lib/cast/cast_receiver.js
index 1c8bf8e6d..e6df93553 100644
--- a/lib/cast/cast_receiver.js
+++ b/lib/cast/cast_receiver.js
@@ -440,12 +440,6 @@ shaka.cast.CastReceiver = class extends shaka.util.FakeEventTarget {
this.video_[k] = v;
}
- for (const k in initState['playerAfterLoad']) {
- const v = initState['playerAfterLoad'][k];
- // All player state vars are setters to be called.
- /** @type {Object} */(this.player_)[k](v);
- }
-
// Restore original autoplay setting.
this.video_.autoplay = autoplay;
if (initState['manifest']) {
diff --git a/lib/cast/cast_utils.js b/lib/cast/cast_utils.js
index dab14732f..c5e2a53d0 100644
--- a/lib/cast/cast_utils.js
+++ b/lib/cast/cast_utils.js
@@ -305,8 +305,6 @@ shaka.cast.CastUtils.VideoVoidMethods = [
shaka.cast.CastUtils.PlayerGetterMethods = new Map()
// NOTE: The 'drmInfo' property is not proxied, as it is very large.
.set('getAssetUri', 2)
- .set('getAudioLanguages', 4)
- .set('getAudioLanguagesAndRoles', 4)
.set('getBufferFullness', 1)
.set('getBufferedInfo', 2)
.set('getExpiration', 2)
@@ -315,13 +313,10 @@ shaka.cast.CastUtils.PlayerGetterMethods = new Map()
// NOTE: The 'getManifestParserFactory' property is not proxied, as it would
// not serialize.
.set('getPlaybackRate', 2)
- .set('getTextLanguages', 4)
- .set('getTextLanguagesAndRoles', 4)
.set('isAudioOnly', 10)
.set('isBuffering', 1)
.set('isInProgress', 1)
.set('isLive', 10)
- .set('isTextTrackVisible', 1)
.set('isVideoOnly', 10)
.set('keySystem', 10)
.set('seekRange', 1)
@@ -380,16 +375,6 @@ shaka.cast.CastUtils.PlayerInitState = [
];
-/**
- * Player getter and setter methods that are used to transfer state after
- * load() is resolved.
- * @const {!Array>}
- */
-shaka.cast.CastUtils.PlayerInitAfterLoadState = [
- ['isTextTrackVisible', 'setTextTrackVisibility'],
-];
-
-
/**
* Player methods with no return value that are proxied while casting.
* @const {!Array}
@@ -398,15 +383,11 @@ shaka.cast.CastUtils.PlayerVoidMethods = [
'cancelTrickPlay',
'configure',
'configurationForLowLatency',
- 'getChapters',
'resetConfiguration',
'retryStreaming',
- 'selectAudioLanguage',
'selectAudioTrack',
- 'selectTextLanguage',
'selectTextTrack',
'selectVariantTrack',
- 'selectVariantsByLabel',
'selectVideoTrack',
'setTextTrackVisibility',
'trickPlay',
diff --git a/lib/dash/dash_parser.js b/lib/dash/dash_parser.js
index a727f2e2c..666fe409c 100644
--- a/lib/dash/dash_parser.js
+++ b/lib/dash/dash_parser.js
@@ -8,7 +8,6 @@ goog.provide('shaka.dash.DashParser');
goog.require('goog.asserts');
goog.require('goog.Uri');
-goog.require('shaka.Deprecate');
goog.require('shaka.abr.Ewma');
goog.require('shaka.dash.ContentProtection');
goog.require('shaka.dash.MpdUtils');
@@ -40,7 +39,6 @@ goog.require('shaka.util.StringUtils');
goog.require('shaka.util.TimeUtils');
goog.require('shaka.util.Timer');
goog.require('shaka.util.TXml');
-goog.require('shaka.util.XmlUtils');
/**
@@ -468,27 +466,7 @@ shaka.dash.DashParser = class {
* @private
*/
async parseManifest_(data, finalManifestUri, rootElement) {
- let manifestData = data;
- const manifestPreprocessor = this.config_.dash.manifestPreprocessor;
- const defaultManifestPreprocessor =
- shaka.util.PlayerConfiguration.defaultManifestPreprocessor;
- if (manifestPreprocessor != defaultManifestPreprocessor) {
- shaka.Deprecate.deprecateFeature(5,
- 'manifest.dash.manifestPreprocessor configuration',
- 'Please Use manifest.dash.manifestPreprocessorTXml instead.');
- const mpdElement =
- shaka.util.XmlUtils.parseXml(manifestData, rootElement);
- if (!mpdElement) {
- throw new shaka.util.Error(
- shaka.util.Error.Severity.CRITICAL,
- shaka.util.Error.Category.MANIFEST,
- shaka.util.Error.Code.DASH_INVALID_XML,
- finalManifestUri);
- }
- manifestPreprocessor(mpdElement);
- manifestData = shaka.util.XmlUtils.toArrayBuffer(mpdElement);
- }
- const mpd = shaka.util.TXml.parseXml(manifestData, rootElement);
+ const mpd = shaka.util.TXml.parseXml(data, rootElement);
if (!mpd) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
@@ -3276,7 +3254,6 @@ shaka.dash.DashParser = class {
endTime: endTime,
id: eventNode.attributes['id'] || '',
timescale: timescale,
- eventElement: TXml.txmlNodeToDomElement(eventNode),
eventNode: TXml.cloneNode(eventNode),
};
diff --git a/lib/dependencies/all.js b/lib/dependencies/all.js
index f2c1a511c..153405dbf 100644
--- a/lib/dependencies/all.js
+++ b/lib/dependencies/all.js
@@ -6,8 +6,6 @@
goog.provide('shaka.dependencies');
-goog.require('shaka.Deprecate');
-
/**
* @export
*/
@@ -24,12 +22,6 @@ shaka.dependencies = class {
if (!shaka.dependencies.Allowed[key]) {
throw new Error(`${key} is not supported`);
}
- if (key == shaka.dependencies.Allowed.muxjs) {
- shaka.Deprecate.deprecateFeature(5,
- 'mux.js',
- 'mux.js is no longer used in Shaka Player.');
- return;
- }
shaka.dependencies.dependencies_.set(key, () => dep);
}
@@ -56,7 +48,6 @@ shaka.dependencies = class {
* @enum {string}
*/
shaka.dependencies.Allowed = {
- muxjs: 'muxjs',
ISOBoxer: 'ISOBoxer',
};
diff --git a/lib/lcevc/lcevc_dec.js b/lib/lcevc/lcevc_dec.js
index 2c606661f..a7e290f5b 100644
--- a/lib/lcevc/lcevc_dec.js
+++ b/lib/lcevc/lcevc_dec.js
@@ -6,7 +6,6 @@
goog.provide('shaka.lcevc.Dec');
goog.require('shaka.log');
-goog.require('shaka.Deprecate');
goog.require('shaka.util.IReleasable');
goog.require('shaka.util.ManifestParserUtils');
@@ -51,9 +50,6 @@ shaka.lcevc.Dec = class {
/** @private {boolean} */
this.isDualTrack_ = isDualTrack;
- /** @private {boolean} */
- this.toBeDeprecated_ = false;
-
this.create_();
}
@@ -114,18 +110,10 @@ shaka.lcevc.Dec = class {
if (this.lcevcLib_.SupportObject.webGLSupport(this.canvas_)) {
// Make sure the canvas is not hidden from a previous playback session.
this.canvas_.classList.remove('shaka-hidden');
- // Initiate LCEVC Dec Library based on the type of module available.
- if (this.toBeDeprecated_) {
- this.dec_ = new this.lcevcLib_.LcevcDil(
- this.media_,
- this.canvas_,
- this.decConfig_);
- } else {
- this.dec_ = new this.lcevcLib_.LCEVCdec(
- this.media_,
- this.canvas_,
- this.decConfig_);
- }
+ this.dec_ = new this.lcevcLib_.LCEVCdec(
+ this.media_,
+ this.canvas_,
+ this.decConfig_);
}
}
}
@@ -159,16 +147,8 @@ shaka.lcevc.Dec = class {
if (typeof LCEVCdec !== 'undefined') {
this.lcevcLib_ = LCEVCdec;
} else {
- if (typeof LcevcDil !== 'undefined') {
- this.lcevcLib_ = LcevcDil;
- this.toBeDeprecated_ = true;
- shaka.Deprecate.deprecateFeature(5,
- 'LcevcDil',
- 'lcevc_dil.js is deprecated, please use lcevc_dec.js instead');
- } else {
- shaka.log.alwaysWarn('Could not find LCEVC Library on this page');
- return false;
- }
+ shaka.log.alwaysWarn('Could not find LCEVC Library on this page');
+ return false;
}
// Making Sure if there is a valid LCEVC Dec Library exists.
@@ -225,10 +205,7 @@ shaka.lcevc.Dec = class {
if (this.dec_) {
this.dec_.setLevelSwitching(stream.id, true);
this.dec_.setContainerFormat(containerFormat);
- // This functionality is only available on the LCEVC Dec Library.
- if (!this.toBeDeprecated_) {
- this.dec_.setStreamingFormat(streamingFormat);
- }
+ this.dec_.setStreamingFormat(streamingFormat);
}
}
diff --git a/lib/media/manifest_parser.js b/lib/media/manifest_parser.js
index 17bca48aa..683c360ff 100644
--- a/lib/media/manifest_parser.js
+++ b/lib/media/manifest_parser.js
@@ -6,7 +6,6 @@
goog.provide('shaka.media.ManifestParser');
-goog.require('shaka.Deprecate');
goog.require('shaka.device.DeviceFactory');
goog.require('shaka.log');
goog.require('shaka.util.Error');
@@ -18,21 +17,6 @@ goog.require('shaka.util.Error');
* @export
*/
shaka.media.ManifestParser = class {
- /**
- * Registers a manifest parser by file extension.
- *
- * @param {string} extension The file extension of the manifest.
- * @param {shaka.extern.ManifestParser.Factory} parserFactory The factory
- * used to create parser instances.
- * @export
- */
- static registerParserByExtension(extension, parserFactory) {
- shaka.Deprecate.deprecateFeature(5,
- 'ManifestParser.registerParserByExtension',
- 'Please use an ManifestParser with registerParserByMime function.');
- }
-
-
/**
* Registers a manifest parser by MIME type.
*
diff --git a/lib/mss/mss_parser.js b/lib/mss/mss_parser.js
index 4fcf71fa1..919bcc384 100644
--- a/lib/mss/mss_parser.js
+++ b/lib/mss/mss_parser.js
@@ -7,7 +7,6 @@
goog.provide('shaka.mss.MssParser');
goog.require('goog.asserts');
-goog.require('shaka.Deprecate');
goog.require('shaka.abr.Ewma');
goog.require('shaka.log');
goog.require('shaka.media.InitSegmentReference');
@@ -27,7 +26,6 @@ goog.require('shaka.util.OperationManager');
goog.require('shaka.util.PlayerConfiguration');
goog.require('shaka.util.Timer');
goog.require('shaka.util.TXml');
-goog.require('shaka.util.XmlUtils');
/**
@@ -298,27 +296,7 @@ shaka.mss.MssParser = class {
* @private
*/
parseManifest_(data, finalManifestUri) {
- let manifestData = data;
- const manifestPreprocessor = this.config_.mss.manifestPreprocessor;
- const defaultManifestPreprocessor =
- shaka.util.PlayerConfiguration.defaultManifestPreprocessor;
- if (manifestPreprocessor != defaultManifestPreprocessor) {
- shaka.Deprecate.deprecateFeature(5,
- 'manifest.mss.manifestPreprocessor configuration',
- 'Please Use manifest.mss.manifestPreprocessorTXml instead.');
- const mssElement =
- shaka.util.XmlUtils.parseXml(manifestData, 'SmoothStreamingMedia');
- if (!mssElement) {
- throw new shaka.util.Error(
- shaka.util.Error.Severity.CRITICAL,
- shaka.util.Error.Category.MANIFEST,
- shaka.util.Error.Code.MSS_INVALID_XML,
- finalManifestUri);
- }
- manifestPreprocessor(mssElement);
- manifestData = shaka.util.XmlUtils.toArrayBuffer(mssElement);
- }
- const mss = shaka.util.TXml.parseXml(manifestData, 'SmoothStreamingMedia');
+ const mss = shaka.util.TXml.parseXml(data, 'SmoothStreamingMedia');
if (!mss) {
throw new shaka.util.Error(
shaka.util.Error.Severity.CRITICAL,
diff --git a/lib/player.js b/lib/player.js
index c26d6be51..077fd1d14 100644
--- a/lib/player.js
+++ b/lib/player.js
@@ -36,7 +36,6 @@ goog.require('shaka.net.NetworkingEngine');
goog.require('shaka.net.NetworkingUtils');
goog.require('shaka.text.Cue');
goog.require('shaka.text.NativeTextDisplayer');
-goog.require('shaka.text.SimpleTextDisplayer');
goog.require('shaka.text.SpeechToText');
goog.require('shaka.text.StubTextDisplayer');
goog.require('shaka.text.TextEngine');
@@ -283,25 +282,6 @@ goog.requireType('shaka.media.PresentationTimeline');
*/
-/**
- * @event shaka.Player.TextTrackVisibilityEvent
- * @description Fired when text track visibility changes.
- * An app may want to look at getStats() or
- * isTextTrackVisible() to see what happened.
- *
- *
- *
- * This event is deprecated and will be removed in version 5.0,
- * text track selection and visibility will no longer be treated
- * separately. Selecting or deselecting a text track can now be
- * handled entirely through `selectTextTrack`.
- * @property {string} type
- * 'texttrackvisibility'
- * @deprecated
- * @exportDoc
- */
-
-
/**
* @event shaka.Player.AudioTracksChangedEvent
* @description Fired when the list of audio tracks changes.
@@ -330,8 +310,8 @@ goog.requireType('shaka.media.PresentationTimeline');
* @event shaka.Player.AdaptationEvent
* @description Fired when an automatic adaptation causes the active tracks
* to change. Does not fire when the application calls
- * selectVariantTrack(), selectTextTrack(),
- * selectAudioLanguage(), or selectTextLanguage().
+ * selectVariantTrack(), selectTextTrack(), or
+ * selectAudioTrack()
* @property {string} type
* 'adaptation'
* @property {shaka.extern.Track} oldTrack
@@ -343,9 +323,9 @@ goog.requireType('shaka.media.PresentationTimeline');
/**
* @event shaka.Player.VariantChangedEvent
* @description Fired when a call from the application caused a variant change.
- * Can be triggered by calls to selectVariantTrack() or
- * selectAudioLanguage(). Does not fire when an automatic
- * adaptation causes a variant change.
+ * Can be triggered by calls to selectVariantTrack(),
+ * selectTextTrack(), or selectAudioTrack().
+ * Does not fire when an automatic adaptation causes a variant change.
* An app may want to look at getStats() or
* getVariantTracks() to see what happened.
* @property {string} type
@@ -359,8 +339,7 @@ goog.requireType('shaka.media.PresentationTimeline');
/**
* @event shaka.Player.TextChangedEvent
* @description Fired when a call from the application caused a text stream
- * change. Can be triggered by calls to selectTextTrack() or
- * selectTextLanguage().
+ * change. Can be triggered by calls to selectTextTrack().
* An app may want to look at getStats() or
* getTextTracks() to see what happened.
* @property {string} type
@@ -1036,17 +1015,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
/** @private {?shaka.media.PreloadManager} */
this.preloadNextUrl_ = null;
- // Even though |attach| will start in later interpreter cycles, it should be
- // the LAST thing we do in the constructor because conceptually it relies on
- // player having been initialized.
- if (mediaElement) {
- shaka.Deprecate.deprecateFeature(5,
- 'Player w/ mediaElement',
- 'Please migrate from initializing Player with a mediaElement; ' +
- 'use the attach method instead.');
- this.attach(mediaElement, /* initializeMediaSource= */ true);
- }
-
/** @private {?shaka.extern.TextDisplayer} */
this.textDisplayer_ = null;
@@ -1918,13 +1886,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
}
if (this.manifest_ && this.manifest_.textStreams.length) {
- if (this.textDisplayer_.enableTextDisplayer) {
- this.textDisplayer_.enableTextDisplayer();
- } else {
- shaka.Deprecate.deprecateFeature(5,
- 'Text displayer w/ enableTextDisplayer',
- 'Text displayer should have a "enableTextDisplayer" method!');
- }
+ this.textDisplayer_.enableTextDisplayer();
}
// Wait for the preload manager to do all of the loading it can do.
@@ -1976,24 +1938,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
this.abrManager_.release();
}
this.abrManager_ = abrFactory();
- if (typeof this.abrManager_.setMediaElement != 'function') {
- shaka.Deprecate.deprecateFeature(5,
- 'AbrManager w/o setMediaElement',
- 'Please use an AbrManager with setMediaElement function.');
- this.abrManager_.setMediaElement = () => {};
- }
- if (typeof this.abrManager_.setCmsdManager != 'function') {
- shaka.Deprecate.deprecateFeature(5,
- 'AbrManager w/o setCmsdManager',
- 'Please use an AbrManager with setCmsdManager function.');
- this.abrManager_.setCmsdManager = () => {};
- }
- if (typeof this.abrManager_.trySuggestStreams != 'function') {
- shaka.Deprecate.deprecateFeature(5,
- 'AbrManager w/o trySuggestStreams',
- 'Please use an AbrManager with trySuggestStreams function.');
- this.abrManager_.trySuggestStreams = () => {};
- }
this.abrManager_.configure(this.config_.abr);
}
@@ -2607,18 +2551,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
if (this.lastTextFactory_ !== textDisplayerFactory || force) {
const oldDisplayer = this.textDisplayer_;
this.textDisplayer_ = textDisplayerFactory();
- if (this.textDisplayer_.configure) {
- this.textDisplayer_.configure(this.config_.textDisplayer);
- } else {
- shaka.Deprecate.deprecateFeature(5,
- 'Text displayer w/ configure',
- 'Text displayer should have a "configure" method!');
- }
- if (!this.textDisplayer_.setTextLanguage) {
- shaka.Deprecate.deprecateFeature(5,
- 'Text displayer w/ setTextLanguage',
- 'Text displayer should have a "setTextLanguage" method!');
- }
+ this.textDisplayer_.configure(this.config_.textDisplayer);
if (oldDisplayer) {
this.textDisplayer_.setTextVisibility(oldDisplayer.isTextVisible());
oldDisplayer.destroy().catch(() => {});
@@ -2635,7 +2568,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
this.streamingEngine_.reloadTextStream();
}
} else {
- if (this.textDisplayer_ && this.textDisplayer_.configure) {
+ if (this.textDisplayer_) {
this.textDisplayer_.configure(this.config_.textDisplayer);
}
}
@@ -3044,7 +2977,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
// Don't initialize with a text stream unless we should be streaming
// text.
- if (initialTextStream && this.isTextTrackVisible()) {
+ if (initialTextStream && this.isTextVisible_) {
this.streamingEngine_.switchTextStream(initialTextStream);
this.setTextDisplayerLanguage_();
}
@@ -3224,14 +3157,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
if (track) {
track.mode = showing ? 'showing' : 'hidden';
}
- if (this.textDisplayer_ instanceof shaka.text.SimpleTextDisplayer) {
- const generatedTrack = this.getGeneratedTextTrack_();
- if (generatedTrack) {
- generatedTrack.mode =
- !showing && this.textDisplayer_.isTextVisible() ?
- 'showing' : 'hidden';
- }
- }
}
};
this.loadEventManager_.listen(mediaElement, 'enterpictureinpicture',
@@ -3376,15 +3301,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
!(this.textDisplayer_ instanceof shaka.text.NativeTextDisplayer)
) {
if (textTracks.length) {
- if (this.textDisplayer_.enableTextDisplayer) {
- this.textDisplayer_.enableTextDisplayer();
- } else {
- shaka.Deprecate.deprecateFeature(
- 5,
- 'Text displayer w/ enableTextDisplayer',
- 'Text displayer should have a "enableTextDisplayer" method',
- );
- }
+ this.textDisplayer_.enableTextDisplayer();
}
let enabledNativeTrack = false;
@@ -3481,8 +3398,16 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
return;
}
- const preferredAudioRole = this.config_.preferredAudioRole;
- this.selectAudioLanguage(preferredAudioLanguage, preferredAudioRole);
+ if (this.video_ && this.video_.audioTracks) {
+ const track = shaka.util.StreamUtils.filterStreamsByLanguageAndRole(
+ this.getVariantTracks(),
+ preferredAudioLanguage,
+ this.config_.preferredAudioRole,
+ false)[0];
+ if (track) {
+ this.selectVariantTrack(track);
+ }
+ }
}
/**
@@ -3499,11 +3424,14 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
return;
}
- const preferForcedSubs = this.config_.preferForcedSubs;
- const preferredTextRole = this.config_.preferredTextRole;
-
- this.selectTextLanguage(preferredTextLanguage, preferredTextRole,
- preferForcedSubs);
+ const track = shaka.util.StreamUtils.filterStreamsByLanguageAndRole(
+ this.getTextTracks(),
+ preferredTextLanguage,
+ this.config_.preferredTextRole,
+ this.config_.preferForcedSubs)[0];
+ if (track) {
+ this.selectTextTrack(track);
+ }
}
/**
@@ -4278,352 +4206,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
goog.asserts.assert(typeof(config) == 'object', 'Should be an object!');
- // Deprecate 'preferredVariantRole' configuration.
- if ('preferredVariantRole' in config) {
- shaka.Deprecate.deprecateFeature(5,
- 'preferredVariantRole configuration',
- 'Please Use preferredAudioRole instead.');
- config['preferredAudioRole'] = config['preferredVariantRole'];
- delete config['preferredVariantRole'];
- }
-
- // Deprecate 'streaming.forceTransmuxTS' configuration.
- if (config['streaming'] && 'forceTransmuxTS' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.forceTransmuxTS configuration',
- 'Please Use mediaSource.forceTransmux instead.');
- config['mediaSource'] = config['mediaSource'] || {};
- config['mediaSource']['mediaSource'] =
- config['streaming']['forceTransmuxTS'];
- delete config['streaming']['forceTransmuxTS'];
- }
-
- // Deprecate 'streaming.forceTransmux' configuration.
- if (config['streaming'] && 'forceTransmux' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.forceTransmux configuration',
- 'Please Use mediaSource.forceTransmux instead.');
- config['mediaSource'] = config['mediaSource'] || {};
- config['mediaSource']['mediaSource'] =
- config['streaming']['forceTransmux'];
- delete config['streaming']['forceTransmux'];
- }
-
- // Deprecate 'streaming.useNativeHlsOnSafari' configuration.
- if (config['streaming'] && 'useNativeHlsOnSafari' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.useNativeHlsOnSafari configuration',
- 'Please Use streaming.useNativeHlsForFairPlay or ' +
- 'streaming.preferNativeHls instead.');
- const device = shaka.device.DeviceFactory.getDevice();
- config['streaming']['preferNativeHls'] =
- config['streaming']['useNativeHlsOnSafari'] &&
- device.getBrowserEngine() ===
- shaka.device.IDevice.BrowserEngine.WEBKIT;
- delete config['streaming']['useNativeHlsOnSafari'];
- }
-
- // Deprecate 'streaming.liveSync' boolean configuration.
- if (config['streaming'] &&
- typeof config['streaming']['liveSync'] == 'boolean') {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.liveSync',
- 'Please Use streaming.liveSync.enabled instead.');
- const liveSyncValue = config['streaming']['liveSync'];
- config['streaming']['liveSync'] = {};
- config['streaming']['liveSync']['enabled'] = liveSyncValue;
- }
-
- // map liveSyncMinLatency and liveSyncMaxLatency to liveSync.targetLatency
- // if liveSync.targetLatency isn't set.
- if (config['streaming'] && (!config['streaming']['liveSync'] ||
- !('targetLatency' in config['streaming']['liveSync'])) &&
- ('liveSyncMinLatency' in config['streaming'] ||
- 'liveSyncMaxLatency' in config['streaming'])) {
- const min = config['streaming']['liveSyncMinLatency'] || 0;
- const max = config['streaming']['liveSyncMaxLatency'] || 1;
- const mid = Math.abs(max - min) / 2;
- config['streaming']['liveSync'] = config['streaming']['liveSync'] || {};
- config['streaming']['liveSync']['targetLatency'] = min + mid;
- config['streaming']['liveSync']['targetLatencyTolerance'] = mid;
- }
- // Deprecate 'streaming.liveSyncMaxLatency' configuration.
- if (config['streaming'] && 'liveSyncMaxLatency' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.liveSyncMaxLatency',
- 'Please Use streaming.liveSync.targetLatency and ' +
- 'streaming.liveSync.targetLatencyTolerance instead. ' +
- 'Or, set the values in your DASH manifest');
- delete config['streaming']['liveSyncMaxLatency'];
- }
- // Deprecate 'streaming.liveSyncMinLatency' configuration.
- if (config['streaming'] && 'liveSyncMinLatency' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.liveSyncMinLatency',
- 'Please Use streaming.liveSync.targetLatency and ' +
- 'streaming.liveSync.targetLatencyTolerance instead. ' +
- 'Or, set the values in your DASH manifest');
- delete config['streaming']['liveSyncMinLatency'];
- }
-
- // Deprecate 'streaming.liveSyncTargetLatency' configuration.
- if (config['streaming'] && 'liveSyncTargetLatency' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.liveSyncTargetLatency',
- 'Please Use streaming.liveSync.targetLatency instead.');
- config['streaming']['liveSync'] = config['streaming']['liveSync'] || {};
- config['streaming']['liveSync']['targetLatency'] =
- config['streaming']['liveSyncTargetLatency'];
- delete config['streaming']['liveSyncTargetLatency'];
- }
-
- // Deprecate 'streaming.liveSyncTargetLatencyTolerance' configuration.
- if (config['streaming'] &&
- 'liveSyncTargetLatencyTolerance' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.liveSyncTargetLatencyTolerance',
- 'Please Use streaming.liveSync.targetLatencyTolerance instead.');
- config['streaming']['liveSync'] = config['streaming']['liveSync'] || {};
- config['streaming']['liveSync']['targetLatencyTolerance'] =
- config['streaming']['liveSyncTargetLatencyTolerance'];
- delete config['streaming']['liveSyncTargetLatencyTolerance'];
- }
-
- // Deprecate 'streaming.liveSyncPlaybackRate' configuration.
- if (config['streaming'] && 'liveSyncPlaybackRate' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.liveSyncPlaybackRate',
- 'Please Use streaming.liveSync.maxPlaybackRate instead.');
- config['streaming']['liveSync'] = config['streaming']['liveSync'] || {};
- config['streaming']['liveSync']['maxPlaybackRate'] =
- config['streaming']['liveSyncPlaybackRate'];
- delete config['streaming']['liveSyncPlaybackRate'];
- }
-
- // Deprecate 'streaming.liveSyncMinPlaybackRate' configuration.
- if (config['streaming'] &&
- 'liveSyncMinPlaybackRate' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.liveSyncMinPlaybackRate',
- 'Please Use streaming.liveSync.minPlaybackRate instead.');
- config['streaming']['liveSync'] = config['streaming']['liveSync'] || {};
- config['streaming']['liveSync']['minPlaybackRate'] =
- config['streaming']['liveSyncMinPlaybackRate'];
- delete config['streaming']['liveSyncMinPlaybackRate'];
- }
-
- // Deprecate 'streaming.liveSyncPanicMode' configuration.
- if (config['streaming'] && 'liveSyncPanicMode' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.liveSyncPanicMode',
- 'Please Use streaming.liveSync.panicMode instead.');
- config['streaming']['liveSync'] = config['streaming']['liveSync'] || {};
- config['streaming']['liveSync']['panicMode'] =
- config['streaming']['liveSyncPanicMode'];
- delete config['streaming']['liveSyncPanicMode'];
- }
-
- // Deprecate 'streaming.liveSyncPanicThreshold' configuration.
- if (config['streaming'] &&
- 'liveSyncPanicThreshold' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.liveSyncPanicThreshold',
- 'Please Use streaming.liveSync.panicThreshold instead.');
- config['streaming']['liveSync'] = config['streaming']['liveSync'] || {};
- config['streaming']['liveSync']['panicThreshold'] =
- config['streaming']['liveSyncPanicThreshold'];
- delete config['streaming']['liveSyncPanicThreshold'];
- }
-
- // Deprecate 'mediaSource.sourceBufferExtraFeatures' configuration.
- if (config['mediaSource'] &&
- 'sourceBufferExtraFeatures' in config['mediaSource']) {
- shaka.Deprecate.deprecateFeature(5,
- 'mediaSource.sourceBufferExtraFeatures configuration',
- 'Please Use mediaSource.addExtraFeaturesToSourceBuffer() instead.');
- const sourceBufferExtraFeatures =
- config['mediaSource']['sourceBufferExtraFeatures'];
- config['mediaSource']['addExtraFeaturesToSourceBuffer'] = () => {
- return sourceBufferExtraFeatures;
- };
- delete config['mediaSource']['sourceBufferExtraFeatures'];
- }
-
- // Deprecate 'manifest.hls.useSafariBehaviorForLive' configuration.
- if (config['manifest'] && config['manifest']['hls'] &&
- 'useSafariBehaviorForLive' in config['manifest']['hls']) {
- shaka.Deprecate.deprecateFeature(5,
- 'manifest.hls.useSafariBehaviorForLive configuration',
- 'Please Use liveSync config to keep on live Edge instead.');
- delete config['manifest']['hls']['useSafariBehaviorForLive'];
- }
-
- // Deprecate 'streaming.parsePrftBox' configuration.
- if (config['streaming'] && 'parsePrftBox' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.parsePrftBox configuration',
- 'Now fired without needing a configuration.');
- delete config['streaming']['parsePrftBox'];
- }
-
- // Deprecate 'manifest.dash.enableAudioGroups' configuration.
- if (config['manifest'] && config['manifest']['dash'] &&
- 'enableAudioGroups' in config['manifest']['dash']) {
- shaka.Deprecate.deprecateFeature(5,
- 'manifest.dash.enableAudioGroups configuration',
- 'Please Use manifest.enableAudioGroups instead.');
- config['manifest']['enableAudioGroups'] =
- config['manifest']['dash']['enableAudioGroups'];
- delete config['manifest']['dash']['enableAudioGroups'];
- }
-
- // Deprecate 'streaming.dispatchAllEmsgBoxes' configuration.
- if (config['streaming'] && 'dispatchAllEmsgBoxes' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.dispatchAllEmsgBoxes configuration',
- 'Please Use mediaSource.dispatchAllEmsgBoxes instead.');
- config['mediaSource'] = config['mediaSource'] || {};
- config['mediaSource']['dispatchAllEmsgBoxes'] =
- config['streaming']['dispatchAllEmsgBoxes'];
- delete config['streaming']['dispatchAllEmsgBoxes'];
- }
-
- // Deprecate 'streaming.autoLowLatencyMode' configuration.
- if (config['streaming'] && 'autoLowLatencyMode' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.autoLowLatencyMode configuration',
- 'Please Use streaming.lowLatencyMode instead.');
- config['streaming']['lowLatencyMode'] =
- config['streaming']['autoLowLatencyMode'];
- delete config['streaming']['autoLowLatencyMode'];
- }
-
- // Deprecate 'manifest.dash.ignoreSupplementalCodecs' configuration.
- if (config['manifest'] && config['manifest']['dash'] &&
- 'ignoreSupplementalCodecs' in config['manifest']['dash']) {
- shaka.Deprecate.deprecateFeature(5,
- 'manifest.dash.ignoreSupplementalCodecs configuration',
- 'Please Use manifest.ignoreSupplementalCodecs instead.');
- config['manifest']['ignoreSupplementalCodecs'] =
- config['manifest']['dash']['ignoreSupplementalCodecs'];
- delete config['manifest']['dash']['ignoreSupplementalCodecs'];
- }
-
- // Deprecate 'manifest.hls.ignoreSupplementalCodecs' configuration.
- if (config['manifest'] && config['manifest']['hls'] &&
- 'ignoreSupplementalCodecs' in config['manifest']['hls']) {
- shaka.Deprecate.deprecateFeature(5,
- 'manifest.hls.ignoreSupplementalCodecs configuration',
- 'Please Use manifest.ignoreSupplementalCodecs instead.');
- config['manifest']['ignoreSupplementalCodecs'] =
- config['manifest']['hls']['ignoreSupplementalCodecs'];
- delete config['manifest']['hls']['ignoreSupplementalCodecs'];
- }
-
- // Deprecate 'manifest.dash.updatePeriod' configuration.
- if (config['manifest'] && config['manifest']['dash'] &&
- 'updatePeriod' in config['manifest']['dash']) {
- shaka.Deprecate.deprecateFeature(5,
- 'manifest.dash.updatePeriod configuration',
- 'Please Use manifest.updatePeriod instead.');
- config['manifest']['updatePeriod'] =
- config['manifest']['dash']['updatePeriod'];
- delete config['manifest']['dash']['updatePeriod'];
- }
-
- // Deprecate 'manifest.hls.updatePeriod' configuration.
- if (config['manifest'] && config['manifest']['hls'] &&
- 'updatePeriod' in config['manifest']['hls']) {
- shaka.Deprecate.deprecateFeature(5,
- 'manifest.hls.updatePeriod configuration',
- 'Please Use manifest.updatePeriod instead.');
- config['manifest']['updatePeriod'] =
- config['manifest']['hls']['updatePeriod'];
- delete config['manifest']['hls']['updatePeriod'];
- }
-
- // Deprecate 'manifest.dash.ignoreDrmInfo' configuration.
- if (config['manifest'] && config['manifest']['dash'] &&
- 'ignoreDrmInfo' in config['manifest']['dash']) {
- shaka.Deprecate.deprecateFeature(5,
- 'manifest.dash.ignoreDrmInfo configuration',
- 'Please Use manifest.ignoreDrmInfo instead.');
- config['manifest']['ignoreDrmInfo'] =
- config['manifest']['dash']['ignoreDrmInfo'];
- delete config['manifest']['dash']['ignoreDrmInfo'];
- }
-
- // Deprecate AdvancedDrmConfiguration's videoRobustness and audioRobustness
- // as a string. It's now an array of strings.
- if (config['drm'] && config['drm']['advanced']) {
- let fixedUp = false;
- for (const keySystem in config['drm']['advanced']) {
- const {videoRobustness, audioRobustness} =
- config['drm']['advanced'][keySystem];
- if ('videoRobustness' in config['drm']['advanced'][keySystem] &&
- !Array.isArray(
- config['drm']['advanced'][keySystem]['videoRobustness'])) {
- config['drm']['advanced'][keySystem]['videoRobustness'] =
- [videoRobustness];
- fixedUp = true;
- }
- if ('audioRobustness' in config['drm']['advanced'][keySystem] &&
- !Array.isArray(
- config['drm']['advanced'][keySystem]['audioRobustness'])) {
- config['drm']['advanced'][keySystem]['audioRobustness'] =
- [audioRobustness];
- fixedUp = true;
- }
- }
-
- if (fixedUp) {
- shaka.Deprecate.deprecateFeature(5,
- 'AdvancedDrmConfiguration\'s videoRobustness and audioRobustness',
- 'These properties are no longer strings but array of strings, ' +
- 'please update your usage of these properties.');
- }
- }
-
- // Deprecate 'streaming.forceHTTP' configuration.
- if (config['streaming'] && 'forceHTTP' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.forceHTTP configuration',
- 'Please Use networking.forceHTTP instead.');
- config['networking'] = config['networking'] || {};
- config['networking']['forceHTTP'] = config['streaming']['forceHTTP'];
- delete config['streaming']['forceHTTP'];
- }
-
- // Deprecate 'streaming.forceHTTPS' configuration.
- if (config['streaming'] && 'forceHTTPS' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.forceHTTPS configuration',
- 'Please Use networking.forceHTTP instead.');
- config['networking'] = config['networking'] || {};
- config['networking']['forceHTTPS'] = config['streaming']['forceHTTPS'];
- delete config['streaming']['forceHTTPS'];
- }
-
- // Deprecate 'streaming.minBytesForProgressEvents' configuration.
- if (config['streaming'] &&
- 'minBytesForProgressEvents' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.minBytesForProgressEvents configuration',
- 'Please Use networking.minBytesForProgressEvents instead.');
- config['networking'] = config['networking'] || {};
- config['networking']['minBytesForProgressEvents'] =
- config['streaming']['minBytesForProgressEvents'];
- delete config['streaming']['minBytesForProgressEvents'];
- }
-
- // Deprecate 'streaming.alwaysStreamText' configuration.
- if (config['streaming'] && 'alwaysStreamText' in config['streaming']) {
- shaka.Deprecate.deprecateFeature(5,
- 'streaming.alwaysStreamText configuration',
- 'It is no longer necessary since we included NativeTextDisplayer.');
- delete config['streaming']['alwaysStreamText'];
- }
-
const ret = shaka.util.PlayerConfiguration.mergeConfigObjects(
this.config_, config, this.defaultConfig_());
@@ -5730,20 +5312,20 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
* Note that AdaptationEvents are not fired for manual track
* selections.
*
- * @param {?shaka.extern.TextTrack} track
+ * @param {(?shaka.extern.TextTrack|undefined)=} track
* @export
*/
selectTextTrack(track) {
let isSpeechToText = false;
- if (this.speechToText_ && track != null) {
+ if (this.speechToText_ && track) {
const speechToTextTracks = this.speechToText_.getTextTracks();
isSpeechToText = speechToTextTracks.includes(track);
}
if (this.speechToText_ && !isSpeechToText) {
this.speechToText_.disable();
}
- if (track == null || isSpeechToText) {
- if (this.speechToText_ && isSpeechToText && track != null) {
+ if (!track || isSpeechToText) {
+ if (this.speechToText_ && isSpeechToText && track) {
this.speechToText_.enable(track);
}
this.onTextChanged_();
@@ -6238,353 +5820,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
return Array.from(videoTracksMap.values());
}
- /**
- * Return a list of audio language-role combinations available. If the
- * player has not loaded any content, this will return an empty list.
- *
- *
- *
- * This API is deprecated and will be removed in version 5.0, please migrate
- * to using `getAudioTracks` and `selectAudioTrack`.
- *
- * @return {!Array}
- * @deprecated
- * @export
- */
- getAudioLanguagesAndRoles() {
- return shaka.Player.getLanguageAndRolesFrom_(this.getVariantTracks());
- }
-
- /**
- * Return a list of text language-role combinations available. If the player
- * has not loaded any content, this will be return an empty list.
- *
- *
- *
- * This API is deprecated and will be removed in version 5.0, please migrate
- * to using `getTextTracks` and `selectTextTrack`.
- *
- * @return {!Array}
- * @deprecated
- * @export
- */
- getTextLanguagesAndRoles() {
- return shaka.Player.getLanguageAndRolesFrom_(this.getTextTracks());
- }
-
- /**
- * Return a list of audio languages available. If the player has not loaded
- * any content, this will return an empty list.
- *
- *
- *
- * This API is deprecated and will be removed in version 5.0, please migrate
- * to using `getAudioTracks` and `selectAudioTrack`.
- *
- * @return {!Array}
- * @deprecated
- * @export
- */
- getAudioLanguages() {
- return Array.from(shaka.Player.getLanguagesFrom_(this.getVariantTracks()));
- }
-
- /**
- * Return a list of text languages available. If the player has not loaded
- * any content, this will return an empty list.
- *
- *
- *
- * This API is deprecated and will be removed in version 5.0, please migrate
- * to using `getTextTracks` and `selectTextTrack`.
- *
- * @return {!Array}
- * @deprecated
- * @export
- */
- getTextLanguages() {
- return Array.from(shaka.Player.getLanguagesFrom_(this.getTextTracks()));
- }
-
- /**
- * Sets the current audio language and current variant role to the selected
- * language, role and channel count, and chooses a new variant if need be.
- * If the player has not loaded any content, this will be a no-op.
- *
- *
- *
- * This API is deprecated and will be removed in version 5.0, please migrate
- * to using `getAudioTracks` and `selectAudioTrack`.
- *
- * @param {string} language
- * @param {string=} role
- * @param {number=} channelsCount
- * @param {number=} safeMargin
- * @param {string=} codec
- * @param {boolean=} spatialAudio
- * @param {string=} label
- * @deprecated
- * @export
- */
- selectAudioLanguage(language, role, channelsCount = 0, safeMargin = 0,
- codec = '', spatialAudio = false, label = '') {
- const selectMediaSourceMode = () => {
- const active = this.streamingEngine_.getCurrentVariant();
- this.currentAdaptationSetCriteria_ =
- this.config_.adaptationSetCriteriaFactory();
- this.currentAdaptationSetCriteria_.configure({
- language,
- role: role || '',
- videoRole: (active.video && active.video.roles &&
- active.video.roles[0]) || '',
- channelCount: channelsCount || 0,
- hdrLevel: '',
- spatialAudio: spatialAudio || false,
- videoLayout: '',
- audioLabel: label || '',
- videoLabel: '',
- codecSwitchingStrategy:
- this.config_.mediaSource.codecSwitchingStrategy,
- audioCodec: codec || '',
- activeAudioCodec: active.audio && active.audio.codecs ?
- active.audio.codecs : '',
- activeAudioChannelCount: active.audio && active.audio.channelsCount ?
- active.audio.channelsCount : 0,
- preferredAudioCodecs: this.config_.preferredAudioCodecs,
- preferredAudioChannelCount: this.config_.preferredAudioChannelCount,
- });
-
- const diff = (a, b) => {
- if (!a.video && !b.video) {
- return 0;
- } else if (!a.video || !b.video) {
- return Infinity;
- } else {
- return Math.abs((a.video.height || 0) - (b.video.height || 0)) +
- Math.abs((a.video.width || 0) - (b.video.width || 0));
- }
- };
- // Find the variant whose size is closest to the active variant. This
- // ensures we stay at about the same resolution when just changing the
- // language/role.
- const set =
- this.currentAdaptationSetCriteria_.create(this.manifest_.variants);
- let bestVariant = null;
- for (const curVariant of set.values()) {
- if (!shaka.util.StreamUtils.isPlayable(curVariant)) {
- continue;
- }
- if (!bestVariant ||
- diff(bestVariant, active) > diff(curVariant, active)) {
- bestVariant = curVariant;
- }
- }
- if (bestVariant == active) {
- shaka.log.debug('Audio already selected.');
- return;
- }
- if (bestVariant) {
- const track = shaka.util.StreamUtils.variantToTrack(bestVariant);
- this.selectVariantTrack(
- track, /* clearBuffer= */ true, safeMargin || 0);
- return;
- }
-
- // If we haven't switched yet, just use ABR to find a new track.
- this.chooseVariantAndSwitch_();
- };
- const selectSrcEqualsMode = () => {
- if (this.video_ && this.video_.audioTracks) {
- const track = shaka.util.StreamUtils.filterStreamsByLanguageAndRole(
- this.getVariantTracks(), language, role || '', false)[0];
- if (track) {
- this.selectVariantTrack(track);
- }
- }
- };
- if (this.manifest_ && this.playhead_) {
- selectMediaSourceMode();
- // When using MSE + remote we need to set tracks for both MSE and native
- // apis so that synchronization is maintained.
- if (!this.isRemotePlayback()) {
- return;
- }
- }
- selectSrcEqualsMode();
- }
-
- /**
- * Sets the current text language and current text role to the selected
- * language and role, and chooses a new variant if need be. If the player has
- * not loaded any content, this will be a no-op.
- *
- *
- *
- * This API is deprecated and will be removed in version 5.0, please migrate
- * to using `getTextTracks` and `selectTextTrack`.
- *
- * @param {string} language
- * @param {string=} role
- * @param {boolean=} forced
- * @deprecated
- * @export
- */
- selectTextLanguage(language, role, forced = false) {
- const selectMediaSourceMode = () => {
- this.currentTextLanguage_ = language;
- this.currentTextRole_ = role || '';
- this.currentTextForced_ = forced || false;
-
- const chosenText = this.chooseTextStream_();
- if (chosenText) {
- if (chosenText == this.streamingEngine_.getCurrentTextStream()) {
- shaka.log.debug('Text track already selected.');
- return;
- }
-
- this.addTextStreamToSwitchHistory_(
- chosenText, /* fromAdaptation= */ false);
- if (this.isTextTrackVisible()) {
- this.streamingEngine_.switchTextStream(chosenText);
- this.onTextChanged_();
- this.setTextDisplayerLanguage_();
- }
- }
- };
- const selectSrcEqualsMode = () => {
- const track = shaka.util.StreamUtils.filterStreamsByLanguageAndRole(
- this.getTextTracks(), language, role || '', forced || false)[0];
- if (track) {
- this.selectTextTrack(track);
- }
- };
- if (this.manifest_ && this.playhead_) {
- selectMediaSourceMode();
- // When using MSE + remote we need to set tracks for both MSE and native
- // apis so that synchronization is maintained.
- if (!this.isRemotePlayback()) {
- return;
- }
- }
- selectSrcEqualsMode();
- }
-
- /**
- * Select variant tracks that have a given label. This assumes the
- * label uniquely identifies an audio stream, so all the variants
- * are expected to have the same variant.audio.
- *
- * This API is deprecated and will be removed in version 5.0, please migrate
- * to using `getAudioTracks` and `selectAudioTrack`.
- *
- * @param {string} label
- * @param {boolean=} clearBuffer Optional clear buffer or not when
- * switch to new variant
- * Defaults to true if not provided
- * @param {number=} safeMargin Optional amount of buffer (in seconds) to
- * retain when clearing the buffer.
- * Defaults to 0 if not provided. Ignored if clearBuffer is false.
- * @deprecated
- * @export
- */
- selectVariantsByLabel(label, clearBuffer = true, safeMargin = 0) {
- const selectMediaSourceMode = () => {
- let firstVariantWithLabel = null;
- for (const variant of this.manifest_.variants) {
- if (variant.audio.label == label) {
- firstVariantWithLabel = variant;
- break;
- }
- }
-
- if (firstVariantWithLabel == null) {
- shaka.log.warning('No variants were found with label: ' +
- label + '. Ignoring the request to switch.');
-
- return;
- }
-
- // Label is a unique identifier of a variant's audio stream.
- // Because of that we assume that all the variants with the same
- // label have the same language.
- this.currentAdaptationSetCriteria_ =
- this.config_.adaptationSetCriteriaFactory();
- this.currentAdaptationSetCriteria_.configure({
- language: firstVariantWithLabel.language,
- role: '',
- videoRole: '',
- channelCount: 0,
- hdrLevel: '',
- spatialAudio: false,
- videoLayout: '',
- videoLabel: '',
- audioLabel: label,
- codecSwitchingStrategy:
- this.config_.mediaSource.codecSwitchingStrategy,
- audioCodec: '',
- activeAudioCodec: '',
- activeAudioChannelCount: 0,
- preferredAudioCodecs: this.config_.preferredAudioCodecs,
- preferredAudioChannelCount: this.config_.preferredAudioChannelCount,
- });
-
- this.chooseVariantAndSwitch_(clearBuffer, safeMargin);
- };
- const selectSrcEqualsMode = () => {
- if (this.video_ && this.video_.audioTracks) {
- const audioTracks = Array.from(this.video_.audioTracks);
-
- let trackMatch = null;
-
- for (const audioTrack of audioTracks) {
- if (audioTrack.label == label) {
- trackMatch = audioTrack;
- }
- }
- if (trackMatch) {
- this.switchHtml5Track_(trackMatch);
- }
- }
- };
- if (this.manifest_ && this.playhead_) {
- selectMediaSourceMode();
- // When using MSE + remote we need to set tracks for both MSE and native
- // apis so that synchronization is maintained.
- if (!this.isRemotePlayback()) {
- return;
- }
- }
- selectSrcEqualsMode();
- }
-
- /**
- * Check if the text displayer is enabled.
- *
- *
- *
- * This API is deprecated and will be removed in version 5.0.
- * `getTextTracks` returns all available text tracks, but none may be
- * active, meaning no track is displayed.
- *
- * @return {boolean}
- * @export
- * @deprecated
- */
- isTextTrackVisible() {
- const expected = this.isTextVisible_;
- if (this.textDisplayer_) {
- const actual = this.textDisplayer_.isTextVisible();
- goog.asserts.assert(
- actual == expected, 'text visibility has fallen out of sync');
-
- // Always return the actual value so that the app has the most accurate
- // information (in the case that the values come out of sync in prod).
- return actual;
- }
-
- return expected;
- }
-
/**
* Return a list of chapters tracks.
*
@@ -6596,51 +5831,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
(text) => shaka.util.StreamUtils.textStreamToTrack(text));
}
- /**
- * This returns the list of chapters.
- *
- * @param {string} language
- * @return {!Array}
- * @export
- */
- getChapters(language) {
- shaka.Deprecate.deprecateFeature(5,
- 'getChapters',
- 'Please use an getChaptersAsync.');
- if (!this.externalChaptersStreams_.length) {
- return [];
- }
- const LanguageUtils = shaka.util.LanguageUtils;
- const inputLanguage = LanguageUtils.normalize(language);
- const chapterStreams = this.externalChaptersStreams_
- .filter((c) => LanguageUtils.normalize(c.language) == inputLanguage);
- if (!chapterStreams.length) {
- return [];
- }
- const chapters = [];
- const uniqueChapters = new Set();
- for (const chapterStream of chapterStreams) {
- if (chapterStream.segmentIndex) {
- chapterStream.segmentIndex.forEachTopLevelReference((ref) => {
- const title = ref.getUris()[0];
- const id = ref.startTime + '-' + ref.endTime + '-' + title;
- /** @type {shaka.extern.Chapter} */
- const chapter = {
- id,
- title,
- startTime: ref.startTime,
- endTime: ref.endTime,
- };
- if (!uniqueChapters.has(id)) {
- chapters.push(chapter);
- uniqueChapters.add(id);
- }
- });
- }
- }
- return chapters;
- }
-
/**
* This returns the list of chapters.
*
@@ -6782,11 +5972,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
} else if (this.video_ && this.video_.src && this.video_.textTracks) {
this.textDisplayer_.setTextVisibility(newVisibility);
}
-
- // We need to fire the event after we have updated everything so that
- // everything will be in a stable state when the app responds to the
- // event.
- this.onTextTrackVisibility_();
}
/**
@@ -8469,14 +7654,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
return this.abrManager_.chooseVariant(initialSelection);
} else {
const adaptationSetCriteria = this.currentAdaptationSetCriteria_;
- if (typeof adaptationSetCriteria.getLastAdaptationSet != 'function') {
- shaka.Deprecate.deprecateFeature(5,
- 'AdaptationSetCriteria w/o getLastAdaptationSet',
- 'Please use an AdaptationSetCriteria with getLastAdaptationSet.');
- adaptationSetCriteria.getLastAdaptationSet = () => {
- return null;
- };
- }
const adaptationSet = adaptationSetCriteria.getLastAdaptationSet();
if (adaptationSet) {
const variants = Array.from(adaptationSet.values());
@@ -8708,14 +7885,11 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
// If the cached value says to show text, then update the text displayer
// since it defaults to not shown.
this.textDisplayer_.setTextVisibility(true);
- goog.asserts.assert(this.isTextTrackVisible(),
- 'Should be streaming text');
}
} else {
this.isTextVisible_ = false;
this.textDisplayer_.setTextVisibility(false);
}
- this.onTextTrackVisibility_();
}
/**
@@ -8895,13 +8069,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
this.delayDispatchEvent_(event);
}
- /** @private */
- onTextTrackVisibility_() {
- const event = shaka.Player.makeEvent_(
- shaka.util.FakeEvent.EventName.TextTrackVisibility);
- this.delayDispatchEvent_(event);
- }
-
/** @private */
onAbrStatusChanged_() {
// Restore disabled variants if abr get disabled
@@ -8919,8 +8086,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
*/
setTextDisplayerLanguage_() {
const activeTextTrack = this.getTextTracks().find((t) => t.active);
- if (activeTextTrack &&
- this.textDisplayer_ && this.textDisplayer_.setTextLanguage) {
+ if (activeTextTrack && this.textDisplayer_) {
this.textDisplayer_.setTextLanguage(activeTextTrack.language);
}
}
@@ -9139,7 +8305,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
endTime: region.endTime,
id: region.id,
timescale: region.timescale,
- eventElement: region.eventElement,
eventNode: region.eventNode,
};
@@ -9413,92 +8578,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
}
}
- /**
- * Get the normalized languages for a group of tracks.
- *
- * @param {!Array(shaka.extern.Track|shaka.extern.TextTrack)>} tracks
- * @return {!Set}
- * @private
- */
- static getLanguagesFrom_(tracks) {
- const languages = new Set();
-
- for (const track of tracks) {
- if (track.language) {
- languages.add(shaka.util.LanguageUtils.normalize(track.language));
- } else {
- languages.add('und');
- }
- }
-
- return languages;
- }
-
- /**
- * Get all permutations of normalized languages and role for a group of
- * tracks.
- *
- * @param {!Array(shaka.extern.Track|shaka.extern.TextTrack)>} tracks
- * @return {!Array}
- * @private
- */
- static getLanguageAndRolesFrom_(tracks) {
- /** @type {!Map} */
- const languageToRoles = new Map();
- /** @type {!Map>} */
- const languageRoleToLabel = new Map();
-
- for (let i = 0; i < tracks.length; i++) {
- const track = /** @type {shaka.extern.Track} */(tracks[i]);
- let language = 'und';
- let roles = [];
-
- if (track.language) {
- language = shaka.util.LanguageUtils.normalize(track.language);
- }
-
- if (track.type == 'variant') {
- roles = track.audioRoles;
- } else {
- roles = track.roles;
- }
-
- if (!roles || !roles.length) {
- // We must have an empty role so that we will still get a language-role
- // entry from our Map.
- roles = [''];
- }
-
- if (!languageToRoles.has(language)) {
- languageToRoles.set(language, new Set());
- }
-
- for (const role of roles) {
- languageToRoles.get(language).add(role);
- if (track.label) {
- if (!languageRoleToLabel.has(language)) {
- languageRoleToLabel.set(language, new Map());
- }
- languageRoleToLabel.get(language).set(role, track.label);
- }
- }
- }
-
- // Flatten our map to an array of language-role pairs.
- const pairings = [];
- languageToRoles.forEach((roles, language) => {
- for (const role of roles) {
- let label = null;
- if (languageRoleToLabel.has(language) &&
- languageRoleToLabel.get(language).has(role)) {
- label = languageRoleToLabel.get(language).get(role);
- }
- pairings.push({language, role, label});
- }
- });
- return pairings;
- }
-
/**
* Create an error for when we purposely interrupt a load operation.
*
diff --git a/lib/text/native_text_displayer.js b/lib/text/native_text_displayer.js
index 357b326be..9e7b45d94 100644
--- a/lib/text/native_text_displayer.js
+++ b/lib/text/native_text_displayer.js
@@ -175,12 +175,10 @@ shaka.text.NativeTextDisplayer = class {
if (trackId > -1) {
this.player_.selectTextTrack(
/** @type {!shaka.extern.TextTrack} */({id: trackId}));
+ } else {
+ this.player_.selectTextTrack();
}
}
- // The selectTextTrack() method does not accept null as parameter.
- // So we need to use setTextTrackVisibility() if no track selected.
- this.player_.setTextTrackVisibility(trackId > -1 &&
- this.trackNodes_.get(trackId).track.mode === 'showing');
}).tickAfter(0);
};
diff --git a/lib/text/simple_text_displayer.js b/lib/text/simple_text_displayer.js
deleted file mode 100644
index af702f25b..000000000
--- a/lib/text/simple_text_displayer.js
+++ /dev/null
@@ -1,176 +0,0 @@
-/*! @license
- * Shaka Player
- * Copyright 2016 Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-/**
- * @fileoverview
- */
-
-goog.provide('shaka.text.SimpleTextDisplayer');
-
-goog.require('shaka.Deprecate');
-goog.require('shaka.text.Utils');
-
-
-/**
- * A text displayer plugin using the browser's native VTTCue interface.
- *
- * @implements {shaka.extern.TextDisplayer}
- * @deprecated
- * @export
- */
-shaka.text.SimpleTextDisplayer = class {
- /**
- * @param {HTMLMediaElement} video
- * @param {string} label
- */
- constructor(video, label) {
- shaka.Deprecate.deprecateFeature(5,
- 'SimpleTextDisplayer', 'Please migrate to NativeTextDisplayer');
- /** @private {HTMLMediaElement} */
- this.video_ = video;
-
- /** @private {string} */
- this.textTrackLabel_ = label;
-
- /** @private {TextTrack} */
- this.textTrack_ = null;
-
- // TODO: Test that in all cases, the built-in CC controls in the video
- // element are toggling our TextTrack.
-
- // If the video element has TextTracks, disable them. If we see one that
- // was created by a previous instance of Shaka Player, reuse it.
- for (const track of Array.from(this.video_.textTracks)) {
- if (track.kind === 'metadata' || track.kind === 'chapters') {
- continue;
- }
- // NOTE: There is no API available to remove a TextTrack from a video
- // element.
- track.mode = 'disabled';
-
- if (track.label == this.textTrackLabel_) {
- this.textTrack_ = track;
- }
- }
- if (this.textTrack_) {
- this.textTrack_.mode = 'hidden';
- }
- }
-
-
- /**
- * @override
- * @export
- */
- configure(config) {
- // Unused.
- }
-
- /**
- * @override
- * @export
- */
- remove(start, end) {
- // Check that the displayer hasn't been destroyed.
- if (!this.textTrack_) {
- return false;
- }
-
- const removeInRange = (cue) => {
- const inside = cue.startTime < end && cue.endTime > start;
- return inside;
- };
-
- shaka.text.Utils.removeCuesFromTextTrack(this.textTrack_, removeInRange);
-
- return true;
- }
-
- /**
- * @override
- * @export
- */
- append(cues) {
- if (!this.textTrack_) {
- return;
- }
-
- shaka.text.Utils.appendCuesToTextTrack(this.textTrack_, cues);
- }
-
- /**
- * @override
- * @export
- */
- destroy() {
- if (this.textTrack_) {
- const removeIt = (cue) => true;
- shaka.text.Utils.removeCuesFromTextTrack(this.textTrack_, removeIt);
-
- // NOTE: There is no API available to remove a TextTrack from a video
- // element.
- this.textTrack_.mode = 'disabled';
- }
-
- this.video_ = null;
- this.textTrack_ = null;
- return Promise.resolve();
- }
-
- /**
- * @override
- * @export
- */
- isTextVisible() {
- if (!this.textTrack_) {
- return false;
- }
- return this.textTrack_.mode == 'showing';
- }
-
- /**
- * @override
- * @export
- */
- setTextVisibility(on) {
- if (on && !this.textTrack_) {
- this.createTextTrack_();
- }
- if (this.textTrack_) {
- this.textTrack_.mode = on ? 'showing' : 'hidden';
- }
- }
-
- /**
- * @override
- * @export
- */
- setTextLanguage(language) {
- }
-
- /**
- * @override
- * @export
- */
- enableTextDisplayer() {
- this.createTextTrack_();
- }
-
- /**
- * @private
- */
- createTextTrack_() {
- if (this.video_ && !this.textTrack_) {
- // As far as I can tell, there is no observable difference between setting
- // kind to 'subtitles' or 'captions' when creating the TextTrack object.
- // The individual text tracks from the manifest will still have their own
- // kinds which can be displayed in the app's UI.
- this.textTrack_ =
- this.video_.addTextTrack('subtitles', this.textTrackLabel_);
- this.textTrack_.mode = 'hidden';
- }
- }
-};
diff --git a/lib/text/text_engine.js b/lib/text/text_engine.js
index 715a6b896..a54775999 100644
--- a/lib/text/text_engine.js
+++ b/lib/text/text_engine.js
@@ -7,7 +7,6 @@
goog.provide('shaka.text.TextEngine');
goog.require('goog.asserts');
-goog.require('shaka.Deprecate');
goog.require('shaka.media.ClosedCaptionParser');
goog.require('shaka.text.Cue');
goog.require('shaka.util.BufferUtils');
@@ -149,20 +148,8 @@ shaka.text.TextEngine = class {
goog.asserts.assert(
factory, 'Text type negotiation should have happened already');
this.parser_ = factory();
- if (this.parser_.setSequenceMode) {
- this.parser_.setSequenceMode(sequenceMode);
- } else {
- shaka.Deprecate.deprecateFeature(5,
- 'Text parsers w/ setSequenceMode',
- 'Text parsers should have a "setSequenceMode" method!');
- }
- if (this.parser_.setManifestType) {
- this.parser_.setManifestType(manifestType);
- } else {
- shaka.Deprecate.deprecateFeature(5,
- 'Text parsers w/ setManifestType',
- 'Text parsers should have a "setManifestType" method!');
- }
+ this.parser_.setSequenceMode(sequenceMode);
+ this.parser_.setManifestType(manifestType);
this.segmentRelativeVttTiming_ = segmentRelativeVttTiming;
}
diff --git a/lib/util/fairplay_utils.js b/lib/util/fairplay_utils.js
deleted file mode 100644
index 43aeea525..000000000
--- a/lib/util/fairplay_utils.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/*! @license
- * Shaka Player
- * Copyright 2016 Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-goog.provide('shaka.util.FairPlayUtils');
-
-goog.require('shaka.drm.FairPlay');
-
-
-/**
- * @summary A set of FairPlay utility functions. DEPRECATED: Please use
- * shaka.drm.FairPlay instead.
- * @deprecated
- * @export
- */
-shaka.util.FairPlayUtils = class extends shaka.drm.FairPlay {
- // DEPRECATED
-};
diff --git a/lib/util/fake_event.js b/lib/util/fake_event.js
index 7927c1ffb..9721569b7 100644
--- a/lib/util/fake_event.js
+++ b/lib/util/fake_event.js
@@ -195,7 +195,6 @@ shaka.util.FakeEvent.EventName = {
StateChanged: 'statechanged',
Streaming: 'streaming',
TextChanged: 'textchanged',
- TextTrackVisibility: 'texttrackvisibility',
ThirdQuartile: 'thirdquartile',
TimelineRegionAdded: 'timelineregionadded',
TimelineRegionEnter: 'timelineregionenter',
diff --git a/lib/util/player_configuration.js b/lib/util/player_configuration.js
index bea4314f2..29c312495 100644
--- a/lib/util/player_configuration.js
+++ b/lib/util/player_configuration.js
@@ -149,8 +149,6 @@ shaka.util.PlayerConfiguration = class {
'urn:uuid:3d5e6d35-9b9a-41e8-b843-dd3c6e72c42c':
'com.huawei.wiseplay',
},
- manifestPreprocessor:
- shaka.util.PlayerConfiguration.defaultManifestPreprocessor,
manifestPreprocessorTXml:
shaka.util.PlayerConfiguration.defaultManifestPreprocessorTXml,
sequenceMode: false,
@@ -175,8 +173,6 @@ shaka.util.PlayerConfiguration = class {
allowRangeRequestsToGuessMimeType: false,
},
mss: {
- manifestPreprocessor:
- shaka.util.PlayerConfiguration.defaultManifestPreprocessor,
manifestPreprocessorTXml:
shaka.util.PlayerConfiguration.defaultManifestPreprocessorTXml,
sequenceMode: false,
@@ -681,16 +677,6 @@ shaka.util.PlayerConfiguration = class {
return selectedTracks;
}
- /**
- * @param {!Element} element
- * @return {!Element}
- */
- static defaultManifestPreprocessor(element) {
- return shaka.util.ConfigUtils.referenceParametersAndReturn(
- [element],
- element);
- }
-
/**
* @param {!shaka.extern.xml.Node} element
* @return {!shaka.extern.xml.Node}
diff --git a/lib/util/tXml.js b/lib/util/tXml.js
index bcb5be362..807e179d1 100644
--- a/lib/util/tXml.js
+++ b/lib/util/tXml.js
@@ -894,39 +894,6 @@ shaka.util.TXml = class {
}
}
-
- /**
- * Converts a tXml node to DOM element.
- * @param {shaka.extern.xml.Node} node
- * @return {!Element}
- */
- static txmlNodeToDomElement(node) {
- const TXml = shaka.util.TXml;
- let namespace = '';
- const parts = node.tagName.split(':');
- if (parts.length > 0) {
- namespace = TXml.getKnownSchema(parts[0]);
- }
- const element = document.createElementNS(namespace, node.tagName);
-
- for (const k in node.attributes) {
- const v = node.attributes[k];
- element.setAttribute(k, v);
- }
-
- for (const child of node.children) {
- let childElement;
- if (typeof child == 'string') {
- childElement = new Text(child);
- } else {
- childElement = TXml.txmlNodeToDomElement(child);
- }
- element.appendChild(childElement);
- }
-
- return element;
- }
-
/**
* Clones node and its children recursively. Skips parent.
* @param {?shaka.extern.xml.Node} node
diff --git a/lib/util/ts_parser.js b/lib/util/ts_parser.js
index 576a56e5f..2f53e3fd8 100644
--- a/lib/util/ts_parser.js
+++ b/lib/util/ts_parser.js
@@ -7,7 +7,6 @@
goog.provide('shaka.util.TsParser');
goog.require('goog.asserts');
-goog.require('shaka.Deprecate');
goog.require('shaka.log');
goog.require('shaka.util.ExpGolomb');
goog.require('shaka.util.Id3Utils');
@@ -523,28 +522,6 @@ shaka.util.TsParser = class {
return pes;
}
- /**
- * Parse AVC Nalus
- *
- * The code is based on hls.js
- * Credit to https://github.com/video-dev/hls.js/blob/master/src/demux/tsdemuxer.ts
- *
- * @param {shaka.extern.MPEG_PES} pes
- * @param {?shaka.extern.MPEG_PES=} nextPes
- * @return {!Array}
- * @export
- */
- parseAvcNalus(pes, nextPes) {
- shaka.Deprecate.deprecateFeature(5,
- 'TsParser.parseAvcNalus',
- 'Please use parseNalus function instead.');
- const lastInfo = {
- nalu: null,
- state: null,
- };
- return this.parseNalus(pes, lastInfo);
- }
-
/**
* Parse AVC and HVC Nalus
*
@@ -868,23 +845,6 @@ shaka.util.TsParser = class {
return nalus;
}
- /**
- * Return the video resolution
- *
- * @return {{height: ?string, width: ?string}}
- * @export
- */
- getVideoResolution() {
- shaka.Deprecate.deprecateFeature(5,
- 'TsParser.getVideoResolution',
- 'Please use getVideoInfo function instead.');
- const videoInfo = this.getVideoInfo();
- return {
- height: videoInfo.height,
- width: videoInfo.width,
- };
- }
-
/**
* Return the video information
*
diff --git a/project-words.txt b/project-words.txt
index e2454ebcf..9f517d6c6 100644
--- a/project-words.txt
+++ b/project-words.txt
@@ -77,7 +77,6 @@ submenuopen
textchanged
textlang
textrole
-texttrackvisibility
thirdquartile
timeandseekrangeupdated
timelineregionadded
diff --git a/roadmap.md b/roadmap.md
index 6da267bff..4ecf7c297 100644
--- a/roadmap.md
+++ b/roadmap.md
@@ -12,10 +12,10 @@ Candidate features for future release cycles:
- Background fetch for offline storage
https://github.com/shaka-project/shaka-player/issues/879
-v5.0
+v6.0
- Conversion to Typescript (Smaller, more modular binary)
-v4.17 - 2025 Q4
+v5.0 - 2025 Q4
- Add automatic subtitles with translations (Experimental and disabled by default)
https://github.com/shaka-project/shaka-player/issues/9110
- Change dvvC box to free box for Dolby Vision workarounds
diff --git a/shaka-player.uncompiled.js b/shaka-player.uncompiled.js
index 483481059..c17fd0064 100644
--- a/shaka-player.uncompiled.js
+++ b/shaka-player.uncompiled.js
@@ -137,5 +137,4 @@ goog.require('shaka.ui.VRWebgl');
goog.require('shaka.ui.Watermark');
goog.require('shaka.util.Dom');
goog.require('shaka.util.Error');
-goog.require('shaka.util.FairPlayUtils');
goog.require('shaka.util.Iterables');
diff --git a/test/ads/interstitial_ad_manager_unit.js b/test/ads/interstitial_ad_manager_unit.js
index 1e0481c76..ea218de0e 100644
--- a/test/ads/interstitial_ad_manager_unit.js
+++ b/test/ads/interstitial_ad_manager_unit.js
@@ -1181,7 +1181,6 @@ describe('Interstitial Ad manager', () => {
id: 'PREROLL',
schemeIdUri: 'urn:mpeg:dash:event:alternativeMPD:insert:2025',
eventNode,
- eventElement: TXml.txmlNodeToDomElement(eventNode),
value: '',
timescale: 1,
};
@@ -1216,7 +1215,6 @@ describe('Interstitial Ad manager', () => {
id: 'PREROLL',
schemeIdUri: 'urn:mpeg:dash:event:alternativeMPD:replace:2025',
eventNode,
- eventElement: TXml.txmlNodeToDomElement(eventNode),
value: '',
timescale: 1,
};
@@ -1253,7 +1251,6 @@ describe('Interstitial Ad manager', () => {
id: 'PREROLL',
schemeIdUri: 'urn:mpeg:dash:event:alternativeMPD:insert:2025',
eventNode,
- eventElement: TXml.txmlNodeToDomElement(eventNode),
value: '',
timescale: 1,
};
@@ -1283,7 +1280,6 @@ describe('Interstitial Ad manager', () => {
id: 'OVERLAY',
schemeIdUri: 'urn:mpeg:dash:event:2012',
eventNode,
- eventElement: TXml.txmlNodeToDomElement(eventNode),
value: '',
timescale: 1,
};
@@ -1356,7 +1352,6 @@ describe('Interstitial Ad manager', () => {
id: 'OVERLAY',
schemeIdUri: 'urn:mpeg:dash:event:2012',
eventNode,
- eventElement: TXml.txmlNodeToDomElement(eventNode),
value: '',
timescale: 1,
};
@@ -1386,7 +1381,6 @@ describe('Interstitial Ad manager', () => {
id: 'OVERLAY',
schemeIdUri: 'urn:scte:dash:scte214-events',
eventNode,
- eventElement: TXml.txmlNodeToDomElement(eventNode),
value: '',
timescale: 1,
};
@@ -1477,7 +1471,6 @@ describe('Interstitial Ad manager', () => {
id: 'OVERLAY',
schemeIdUri: 'urn:scte:dash:scte214-events',
eventNode,
- eventElement: TXml.txmlNodeToDomElement(eventNode),
value: '',
timescale: 1,
};
diff --git a/test/cast/cast_proxy_unit.js b/test/cast/cast_proxy_unit.js
index 605ca4c3a..02cea0322 100644
--- a/test/cast/cast_proxy_unit.js
+++ b/test/cast/cast_proxy_unit.js
@@ -316,7 +316,6 @@ describe('CastProxy', () => {
// Local values that will be ignored:
const fakeConfig = {key: 'value'};
mockPlayer.getConfiguration.and.returnValue(fakeConfig);
- mockPlayer.isTextTrackVisible.and.returnValue(false);
// Set up the sender in casting mode:
mockSender.isCasting.and.returnValue(true);
@@ -326,7 +325,6 @@ describe('CastProxy', () => {
const fakeConfig2 = {key2: 'value2'};
const cache = {player: {
getConfiguration: fakeConfig2,
- isTextTrackVisible: true,
trickPlay: jasmine.createSpy('trickPlay'),
}};
mockSender.get.and.callFake((targetName, property) => {
@@ -342,7 +340,6 @@ describe('CastProxy', () => {
});
expect(proxy.getPlayer().getConfiguration()).toEqual(fakeConfig2);
- expect(proxy.getPlayer().isTextTrackVisible()).toBe(true);
// Call a method:
expect(mockPlayer.trickPlay).not.toHaveBeenCalled();
@@ -355,7 +352,6 @@ describe('CastProxy', () => {
it('returns local values when we have no remote values yet', () => {
const fakeConfig = {key: 'value'};
mockPlayer.getConfiguration.and.returnValue(fakeConfig);
- mockPlayer.isTextTrackVisible.and.returnValue(true);
// Set up the sender in casting mode, but without any remote values:
mockSender.isCasting.and.returnValue(true);
@@ -371,7 +367,6 @@ describe('CastProxy', () => {
// Without remote values, we should still return the local ones.
expect(proxy.getPlayer().getConfiguration()).toEqual(fakeConfig);
- expect(proxy.getPlayer().isTextTrackVisible()).toBe(true);
// Call a method:
expect(mockPlayer.trickPlay).not.toHaveBeenCalled();
@@ -494,7 +489,6 @@ describe('CastProxy', () => {
},
player: {
getConfiguration: {key: 'value'},
- isTextTrackVisible: true,
},
};
mockSender.get.and.callFake((targetName, property) => {
@@ -509,7 +503,6 @@ describe('CastProxy', () => {
it('transfers remote state back to local objects', async () => {
// Nothing has been set yet:
expect(mockPlayer.configure).not.toHaveBeenCalled();
- expect(mockPlayer.setTextTrackVisibility).not.toHaveBeenCalled();
expect(mockVideo.loop).toBe(false);
expect(mockVideo.playbackRate).toBe(1);
@@ -520,14 +513,11 @@ describe('CastProxy', () => {
expect(mockPlayer.configure).toHaveBeenCalledWith(
cache.player.getConfiguration);
// Nothing else yet:
- expect(mockPlayer.setTextTrackVisibility).not.toHaveBeenCalled();
expect(mockVideo.loop).toBe(false);
expect(mockVideo.playbackRate).toBe(1);
// The rest is done async:
await shaka.test.Util.shortDelay();
- expect(mockPlayer.setTextTrackVisibility).toHaveBeenCalledWith(
- cache.player.isTextTrackVisible);
expect(mockVideo.loop).toBe(cache.video.loop);
expect(mockVideo.playbackRate).toBe(cache.video.playbackRate);
});
@@ -580,8 +570,6 @@ describe('CastProxy', () => {
expect(mockVideo.play).not.toHaveBeenCalled();
// State was still transferred, though:
- expect(mockPlayer.setTextTrackVisibility).toHaveBeenCalledWith(
- cache.player.isTextTrackVisible);
expect(mockVideo.loop).toBe(cache.video.loop);
expect(mockVideo.playbackRate).toBe(cache.video.playbackRate);
});
@@ -674,8 +662,7 @@ describe('CastProxy', () => {
getAssetUri: jasmine.createSpy('getAssetUri'),
getConfiguration: jasmine.createSpy('getConfiguration'),
configure: jasmine.createSpy('configure'),
- isTextTrackVisible: jasmine.createSpy('isTextTrackVisible'),
- setTextTrackVisibility: jasmine.createSpy('setTextTrackVisibility'),
+ selectTextTrack: jasmine.createSpy('selectTextTrack'),
trickPlay: jasmine.createSpy('trickPlay'),
destroy: jasmine.createSpy('destroy'),
addEventListener: (eventName, listener) => {
diff --git a/test/cast/cast_receiver_integration.js b/test/cast/cast_receiver_integration.js
index d9102e4af..e33261143 100644
--- a/test/cast/cast_receiver_integration.js
+++ b/test/cast/cast_receiver_integration.js
@@ -99,9 +99,6 @@ filterDescribe('CastReceiver', castReceiverIntegrationSupport, () => {
player: {
configure: {},
},
- playerAfterLoad: {
- setTextTrackVisibility: true,
- },
video: {
loop: true,
playbackRate: 5,
diff --git a/test/cast/cast_receiver_unit.js b/test/cast/cast_receiver_unit.js
index 34b9f888f..cf173df36 100644
--- a/test/cast/cast_receiver_unit.js
+++ b/test/cast/cast_receiver_unit.js
@@ -249,9 +249,6 @@ filterDescribe('CastReceiver', castReceiverSupport, () => {
player: {
configure: fakeConfig,
},
- playerAfterLoad: {
- setTextTrackVisibility: true,
- },
video: {
loop: true,
playbackRate: 5,
@@ -275,14 +272,11 @@ filterDescribe('CastReceiver', castReceiverSupport, () => {
// App data next:
expect(mockAppDataCallback).toHaveBeenCalledWith(fakeAppData);
// Nothing else yet:
- expect(mockPlayer.setTextTrackVisibility).not.toHaveBeenCalled();
expect(mockVideo.loop).toBe(false);
expect(mockVideo.playbackRate).toBe(1);
// The rest is done async:
await shaka.test.Util.shortDelay();
- expect(mockPlayer.setTextTrackVisibility).toHaveBeenCalledWith(
- fakeInitState.playerAfterLoad.setTextTrackVisibility);
expect(mockVideo.loop).toBe(fakeInitState.video.loop);
expect(mockVideo.playbackRate).toBe(fakeInitState.video.playbackRate);
});
@@ -392,8 +386,6 @@ filterDescribe('CastReceiver', castReceiverSupport, () => {
expect(mockVideo.play).not.toHaveBeenCalled();
// State was still transferred, though:
- expect(mockPlayer.setTextTrackVisibility).toHaveBeenCalledWith(
- fakeInitState.playerAfterLoad.setTextTrackVisibility);
expect(mockVideo.loop).toBe(fakeInitState.video.loop);
expect(mockVideo.playbackRate).toBe(fakeInitState.video.playbackRate);
});
diff --git a/test/dash/dash_parser_live_unit.js b/test/dash/dash_parser_live_unit.js
index 264ad4999..e350e3e4c 100644
--- a/test/dash/dash_parser_live_unit.js
+++ b/test/dash/dash_parser_live_unit.js
@@ -1332,7 +1332,6 @@ describe('DashParser Live', () => {
endTime: 60,
id: '',
timescale: 100,
- eventElement: jasmine.any(Element),
eventNode: jasmine.any(Object),
});
expect(onTimelineRegionAddedSpy).toHaveBeenCalledWith({
@@ -1342,7 +1341,6 @@ describe('DashParser Live', () => {
endTime: 23,
id: 'abc',
timescale: 100,
- eventElement: jasmine.any(Element),
eventNode: jasmine.any(Object),
});
});
diff --git a/test/media/region_observer_unit.js b/test/media/region_observer_unit.js
index d572c3514..a7c6c31c8 100644
--- a/test/media/region_observer_unit.js
+++ b/test/media/region_observer_unit.js
@@ -365,7 +365,6 @@ describe('RegionObserver', () => {
startTime: startTimeSeconds,
endTime: endTimeSeconds,
timescale: 1,
- eventElement: null,
eventNode: null,
};
}
diff --git a/test/media/region_timeline_unit.js b/test/media/region_timeline_unit.js
index cc59815cd..e75633ccb 100644
--- a/test/media/region_timeline_unit.js
+++ b/test/media/region_timeline_unit.js
@@ -134,7 +134,6 @@ describe('RegionTimeline', () => {
startTime: startTimeSeconds,
endTime: endTimeSeconds,
timescale: 1,
- eventElement: null,
eventNode: null,
};
}
diff --git a/test/player_integration.js b/test/player_integration.js
index 58b591040..f89f92d05 100644
--- a/test/player_integration.js
+++ b/test/player_integration.js
@@ -306,145 +306,6 @@ describe('Player', () => {
});
}); // describe('getStats')
- describe('setTextTrackVisibility', () => {
- // Repro for https://github.com/shaka-project/shaka-player/issues/1879.
- it('appends cues when enabled initially', async () => {
- let cues = [];
- /** @const {!shaka.test.FakeTextDisplayer} */
- const displayer = new shaka.test.FakeTextDisplayer();
- displayer.appendSpy.and.callFake((added) => {
- cues = cues.concat(added);
- });
-
- player.configure('textDisplayFactory', () => displayer);
-
- const preferredTextLanguage = 'fa'; // The same as in the content itself
- player.configure({preferredTextLanguage: preferredTextLanguage});
-
- await player.load('test:sintel_realistic_compiled');
-
- // Play until a time at which the external cues would be on screen.
- await video.play();
- await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 4, 20);
-
- expect(player.isTextTrackVisible()).toBe(true);
- expect(displayer.isTextVisible()).toBe(true);
- expect(cues.length).toBeGreaterThan(0);
- });
-
- it('appends cues for external text', async () => {
- let cues = [];
- /** @const {!shaka.test.FakeTextDisplayer} */
- const displayer = new shaka.test.FakeTextDisplayer();
- displayer.appendSpy.and.callFake((added) => {
- cues = cues.concat(added);
- });
-
- player.configure('textDisplayFactory', () => displayer);
-
- await player.load('test:sintel_no_text_compiled');
- const locationUri = new goog.Uri(location.href);
- const partialUri = new goog.Uri('/base/test/test/assets/text-clip.vtt');
- const absoluteUri = locationUri.resolve(partialUri);
- const newTrack = await player.addTextTrackAsync(
- absoluteUri.toString(), 'en', 'subtitles', 'text/vtt');
-
- expect(player.getTextTracks()).toEqual([newTrack]);
-
- player.selectTextTrack(newTrack);
- player.setTextTrackVisibility(true);
- await waiter.waitForEvent(player, 'texttrackvisibility');
-
- // Play until a time at which the external cues would be on screen.
- await video.play();
- await waiter.waitUntilPlayheadReachesOrFailOnTimeout(video, 4, 20);
-
- expect(player.isTextTrackVisible()).toBe(true);
- expect(displayer.isTextVisible()).toBe(true);
- expect(cues.length).toBeGreaterThan(0);
- });
-
- // https://github.com/shaka-project/shaka-player/issues/2553
- it('does not change the selected track', async () => {
- await player.load('test:forced_subs_simulation_compiled');
-
- // In this content, both text tracks have the same language and role, and
- // so should look identical in terms of choosing one to match a
- // preference. This is important to the test, so verify it first.
- const tracks = player.getTextTracks();
- expect(tracks[0].language).toBe(tracks[1].language);
- expect(tracks[0].roles).toEqual(tracks[1].roles);
-
- const getTracksActive = () => player.getTextTracks().map((t) => t.active);
-
- // If we choose a track first, then turn on text, the track should not
- // change. Try this with both tracks.
- player.setTextTrackVisibility(false);
-
- player.selectTextTrack(tracks[0]);
- expect(getTracksActive()).toEqual([true, false]);
- player.setTextTrackVisibility(true);
- expect(getTracksActive()).toEqual([true, false]);
-
- player.setTextTrackVisibility(false);
-
- player.selectTextTrack(tracks[1]);
- expect(getTracksActive()).toEqual([false, true]);
- player.setTextTrackVisibility(true);
- expect(getTracksActive()).toEqual([false, true]);
- });
-
- // https://github.com/shaka-project/shaka-player/issues/4821
- it('loads a single text stream', async () => {
- /** @type {!jasmine.Spy} */
- const textchanged = jasmine.createSpy('listener');
-
- player.addEventListener('textchanged', Util.spyFunc(textchanged));
-
- player.configure({preferredTextLanguage: 'en'});
- await player.load('test:sintel_no_text_compiled');
-
- textchanged.calls.reset();
-
- // Add preferred language text track.
- const locationUri = new goog.Uri(location.href);
- const partialUri = new goog.Uri('/base/test/test/assets/text-clip.vtt');
- const absoluteUri = locationUri.resolve(partialUri);
- await player.addTextTrackAsync(
- absoluteUri.toString(), 'en', 'subtitles', 'text/vtt');
-
- expect(textchanged).toHaveBeenCalledTimes(1);
-
- // Add alternate language text track.
- // Two text tracks with same timings but different text
- // are necessary for test.
- const partialUri2 =
- new goog.Uri('/base/test/test/assets/text-clip-alt.vtt');
- const absoluteUri2 = locationUri.resolve(partialUri2);
- await player.addTextTrackAsync(
- absoluteUri2.toString(), 'fr', 'subtitles', 'text/vtt');
-
- expect(textchanged).toHaveBeenCalledTimes(2);
-
- const textTracks = player.getTextTracks();
- expect(textTracks.length).toBe(2);
- expect(textTracks[0].language).toBe('en');
- expect(textTracks[1].language).toBe('fr');
-
- // Enable text visibility and immediately change language.
- // Only one set of cues should be active.
- // Cues should be of the selected language track.
- player.setTextTrackVisibility(true);
- player.selectTextLanguage('fr');
- video.currentTime = 5;
- await video.play();
- await waiter.waitForMovementOrFailOnTimeout(video, 10);
-
- expect(video.textTracks[1].activeCues.length).toBe(1);
- expect(player.getTextTracks()[1].active).toBe(true);
- });
- }); // describe('setTextTrackVisibility')
-
describe('autoShowText', () => {
async function textMatchesAudioDoesNot() {
const preferredTextLanguage = 'fa'; // The same as in the content
@@ -519,17 +380,20 @@ describe('Player', () => {
it('enables text if text matches and audio does not', async () => {
await textMatchesAudioDoesNot();
- expect(player.isTextTrackVisible()).toBe(true);
+ const activeTextTrack = player.getTextTracks().find((t) => t.active);
+ expect(activeTextTrack).toBeDefined();
});
it('disables text if text does not match', async () => {
await textDoesNotMatch();
- expect(player.isTextTrackVisible()).toBe(false);
+ const activeTextTrack = player.getTextTracks().find((t) => t.active);
+ expect(activeTextTrack).toBeUndefined();
});
it('disables text if both text and audio match', async () => {
await textAndAudioMatch();
- expect(player.isTextTrackVisible()).toBe(false);
+ const activeTextTrack = player.getTextTracks().find((t) => t.active);
+ expect(activeTextTrack).toBeUndefined();
});
}); // IF_SUBTITLES_MAY_BE_NEEDED
@@ -542,17 +406,20 @@ describe('Player', () => {
it('enables text if text matches and audio does not', async () => {
await textMatchesAudioDoesNot();
- expect(player.isTextTrackVisible()).toBe(true);
+ const activeTextTrack = player.getTextTracks().find((t) => t.active);
+ expect(activeTextTrack).toBeDefined();
});
it('disables text if text does not match', async () => {
await textDoesNotMatch();
- expect(player.isTextTrackVisible()).toBe(false);
+ const activeTextTrack = player.getTextTracks().find((t) => t.active);
+ expect(activeTextTrack).toBeUndefined();
});
it('enables text if both text and audio match', async () => {
await textAndAudioMatch();
- expect(player.isTextTrackVisible()).toBe(true);
+ const activeTextTrack = player.getTextTracks().find((t) => t.active);
+ expect(activeTextTrack).toBeDefined();
});
}); // IF_PREFERRED_TEXT_LANGUAGE
@@ -563,17 +430,20 @@ describe('Player', () => {
it('enables text if text matches and audio does not', async () => {
await textMatchesAudioDoesNot();
- expect(player.isTextTrackVisible()).toBe(true);
+ const activeTextTrack = player.getTextTracks().find((t) => t.active);
+ expect(activeTextTrack).toBeDefined();
});
it('enables text if text does not match', async () => {
await textDoesNotMatch();
- expect(player.isTextTrackVisible()).toBe(true);
+ const activeTextTrack = player.getTextTracks().find((t) => t.active);
+ expect(activeTextTrack).toBeDefined();
});
it('enables text if both text and audio match', async () => {
await textAndAudioMatch();
- expect(player.isTextTrackVisible()).toBe(true);
+ const activeTextTrack = player.getTextTracks().find((t) => t.active);
+ expect(activeTextTrack).toBeDefined();
});
}); // ALWAYS
@@ -584,17 +454,20 @@ describe('Player', () => {
it('disables text if text matches and audio does not', async () => {
await textMatchesAudioDoesNot();
- expect(player.isTextTrackVisible()).toBe(false);
+ const activeTextTrack = player.getTextTracks().find((t) => t.active);
+ expect(activeTextTrack).toBeUndefined();
});
it('disables text if text does not match', async () => {
await textDoesNotMatch();
- expect(player.isTextTrackVisible()).toBe(false);
+ const activeTextTrack = player.getTextTracks().find((t) => t.active);
+ expect(activeTextTrack).toBeUndefined();
});
it('disables text if both text and audio match', async () => {
await textAndAudioMatch();
- expect(player.isTextTrackVisible()).toBe(false);
+ const activeTextTrack = player.getTextTracks().find((t) => t.active);
+ expect(activeTextTrack).toBeUndefined();
});
}); // NEVER
}); // AutoShowText
@@ -724,20 +597,6 @@ describe('Player', () => {
});
}); // describe('TextDisplayer plugin')
- describe('TextAndRoles', () => {
- // Regression Test. Makes sure that the language and role fields have been
- // properly exported from the player.
- it('exports language and roles fields', async () => {
- await player.load('test:sintel_compiled');
- const languagesAndRoles = player.getTextLanguagesAndRoles();
- expect(languagesAndRoles.length).toBeTruthy();
- for (const languageAndRole of languagesAndRoles) {
- expect(languageAndRole.language).not.toBeUndefined();
- expect(languageAndRole.role).not.toBeUndefined();
- }
- });
- }); // describe('TextAndRoles')
-
describe('streaming event', () => {
// Calling switch early during load() caused a failed assertion in Player
// and the track selection was ignored. Because this bug involved
diff --git a/test/player_src_equals_external.js b/test/player_src_equals_external.js
index 439a35a92..94da981c6 100644
--- a/test/player_src_equals_external.js
+++ b/test/player_src_equals_external.js
@@ -110,7 +110,7 @@ describe('Player Src Equals', () => {
player.configure('preferredAudioLanguage', 'de');
player.configure('preferredTextLanguage', 'el');
- player.setTextTrackVisibility(true);
+ player.configure('autoShowText', shaka.config.AutoShowText.ALWAYS);
await loadWithSrcEquals(HLS_CONTENT_URI);
diff --git a/test/player_src_equals_integration.js b/test/player_src_equals_integration.js
index 0fc901f5d..4ddbdc7f7 100644
--- a/test/player_src_equals_integration.js
+++ b/test/player_src_equals_integration.js
@@ -277,19 +277,13 @@ describe('Player Src Equals', () => {
// On platforms with audioTracks, such as Safari, we get one track, with
// language set to whatever is in the mp4.
if (video.audioTracks) {
- expect(player.getAudioLanguages()).toEqual(['en']);
- // Note that some browsers, such as Safari, say this is the 'main'
- // role, while others, such as Edge, do not. For the purposes of this
- // test, it doesn't matter what the role is.
- expect(player.getAudioLanguagesAndRoles()).toEqual(
- [{language: 'en', role: jasmine.any(String), label: null}]);
+ expect(player.getAudioTracks())
+ .toEqual([jasmine.objectContaining({language: 'en'})]);
} else {
- expect(player.getAudioLanguages()).toEqual([]);
- expect(player.getAudioLanguagesAndRoles()).toEqual([]);
+ expect(player.getAudioTracks()).toEqual([]);
}
- expect(player.getTextLanguages()).toEqual([]);
- expect(player.getTextLanguagesAndRoles()).toEqual([]);
+ expect(player.getTextTracks()).toEqual([]);
});
// Even though we loaded content using |src=| we should still be able to get
diff --git a/test/player_unit.js b/test/player_unit.js
index 7f2f6a6be..b6e5b9eae 100644
--- a/test/player_unit.js
+++ b/test/player_unit.js
@@ -679,39 +679,6 @@ describe('Player', () => {
});
});
- describe('setTextTrackVisibility', () => {
- beforeEach(() => {
- manifest = shaka.test.ManifestGenerator.generate((manifest) => {
- manifest.addVariant(0, (variant) => {
- variant.addAudio(1);
- variant.addVideo(2);
- });
- manifest.addTextStream(3, (stream) => {
- stream.bandwidth = 100;
- stream.kind = 'caption';
- stream.label = 'Spanish';
- stream.language = 'es';
- });
- });
- });
-
- it('load text stream if caption is visible', async () => {
- await player.setTextTrackVisibility(true);
- await player.load(fakeManifestUri, 0, fakeMimeType);
- expect(streamingEngine.switchTextStream).toHaveBeenCalled();
- expect(shaka.test.Util.invokeSpy(streamingEngine.getCurrentTextStream))
- .not.toBe(null);
- });
-
- it('does not load text stream if caption is invisible', async () => {
- await player.setTextTrackVisibility(false);
- await player.load(fakeManifestUri, 0, fakeMimeType);
- expect(streamingEngine.switchTextStream).not.toHaveBeenCalled();
- expect(shaka.test.Util.invokeSpy(streamingEngine.getCurrentTextStream))
- .toBe(null);
- });
- });
-
describe('when config.streaming.preferNativeDash is set to true', () => {
beforeAll(() => {
shaka.media.ManifestParser.registerParserByMime(
@@ -2494,13 +2461,15 @@ describe('Player', () => {
expect(getActiveTextTrack().id).toBe(englishTextTrack.id);
});
- it('selectAudioLanguage() takes precedence over ' +
+ it('selectAudioTrack() takes precedence over ' +
'preferredAudioLanguage', () => {
// This preference is set in beforeEach, before load().
expect(player.getConfiguration().preferredAudioLanguage).toBe('en');
expect(getActiveVariantTrack().language).toBe('en');
- player.selectAudioLanguage('es');
+ const newAudioTrack = audioTracks.find((t) => t.language == 'es');
+ goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
+ player.selectAudioTrack(newAudioTrack);
expect(streamingEngine.switchVariant).toHaveBeenCalled();
const args = streamingEngine.switchVariant.calls.argsFor(0);
@@ -2509,10 +2478,13 @@ describe('Player', () => {
expect(getActiveVariantTrack().language).toBe('es');
});
- it('selectAudioLanguage() respects selected role', () => {
+ it('selectAudioTrack() respects selected role', () => {
expect(getActiveVariantTrack().roles).not.toContain('commentary');
- player.selectAudioLanguage('en', 'commentary');
+ const newAudioTrack = audioTracks.find((t) =>
+ t.language == 'en' && t.roles.includes('commentary'));
+ goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
+ player.selectAudioTrack(newAudioTrack);
expect(streamingEngine.switchVariant).toHaveBeenCalled();
const args = streamingEngine.switchVariant.calls.argsFor(0);
@@ -2521,115 +2493,61 @@ describe('Player', () => {
expect(getActiveVariantTrack().roles).toContain('commentary');
});
- it('selectAudioLanguage() ignores unplayable variants', () => {
- player.configure({
- restrictions: {minChannelsCount: 6},
- });
- player.selectAudioLanguage('es');
- expect(getActiveVariantTrack().channelsCount).toBe(6);
- });
-
- it('selectAudioLanguage() respects selected audio codec', () => {
- player.selectAudioLanguage('es', '', 0, 0, 'mp4a.40.2');
+ it('selectAudioTrack() respects selected audio codec', () => {
+ let newAudioTrack = audioTracks.find((t) =>
+ t.language == 'es' && t.codecs == 'mp4a.40.2');
+ goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
+ player.selectAudioTrack(newAudioTrack);
expect(getActiveVariantTrack().audioCodec).toBe('mp4a.40.2');
- player.selectAudioLanguage('es', '', 0, 0, 'ec-3');
+ newAudioTrack = audioTracks.find((t) =>
+ t.language == 'es' && t.codecs == 'ec-3');
+ goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
+ player.selectAudioTrack(newAudioTrack);
expect(getActiveVariantTrack().audioCodec).toBe('ec-3');
});
- it('selectAudioLanguage() applies role only to audio', () => {
+ it('selectAudioTrack() applies role only to audio', () => {
expect(getActiveVariantTrack().roles).not.toContain('commentary');
const videoRoles = getActiveVariantTrack().videoRoles;
- player.selectAudioLanguage('en', 'commentary');
+ let newAudioTrack = audioTracks.find((t) =>
+ t.language == 'en' && t.roles.includes('commentary'));
+ goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
+ player.selectAudioTrack(newAudioTrack);
let args = streamingEngine.switchVariant.calls.argsFor(0);
expect(args[0].audio.roles).toContain('commentary');
expect(args[0].video.roles).toBe(videoRoles);
// Switch audio role from 'commentary' to 'main'.
streamingEngine.switchVariant.calls.reset();
- player.selectAudioLanguage('en', 'main');
+ newAudioTrack = audioTracks.find((t) =>
+ t.language == 'en' && t.roles.includes('main'));
+ goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
+ player.selectAudioTrack(newAudioTrack);
expect(streamingEngine.switchVariant).toHaveBeenCalled();
args = streamingEngine.switchVariant.calls.argsFor(0);
expect(args[0].audio.roles).toContain('main');
expect(args[0].video.roles).toBe(videoRoles);
});
- it('selectAudioLanguage() does not change selected text track', () => {
+ it('selectAudioTrack() does not change selected text track', () => {
// This came up in a custom application that allows to select
// from all tracks regardless of selected language.
- // We imitate this behavior by calling selectTextLanguage()
+ // We imitate this behavior by calling selectTextTrack()
// with one language and then selecting a track in a different
// language.
- player.selectTextLanguage('en');
- const spanishTextTrack = textTracks.filter((t) => t.language == 'es')[0];
- player.selectTextTrack(spanishTextTrack);
- player.selectAudioLanguage('es');
- expect(getActiveTextTrack().id).toBe(spanishTextTrack.id);
- });
-
- // Regression test for https://github.com/shaka-project/shaka-player/issues/2906
- // and https://github.com/shaka-project/shaka-player/issues/2909.
- it('selectAudioLanguage() can choose role-less tracks', async () => {
- // For this test, we use a different (and simpler) manifest.
- // Both audio tracks are English; one has a role, and one has no roles.
- // The role=description track comes first to reproduce the conditions in
- // #2909.
- manifest = shaka.test.ManifestGenerator.generate((manifest) => {
- manifest.addVariant(100, (variant) => {
- variant.bandwidth = 1300;
- variant.language = 'en';
- variant.addVideo(1, (stream) => {
- stream.originalId = 'video';
- stream.bandwidth = 1000;
- stream.width = 100;
- stream.height = 200;
- stream.frameRate = 1000000 / 42000;
- stream.pixelAspectRatio = '59:54';
- stream.roles = [];
- });
- variant.addAudio(2, (stream) => {
- stream.originalId = 'audio-en-description';
- stream.bandwidth = 100;
- stream.channelsCount = 2;
- stream.audioSamplingRate = 48000;
- stream.roles = ['description'];
- });
- });
- manifest.addVariant(101, (variant) => {
- variant.bandwidth = 2300;
- variant.language = 'en';
- variant.addExistingStream(1); // video
- variant.addAudio(3, (stream) => {
- stream.originalId = 'audio-en';
- stream.bandwidth = 100;
- stream.channelsCount = 2;
- stream.audioSamplingRate = 48000;
- stream.roles = [];
- });
- });
- });
-
- // No explicit preferred audio language is also part of #2909.
- player.configure('preferredAudioLanguage', undefined);
-
- // Load again to get this test-specific manifest loaded.
- await player.load(fakeManifestUri, 0, fakeMimeType);
-
- // #2909: The initial choice should be for the role-less track, even
- // though it is second in the manifest.
- expect(getActiveVariantTrack().audioRoles).toEqual([]);
-
- player.selectAudioLanguage('en', 'description');
- expect(getActiveVariantTrack().audioRoles).toEqual(['description']);
-
- // #2906: Selecting no particular role should prefer the track without any
- // roles.
- player.selectAudioLanguage('en');
- expect(getActiveVariantTrack().audioRoles).toEqual([]);
+ let newTextTrack = textTracks.find((t) => t.language == 'en');
+ player.selectTextTrack(newTextTrack);
+ newTextTrack = textTracks.find((t) => t.language == 'es');
+ player.selectTextTrack(newTextTrack);
+ const newAudioTrack = audioTracks.find((t) => t.language == 'es');
+ goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
+ player.selectAudioTrack(newAudioTrack);
+ expect(getActiveTextTrack().id).toBe(newTextTrack.id);
});
// https://github.com/shaka-project/shaka-player/issues/3262
- it('selectAudioLanguage() doesn\'t change resolution', () => {
+ it('selectAudioTrack() doesn\'t change resolution', () => {
player.configure('abr.enabled', false);
abrManager.chooseIndex = 1;
const lowResEn =
@@ -2638,33 +2556,39 @@ describe('Player', () => {
// Switching to 'es' should keep the low-res stream and not choose the
// high-res version.
- player.selectAudioLanguage('es');
+ const newAudioTrack = audioTracks.find((t) => t.language == 'es');
+ goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
+ player.selectAudioTrack(newAudioTrack);
const lowResEs =
variantTracks.filter((t) => t.language == 'es' && t.height == 200)[0];
expect(getActiveVariantTrack().id).toBe(lowResEs.id);
});
- it('selectTextLanguage() does not change selected variant track', () => {
+ it('selectTextTrack() does not change selected variant track', () => {
// This came up in a custom application that allows to select
// from all tracks regardless of selected language.
- // We imitate this behavior by calling selectAudioLanguage()
+ // We imitate this behavior by calling selectAudioTrack()
// with one language and then selecting a track in a different
// language.
- player.selectAudioLanguage('es');
+ const newAudioTrack = audioTracks.find((t) => t.language == 'es');
+ goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
+ player.selectAudioTrack(newAudioTrack);
const englishVariantTrack =
variantTracks.filter((t) => t.language == 'en')[0];
player.selectVariantTrack(englishVariantTrack);
- player.selectTextLanguage('es');
+ const newTextTrack = textTracks.find((t) => t.language == 'es');
+ player.selectTextTrack(newTextTrack);
expect(getActiveVariantTrack().id).toBe(englishVariantTrack.id);
});
- it('selectTextLanguage() takes precedence over ' +
+ it('selectTextTrack() takes precedence over ' +
'preferredTextLanguage', () => {
// This preference is set in beforeEach, before load().
expect(player.getConfiguration().preferredTextLanguage).toBe('es');
expect(getActiveTextTrack().language).toBe('es');
- player.selectTextLanguage('en');
+ const newTextTrack = textTracks.find((t) => t.language == 'en');
+ player.selectTextTrack(newTextTrack);
expect(streamingEngine.switchTextStream).toHaveBeenCalled();
const args = streamingEngine.switchTextStream.calls.argsFor(0);
@@ -2672,10 +2596,12 @@ describe('Player', () => {
expect(getActiveTextTrack().language).toBe('en');
});
- it('selectTextLanguage() respects selected role', () => {
+ it('selectTextTrack() respects selected role', () => {
expect(getActiveTextTrack().roles).not.toContain('commentary');
- player.selectTextLanguage('en', 'commentary');
+ const newTextTrack = textTracks.find((t) =>
+ t.language == 'en' && t.roles.includes('commentary'));
+ player.selectTextTrack(newTextTrack);
expect(streamingEngine.switchTextStream).toHaveBeenCalled();
const args = streamingEngine.switchTextStream.calls.argsFor(0);
@@ -2686,7 +2612,9 @@ describe('Player', () => {
it('changing current audio language changes active stream', () => {
expect(getActiveVariantTrack().language).not.toBe('es');
expect(streamingEngine.switchVariant).not.toHaveBeenCalled();
- player.selectAudioLanguage('es');
+ const newAudioTrack = audioTracks.find((t) => t.language == 'es');
+ goog.asserts.assert(newAudioTrack, 'audio track must be non-null');
+ player.selectAudioTrack(newAudioTrack);
expect(streamingEngine.switchVariant).toHaveBeenCalled();
const args = streamingEngine.switchVariant.calls.argsFor(0);
@@ -2698,7 +2626,8 @@ describe('Player', () => {
it('changing current text language changes active stream', () => {
expect(getActiveTextTrack().language).not.toBe('en');
expect(streamingEngine.switchTextStream).not.toHaveBeenCalled();
- player.selectTextLanguage('en');
+ const newTextTrack = textTracks.find((t) => t.language == 'en');
+ player.selectTextTrack(newTextTrack);
expect(streamingEngine.switchTextStream).toHaveBeenCalled();
const args = streamingEngine.switchTextStream.calls.argsFor(0);
@@ -2706,19 +2635,6 @@ describe('Player', () => {
expect(getActiveTextTrack().language).toBe('en');
});
- // https://github.com/shaka-project/shaka-player/issues/2010
- it('changing text lang changes active stream when not streaming', () => {
- player.setTextTrackVisibility(false);
-
- expect(getActiveTextTrack()).toBe(null);
- expect(streamingEngine.switchTextStream).not.toHaveBeenCalled();
- player.selectTextLanguage('en');
- player.setTextTrackVisibility(true);
-
- expect(streamingEngine.switchTextStream).toHaveBeenCalled();
- expect(getActiveTextTrack().language).toBe('en');
- });
-
it('remembers the channel count when ABR is reenabled', () => {
// We prefer 6 channels, and we are currently playing 6 channels.
expect(player.getConfiguration().preferredAudioChannelCount).toBe(6);
@@ -2875,48 +2791,6 @@ describe('Player', () => {
expect(variantChanged).not.toHaveBeenCalled();
});
- it('in selectTextLanguage', async () => {
- // The current text language.
- const currentLanguage = player.getTextTracks()
- .filter((t) => t.active)[0].language;
- const newLanguage = player.getTextTracks()
- .filter((t) => t.language != currentLanguage)[0].language;
-
- // Call selectTextLanguage with a new language. Expect an event to
- // fire.
- player.selectTextLanguage(newLanguage);
- await shaka.test.Util.shortDelay();
- expect(textChanged).toHaveBeenCalled();
- textChanged.calls.reset();
-
- // Call again with the same language, and expect no event to fire,
- // since nothing changed this time.
- player.selectTextLanguage(newLanguage);
- await shaka.test.Util.shortDelay();
- expect(textChanged).not.toHaveBeenCalled();
- });
-
- it('in selectAudioLanguage', async () => {
- // The current audio language.
- const currentLanguage = player.getVariantTracks()
- .filter((t) => t.active)[0].language;
- const newLanguage = player.getVariantTracks()
- .filter((t) => t.language != currentLanguage)[0].language;
-
- // Call selectAudioLanguage with a new language. Expect an event to
- // fire.
- player.selectAudioLanguage(newLanguage);
- await shaka.test.Util.shortDelay();
- expect(variantChanged).toHaveBeenCalled();
- variantChanged.calls.reset();
-
- // Call again with the same language, and expect no event to fire,
- // since nothing changed this time.
- player.selectAudioLanguage(newLanguage);
- await shaka.test.Util.shortDelay();
- expect(variantChanged).not.toHaveBeenCalled();
- });
-
it('in selectAudioTrack', async () => {
// New audio track.
const newAudioTrack = player.getAudioTracks().find((t) => !t.active);
@@ -2946,8 +2820,6 @@ describe('Player', () => {
await player.load(fakeManifestUri, 0, fakeMimeType);
// Text was turned on during startup.
- expect(player.isTextTrackVisible()).toBe(true);
-
expect(getActiveTextTrack()).toEqual(jasmine.objectContaining({
id: 52,
language: 'en',
@@ -2993,48 +2865,6 @@ describe('Player', () => {
await runTest(['en', 'es', 'pt-BR'], 'pt-PT', 2);
});
- it('enables text if its language differs from audio at start', async () => {
- // A manifest we can use to test text visibility.
- manifest = shaka.test.ManifestGenerator.generate((manifest) => {
- manifest.addVariant(0, (variant) => {
- variant.language = 'pt';
- variant.addAudio(0);
- });
- manifest.addVariant(1, (variant) => {
- variant.language = 'en';
- variant.addAudio(1);
- });
- manifest.addTextStream(2, (stream) => {
- stream.language = 'pt';
- });
- manifest.addTextStream(3, (stream) => {
- stream.language = 'fr';
- });
- });
-
- player.configure({
- preferredAudioLanguage: 'en',
- preferredTextLanguage: 'fr',
- });
-
- expect(player.isTextTrackVisible()).toBe(false);
-
- await player.load(fakeManifestUri, 0, fakeMimeType);
-
- // Text was turned on during startup.
- expect(player.isTextTrackVisible()).toBe(true);
-
- // Turn text back off.
- await player.setTextTrackVisibility(false);
- expect(player.isTextTrackVisible()).toBe(false);
-
- // Change text languages after startup.
- player.selectTextLanguage('pt');
-
- // This should not turn text back on.
- expect(player.isTextTrackVisible()).toBe(false);
- });
-
it('chooses an arbitrary language when none given', async () => {
// The Player shouldn't allow changing between languages, so it should
// choose an arbitrary language when none is given.
@@ -4531,18 +4361,6 @@ describe('Player', () => {
abrManager.switchCallback(manifest.variants[2]);
});
- describe('isTextTrackVisible', () => {
- it('does not throw before load', () => {
- player.isTextTrackVisible();
- });
- });
-
- describe('setTextTrackVisibility', () => {
- it('does not throw before load', async () => {
- await player.setTextTrackVisibility(true);
- });
- });
-
describe('isAudioOnly', () => {
it('detects audio-only content', async () => {
// False before we've loaded anything.
@@ -4697,8 +4515,6 @@ describe('Player', () => {
});
describe('language methods', () => {
- let videoOnlyManifest;
-
beforeEach(() => {
manifest = shaka.test.ManifestGenerator.generate((manifest) => {
manifest.addVariant(1, (variant) => {
@@ -4753,125 +4569,6 @@ describe('Player', () => {
stream.roles = ['main', 'subtitle'];
});
});
-
- videoOnlyManifest = shaka.test.ManifestGenerator.generate((manifest) => {
- manifest.addVariant(1, (variant) => {
- variant.bandwidth = 400;
- variant.addVideo(1);
- });
- manifest.addVariant(2, (variant) => {
- variant.bandwidth = 800;
- variant.addVideo(2);
- });
- });
- });
-
- describe('get*Languages', () => {
- it('returns a list of languages', async () => {
- await player.load(fakeManifestUri, 0, fakeMimeType);
- expect(player.getAudioLanguages()).toEqual(['fr', 'en', 'de']);
- expect(player.getTextLanguages()).toEqual(['es', 'en']);
- });
-
- it('returns "und" for video-only tracks', async () => {
- manifest = videoOnlyManifest;
-
- await player.load(fakeManifestUri, 0, fakeMimeType);
- expect(player.getAudioLanguages()).toEqual(['und']);
- expect(player.getTextLanguages()).toEqual([]);
- });
- });
-
- describe('getAudioLanguagesAndRoles', () => {
- it('ignores video roles and labels', async () => {
- manifest = shaka.test.ManifestGenerator.generate((manifest) => {
- manifest.addVariant(0, (variant) => {
- variant.language = 'en';
- variant.addVideo(1, (stream) => {
- stream.roles = ['video-only-role'];
- stream.label = 'should not show up';
- });
- variant.addAudio(2, (stream) => {
- stream.roles = ['audio-only-role'];
- stream.language = 'en';
- });
- });
- });
-
- await player.load(fakeManifestUri, 0, fakeMimeType);
-
- expect(player.getAudioLanguagesAndRoles()).toEqual([
- {language: 'en', role: 'audio-only-role', label: null},
- ]);
- });
-
- it('lists all language-role combinations', async () => {
- await player.load(fakeManifestUri, 0, fakeMimeType);
- expect(player.getAudioLanguagesAndRoles()).toEqual([
- {language: 'fr', role: '', label: null},
- {language: 'en', role: 'main', label: null},
- {language: 'en', role: 'commentary', label: null},
- {language: 'de', role: 'foo', label: null},
- {language: 'de', role: 'bar', label: null},
- ]);
- });
-
- it('associates audio streams with their labels', async () => {
- manifest = shaka.test.ManifestGenerator.generate((manifest) => {
- manifest.addVariant(0, (variant) => {
- variant.language = 'en';
- variant.addAudio(1, (stream) => {
- stream.roles = ['role-1'];
- stream.language = 'en';
- stream.label = 'english';
- });
- });
- manifest.addVariant(0, (variant) => {
- variant.language = 'es';
- variant.addAudio(2, (stream) => {
- stream.roles = ['role-2', 'role-3'];
- stream.language = 'es';
- stream.label = 'spanish';
- });
- });
- });
-
- await player.load(fakeManifestUri, 0, fakeMimeType);
-
- expect(player.getAudioLanguagesAndRoles()).toEqual([
- {language: 'en', role: 'role-1', label: 'english'},
- {language: 'es', role: 'role-2', label: 'spanish'},
- {language: 'es', role: 'role-3', label: 'spanish'},
- ]);
- });
-
- it('uses "und" for video-only tracks', async () => {
- manifest = shaka.test.ManifestGenerator.generate((manifest) => {
- manifest.addVariant(0, (variant) => {
- variant.addVideo(1, (stream) => {
- stream.roles = ['video-only-role'];
- });
- });
- });
-
- await player.load(fakeManifestUri, 0, fakeMimeType);
- expect(player.getAudioLanguagesAndRoles()).toEqual([
- {language: 'und', role: '', label: null},
- ]);
- });
- });
-
- describe('getTextLanguageAndRoles', () => {
- it('lists all language-role combinations', async () => {
- await player.load(fakeManifestUri, 0, fakeMimeType);
- expect(player.getTextLanguagesAndRoles()).toEqual([
- {language: 'es', role: 'baz', label: null},
- {language: 'es', role: 'qwerty', label: null},
- {language: 'en', role: 'main', label: null},
- {language: 'en', role: 'caption', label: null},
- {language: 'en', role: 'subtitle', label: null},
- ]);
- });
});
describe('getThumbnails', () => {
diff --git a/test/test/util/fake_ad_manager.js b/test/test/util/fake_ad_manager.js
index c8d4de109..05f37819b 100644
--- a/test/test/util/fake_ad_manager.js
+++ b/test/test/util/fake_ad_manager.js
@@ -64,11 +64,6 @@ shaka.test.FakeAdManager = class extends shaka.util.FakeEventTarget {
/** @override */
replaceServerSideAdTagParameters(adTagParameters) {}
- /** @override */
- getServerSideCuePoints() {
- return [];
- }
-
/** @override */
getCuePoints() {
return [];
diff --git a/test/test/util/layout_tests.js b/test/test/util/layout_tests.js
index 262d9ff48..4d8afaff4 100644
--- a/test/test/util/layout_tests.js
+++ b/test/test/util/layout_tests.js
@@ -348,13 +348,15 @@ shaka.test.NativeTextLayoutTests = class extends shaka.test.TextLayoutTests {
getMediaElement: () => this.video,
getLoadMode: () => shaka.Player.LoadMode.MEDIA_SOURCE,
getTextTracks: () => textTracks,
- selectTextTrack: ({id}) => {
- const track = textTracks.find((t) => t.id === id);
- expect(track).toBeTruthy();
- track.active = true;
+ selectTextTrack: (track) => {
+ if (track) {
+ const activeTrack = textTracks.find((t) => t.id === track.id);
+ expect(activeTrack).toBeTruthy();
+ this.textDisplayer.setTextVisibility(true);
+ } else {
+ this.textDisplayer.setTextVisibility(false);
+ }
},
- setTextTrackVisibility: (visible) =>
- this.textDisplayer.setTextVisibility(visible),
};
this.video = shaka.test.UiUtils.createVideoElement();
diff --git a/test/test/util/simple_fakes.js b/test/test/util/simple_fakes.js
index 644fe7e7d..6b3e228ac 100644
--- a/test/test/util/simple_fakes.js
+++ b/test/test/util/simple_fakes.js
@@ -44,6 +44,9 @@ shaka.test.FakeAbrManager = class {
/** @type {!jasmine.Spy} */
this.disable = jasmine.createSpy('disable');
+ /** @type {!jasmine.Spy} */
+ this.trySuggestStreams = jasmine.createSpy('trySuggestStreams');
+
/** @type {!jasmine.Spy} */
this.segmentDownloaded = jasmine.createSpy('segmentDownloaded');
@@ -63,6 +66,12 @@ shaka.test.FakeAbrManager = class {
/** @type {!jasmine.Spy} */
this.playbackRateChanged = jasmine.createSpy('playbackRateChanged');
+ /** @type {!jasmine.Spy} */
+ this.setMediaElement = jasmine.createSpy('setMediaElement');
+
+ /** @type {!jasmine.Spy} */
+ this.setCmsdManager = jasmine.createSpy('setCmsdManager');
+
/** @type {!jasmine.Spy} */
this.configure = jasmine.createSpy('configure');
}
diff --git a/test/text/native_text_displayer_unit.js b/test/text/native_text_displayer_unit.js
index a98ecc80f..b3fb41446 100644
--- a/test/text/native_text_displayer_unit.js
+++ b/test/text/native_text_displayer_unit.js
@@ -35,8 +35,6 @@ describe('NativeTextDisplayer', () => {
expect(track).toBeTruthy();
track.active = true;
},
- setTextTrackVisibility: (visible) =>
- displayer.setTextVisibility(visible),
};
video = new shaka.test.FakeVideo();
/** @suppress {checkTypes} */
diff --git a/test/text/simple_text_displayer_unit.js b/test/text/simple_text_displayer_unit.js
deleted file mode 100644
index 46e58d872..000000000
--- a/test/text/simple_text_displayer_unit.js
+++ /dev/null
@@ -1,469 +0,0 @@
-/*! @license
- * Shaka Player
- * Copyright 2016 Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-
-describe('SimpleTextDisplayer', () => {
- const originalVTTCue = window.VTTCue;
- const Cue = shaka.text.Cue;
- const SimpleTextDisplayer = shaka.text.SimpleTextDisplayer;
-
- /** @type {!shaka.test.FakeVideo} */
- let video;
- /** @type {!shaka.test.FakeTextTrack} */
- let mockTrack;
- /** @type {!shaka.text.SimpleTextDisplayer} */
- let displayer;
-
- beforeEach(() => {
- video = new shaka.test.FakeVideo();
- displayer = new SimpleTextDisplayer(video, shaka.Player.TextTrackLabel);
- displayer.enableTextDisplayer();
-
- expect(video.textTracks.length).toBe(1);
- mockTrack = /** @type {!shaka.test.FakeTextTrack} */ (video.textTracks[0]);
- expect(mockTrack).toBeTruthy();
-
- /**
- * @constructor
- * @param {number} start
- * @param {number} end
- * @param {string} text
- */
- function FakeVTTCue(start, end, text) {
- this.startTime = start;
- this.endTime = end;
- this.text = text;
- this.snapToLines = true;
- this.vertical = undefined;
- this.line = 'auto';
- this.position = 'auto';
- }
- window.VTTCue = /** @type {?} */(FakeVTTCue);
- });
-
- afterEach(async () => {
- await displayer.destroy();
- });
-
- afterAll(() => {
- window.VTTCue = originalVTTCue;
- });
-
- describe('append', () => {
- it('sorts cues before inserting', () => {
- // See: https://bit.ly/2K9VX3s
- verifyHelper(
- [
- {startTime: 10, endTime: 20, text: 'Test1'},
- {startTime: 20, endTime: 30, text: 'Test2'},
- {startTime: 30, endTime: 40, text: 'Test3'},
- ],
- [
- new shaka.text.Cue(20, 30, 'Test2'),
- new shaka.text.Cue(30, 40, 'Test3'),
- new shaka.text.Cue(10, 20, 'Test1'),
- ]);
- });
-
- it('appends equal time cues in reverse order', () => {
- // Regression test for https://github.com/shaka-project/shaka-player/issues/848
-
- // When VTTCue is seen as the real thing (because of the presence of
- // VTTCue.prototype.line), then the reverse-order behavior comes into
- // play. The reverse order is only needed because of VTTCue spec
- // behavior.
-
- // First we test the behavior with a real-looking VTTCue (in which
- // prototype.line merely exists). This simulates Chrome, Firefox, and
- // Safari.
- // eslint-disable-next-line no-restricted-syntax
- window.VTTCue.prototype['line'] = 'auto';
- verifyHelper(
- [
- {startTime: 20, endTime: 40, text: 'Test1'},
- {startTime: 20, endTime: 40, text: 'Test2'},
- {startTime: 20, endTime: 40, text: 'Test3'},
- ],
- [
- // Reverse order to compensate for the way line='auto' is
- // implemented in browsers.
- new shaka.text.Cue(20, 40, 'Test3'),
- new shaka.text.Cue(20, 40, 'Test2'),
- new shaka.text.Cue(20, 40, 'Test1'),
- ]);
-
- // Next we test the behavior with a VTTCue which is seen as a cheap
- // polyfill (in which prototype.line does not exist). This simulates
- // legacy Edge.
- // eslint-disable-next-line no-restricted-syntax
- delete window.VTTCue.prototype['line'];
- displayer.remove(0, Infinity); // Clear the cues from above.
- verifyHelper(
- [
- {startTime: 20, endTime: 40, text: 'Test1'},
- {startTime: 20, endTime: 40, text: 'Test2'},
- {startTime: 20, endTime: 40, text: 'Test3'},
- ],
- [
- // Input order, since the displayer sees this as a fake VTTCue
- // implementation.
- new shaka.text.Cue(20, 40, 'Test1'),
- new shaka.text.Cue(20, 40, 'Test2'),
- new shaka.text.Cue(20, 40, 'Test3'),
- ]);
- });
-
- it('appends nested cues', () => {
- const shakaCue = new shaka.text.Cue(10, 20, '');
- const nestedCue1 = new shaka.text.Cue(10, 20, 'Test1 ');
- const nestedCue2 = new shaka.text.Cue(10, 20, 'Test2');
-
- shakaCue.nestedCues = [nestedCue1, nestedCue2];
- verifyHelper(
- [
- {startTime: 10, endTime: 20, text: 'Test1 Test2'},
- ],
- [shakaCue]);
- });
-
- it('flattens nested cue payloads correctly', () => {
- const level0ContainerCue = new shaka.text.Cue(10, 30, '');
- level0ContainerCue.isContainer = true;
-
- const level1NonContainerCueA = new shaka.text.Cue(10, 20, '');
- const level1NonContainerCueB = new shaka.text.Cue(20, 30, '');
-
- // Add a trailing whitespace character to get a space-delimited expected
- // result.
- const cueANestedCue0 = new shaka.text.Cue(10, 20, 'Cue A Test0 ');
- const cueANestedCue1 = new shaka.text.Cue(10, 20, 'Cue A Test1');
- const cueBNestedCue0 = new shaka.text.Cue(20, 30, 'Cue B Test0 ');
- const cueBNestedCue1 = new shaka.text.Cue(20, 30, 'Cue B Test1');
-
- level1NonContainerCueA.nestedCues = [cueANestedCue0, cueANestedCue1];
- level1NonContainerCueB.nestedCues = [cueBNestedCue0, cueBNestedCue1];
- level0ContainerCue.nestedCues =
- [level1NonContainerCueA, level1NonContainerCueB];
-
- verifyHelper(
- [
- {startTime: 10, endTime: 20, text: 'Cue A Test0 Cue A Test1'},
- {startTime: 20, endTime: 30, text: 'Cue B Test0 Cue B Test1'},
- ],
- [level0ContainerCue]);
- });
-
- // Regression test for b/159050711
- it('maintains the styles of the parent cue', () => {
- const shakaCue = new shaka.text.Cue(10, 20, '');
- const nestedCue1 = new shaka.text.Cue(10, 20, 'Test1 ');
- const nestedCue2 = new shaka.text.Cue(10, 20, 'Test2');
-
- shakaCue.nestedCues = [nestedCue1, nestedCue2];
-
- shakaCue.lineAlign = Cue.lineAlign.CENTER;
- nestedCue1.lineAlign = Cue.lineAlign.START;
- nestedCue2.lineAlign = Cue.lineAlign.START;
-
- verifyHelper(
- [
- {
- startTime: 10,
- endTime: 20,
- text: 'Test1 Test2',
- lineAlign: 'center',
- },
- ],
- [shakaCue]);
- });
-
- it('creates style tags for cues with underline/italics/bold', () => {
- const shakaCue = new shaka.text.Cue(10, 20, '');
-
- // First cue is underlined and italicized.
- const nestedCue1 = new shaka.text.Cue(10, 20, 'Test1');
- nestedCue1.fontStyle = shaka.text.Cue.fontStyle.ITALIC;
- nestedCue1.textDecoration.push(shaka.text.Cue.textDecoration.UNDERLINE);
-
- // Second cue is italicized and bolded.
- const nestedCue2 = new shaka.text.Cue(10, 20, 'Test2');
- nestedCue2.fontStyle = shaka.text.Cue.fontStyle.ITALIC;
- nestedCue2.fontWeight = shaka.text.Cue.fontWeight.BOLD;
-
- // Third cue has no bold, italics, or underline.
- const nestedCue3 = new shaka.text.Cue(10, 20, 'Test3');
-
- // Fourth cue is only underlined.
- const nestedCue4 = new shaka.text.Cue(10, 20, 'Test4');
- nestedCue4.textDecoration.push(shaka.text.Cue.textDecoration.UNDERLINE);
-
- const expectedText =
- 'Test1Test2Test3Test4';
- shakaCue.nestedCues = [nestedCue1, nestedCue2, nestedCue3, nestedCue4];
- verifyHelper(
- [
- {startTime: 10, endTime: 20, text: expectedText},
- ],
- [shakaCue]);
- });
-
- it('adds linebreaks when a linebreak cue is seen', () => {
- const shakaCue = new shaka.text.Cue(10, 20, '');
- const nestedCue1 = new shaka.text.Cue(10, 20, 'Test1');
-
- // Second cue is a linebreak cue.
- const nestedCue2 = new shaka.text.Cue(10, 20, '');
- nestedCue2.lineBreak = true;
-
- const nestedCue3 = new shaka.text.Cue(10, 20, 'Test2');
-
- shakaCue.nestedCues = [nestedCue1, nestedCue2, nestedCue3];
- verifyHelper(
- [
- {startTime: 10, endTime: 20, text: 'Test1\nTest2'},
- ],
- [shakaCue]);
- });
-
- it('skips duplicate cues', () => {
- const cue1 = new shaka.text.Cue(10, 20, 'Test');
- displayer.append([cue1]);
- expect(mockTrack.addCue).toHaveBeenCalledTimes(1);
- mockTrack.addCue.calls.reset();
-
- const cue2 = new shaka.text.Cue(10, 20, 'Test');
- displayer.append([cue2]);
- expect(mockTrack.addCue).not.toHaveBeenCalled();
- });
- });
-
- describe('remove', () => {
- it('removes cues which overlap the range', () => {
- const cue1 = new shaka.text.Cue(0, 1, 'Test');
- const cue2 = new shaka.text.Cue(1, 2, 'Test');
- const cue3 = new shaka.text.Cue(2, 3, 'Test');
- displayer.append([cue1, cue2, cue3]);
-
- displayer.remove(0, 1);
- expect(mockTrack.removeCue).toHaveBeenCalledTimes(1);
- expect(mockTrack.removeCue).toHaveBeenCalledWith(
- jasmine.objectContaining({startTime: 0, endTime: 1}));
- mockTrack.removeCue.calls.reset();
-
- displayer.remove(0.5, 1.001);
- expect(mockTrack.removeCue).toHaveBeenCalledTimes(1);
- expect(mockTrack.removeCue).toHaveBeenCalledWith(
- jasmine.objectContaining({startTime: 1, endTime: 2}));
- mockTrack.removeCue.calls.reset();
-
- displayer.remove(3, 5);
- expect(mockTrack.removeCue).not.toHaveBeenCalled();
- mockTrack.removeCue.calls.reset();
-
- displayer.remove(2.9999, Infinity);
- expect(mockTrack.removeCue).toHaveBeenCalledTimes(1);
- expect(mockTrack.removeCue).toHaveBeenCalledWith(
- jasmine.objectContaining({startTime: 2, endTime: 3}));
- mockTrack.removeCue.calls.reset();
- });
-
- it('does nothing when nothing is buffered', () => {
- displayer.remove(0, 1);
- expect(mockTrack.removeCue).not.toHaveBeenCalled();
- });
- });
-
- describe('convertToTextTrackCue', () => {
- it('converts shaka.text.Cues to VttCues', () => {
- verifyHelper(
- [
- {startTime: 20, endTime: 40, text: 'Test4'},
- ],
- [
- new shaka.text.Cue(20, 40, 'Test4'),
- ]);
-
- const cue1 = new shaka.text.Cue(20, 40, 'Test5');
- cue1.positionAlign = Cue.positionAlign.LEFT;
- cue1.lineAlign = Cue.lineAlign.START;
- cue1.size = 80;
- cue1.textAlign = Cue.textAlign.LEFT;
- cue1.writingMode = Cue.writingMode.VERTICAL_LEFT_TO_RIGHT;
- cue1.lineInterpretation = Cue.lineInterpretation.LINE_NUMBER;
- cue1.line = 5;
- cue1.position = 10;
-
- verifyHelper(
- [
- {
- startTime: 20,
- endTime: 40,
- text: 'Test5',
- lineAlign: 'start',
- positionAlign: 'line-left',
- size: 80,
- align: 'left',
- vertical: 'lr',
- snapToLines: true,
- line: 5,
- position: 10,
- },
- ], [cue1]);
-
- const cue2 = new shaka.text.Cue(30, 50, 'Test');
- cue2.positionAlign = Cue.positionAlign.RIGHT;
- cue2.lineAlign = Cue.lineAlign.END;
- cue2.textAlign = Cue.textAlign.RIGHT;
- cue2.writingMode = Cue.writingMode.VERTICAL_RIGHT_TO_LEFT;
- cue2.lineInterpretation = Cue.lineInterpretation.PERCENTAGE;
- cue2.line = 5;
-
- verifyHelper(
- [
- {
- startTime: 30,
- endTime: 50,
- text: 'Test',
- lineAlign: 'end',
- positionAlign: 'line-right',
- align: 'right',
- vertical: 'rl',
- snapToLines: false,
- line: 5,
- },
- ], [cue2]);
-
- const cue3 = new shaka.text.Cue(40, 60, 'Test1');
- cue3.positionAlign = Cue.positionAlign.CENTER;
- cue3.lineAlign = Cue.lineAlign.CENTER;
- cue3.textAlign = Cue.textAlign.START;
- cue3.direction = Cue.direction.HORIZONTAL_LEFT_TO_RIGHT;
-
- verifyHelper(
- [
- {
- startTime: 40,
- endTime: 60,
- text: 'Test1',
- lineAlign: 'center',
- positionAlign: 'center',
- align: 'start',
- vertical: undefined,
- },
- ], [cue3]);
-
- const cue4 = new shaka.text.Cue(40, 60, 'Test2');
- cue4.line = null;
- cue4.position = null;
-
- verifyHelper(
- [
- {
- startTime: 40,
- endTime: 60,
- text: 'Test2',
- line: 'auto',
- position: 'auto',
- },
- ], [cue4]);
-
- const cue5 = new shaka.text.Cue(40, 60, 'Test3');
- cue5.line = 0;
- cue5.position = 0;
-
- verifyHelper(
- [
- {
- startTime: 40,
- endTime: 60,
- text: 'Test3',
- line: 0,
- position: 0,
- },
- ], [cue5]);
- });
-
- it('works around browsers not supporting align=center', () => {
- /**
- * @constructor
- * @param {number} start
- * @param {number} end
- * @param {string} text
- */
- function FakeVTTCueWithoutAlignCenter(start, end, text) {
- let align = 'middle';
- Object.defineProperty(this, 'align', {
- get: () => align,
- set: (newValue) => {
- if (newValue != 'center') {
- align = newValue;
- }
- },
- });
- this.startTime = start;
- this.endTime = end;
- this.text = text;
- }
- window.VTTCue = /** @type {?} */(FakeVTTCueWithoutAlignCenter);
-
- const cue1 = new shaka.text.Cue(20, 40, 'Test');
- cue1.textAlign = Cue.textAlign.CENTER;
-
- verifyHelper(
- [
- {
- startTime: 20,
- endTime: 40,
- text: 'Test',
- align: 'middle',
- },
- ],
- [cue1]);
- });
-
- it('ignores cues with startTime >= endTime', () => {
- mockTrack.addCue.calls.reset();
- const cue1 = new shaka.text.Cue(60, 40, 'Test');
- const cue2 = new shaka.text.Cue(40, 40, 'Test');
- displayer.append([cue1, cue2]);
- expect(mockTrack.addCue).not.toHaveBeenCalled();
- });
- });
-
- describe('destroy', () => {
- it('disables the TextTrack it created', async () => {
- // There should only be the one track created by this displayer.
- expect(video.textTracks.length).toBe(1);
-
- /** @type {!TextTrack} */
- const textTrack = video.textTracks[0];
-
- // It should not be disabled before we destroy it.
- expect(textTrack.mode).not.toBe('disabled');
-
- await displayer.destroy();
-
- // It should be disabled after we destroy it.
- expect(textTrack.mode).toBe('disabled');
- });
- });
-
- function createFakeCue(startTime, endTime) {
- return {startTime: startTime, endTime: endTime};
- }
-
- /**
- * Verifies that vttCues are converted to shakaCues and appended.
- * @param {!Array} vttCues
- * @param {!Array} shakaCues
- */
- function verifyHelper(vttCues, shakaCues) {
- mockTrack.addCue.calls.reset();
- displayer.append(shakaCues);
- const result = mockTrack.addCue.calls.allArgs().reduce(
- shaka.util.Functional.collapseArrays, []);
- expect(result).toEqual(vttCues.map((c) => jasmine.objectContaining(c)));
- }
-});
diff --git a/test/text/text_engine_unit.js b/test/text/text_engine_unit.js
index 12099ae24..493469354 100644
--- a/test/text/text_engine_unit.js
+++ b/test/text/text_engine_unit.js
@@ -22,6 +22,9 @@ describe('TextEngine', () => {
/** @type {!jasmine.Spy} */
let mockSetSequenceMode;
+ /** @type {!jasmine.Spy} */
+ let mockSetManifestType;
+
/** @type {!jasmine.Spy} */
let mockParseMedia;
@@ -31,12 +34,14 @@ describe('TextEngine', () => {
beforeEach(() => {
mockParseInit = jasmine.createSpy('mockParseInit');
mockSetSequenceMode = jasmine.createSpy('mockSetSequenceMode');
+ mockSetManifestType = jasmine.createSpy('mockSetManifestType');
mockParseMedia = jasmine.createSpy('mockParseMedia');
// eslint-disable-next-line no-restricted-syntax
mockParserPlugIn = function() {
return {
parseInit: mockParseInit,
setSequenceMode: mockSetSequenceMode,
+ setManifestType: mockSetManifestType,
parseMedia: mockParseMedia,
};
};
diff --git a/test/ui/ui_integration.js b/test/ui/ui_integration.js
index e4db4a69a..dba53e057 100644
--- a/test/ui/ui_integration.js
+++ b/test/ui/ui_integration.js
@@ -147,7 +147,10 @@ describe('UI', () => {
newLanguage = 'es';
languageMenu = shaka.util.Dom.getElementByClassName(
'shaka-audio-languages', videoContainer);
- setupLanguageTests(player.getAudioLanguagesAndRoles());
+ const audioTracks = player.getAudioTracks();
+ const uniqueLanguages =
+ [...new Set(audioTracks.map((track) => track.language))];
+ setupLanguageTests(uniqueLanguages);
});
it('contains all the languages', () => {
@@ -160,10 +163,18 @@ describe('UI', () => {
});
it('choosing language through API has effect on UI', async () => {
+ const selectAudioLanguage = (language) => {
+ const audioTracks = player.getAudioTracks();
+ const track = audioTracks.find((t) => t.language == language);
+ if (track) {
+ player.selectAudioTrack(track);
+ }
+ };
+
await verifyLanguageChangeViaAPI(
'languageselectionupdated',
() => player.getVariantTracks(),
- (language) => player.selectAudioLanguage(language));
+ (language) => selectAudioLanguage(language));
});
}); // describe('audio')
@@ -173,7 +184,10 @@ describe('UI', () => {
newLanguage = 'fr';
languageMenu = shaka.util.Dom.getElementByClassName(
'shaka-text-languages', videoContainer);
- setupLanguageTests(player.getTextLanguagesAndRoles());
+ const textTracks = player.getTextTracks();
+ const uniqueLanguages =
+ [...new Set(textTracks.map((track) => track.language))];
+ setupLanguageTests(uniqueLanguages);
});
it('contains all the languages', () => {
@@ -189,39 +203,58 @@ describe('UI', () => {
it('choosing language through API has effect on UI', async () => {
// Enable & verify the text, or else the text won't be streamed and the
// language selection won't do anything.
- await player.setTextTrackVisibility(true);
- expect(player.isTextTrackVisible()).toBe(true);
+ let textTracks = player.getTextTracks();
+ player.selectTextTrack(textTracks[0]);
+ textTracks = player.getTextTracks();
+ const activeTrack = textTracks.find((t) => t.active);
+ expect(activeTrack).toBeDefined();
+
+ const selectTextLanguage = (language) => {
+ const textTracks = player.getTextTracks();
+ const track = textTracks.find((t) => t.language == language);
+ if (track) {
+ player.selectTextTrack(track);
+ }
+ };
await verifyLanguageChangeViaAPI(
'captionselectionupdated',
() => player.getTextTracks(),
- (language) => player.selectTextLanguage(language));
+ (language) => selectTextLanguage(language));
});
it('turning captions off through UI has effect on player', async () => {
// Enable & verify the text.
- await player.setTextTrackVisibility(true);
- expect(player.isTextTrackVisible()).toBe(true);
-
+ let textTracks = player.getTextTracks();
+ player.selectTextTrack(textTracks[0]);
+ textTracks = player.getTextTracks();
+ let activeTrack = textTracks.find((t) => t.active);
+ expect(activeTrack).toBeDefined();
// Find and click the 'Off' button
getOffButton().click();
// Wait for the change to take effect
- await waiter.waitForEvent(player, 'texttrackvisibility');
+ await waiter.waitForEvent(player, 'textchanged');
- expect(player.isTextTrackVisible()).toBe(false);
+ textTracks = player.getTextTracks();
+ activeTrack = textTracks.find((t) => t.active);
+ expect(activeTrack).toBeUndefined();
});
it('turning captions off through API has effect on UI', async () => {
- // This test is invalid if the text is not initially visible, because
- // setTextTrackVisibility() does nothing if there are no changes.
- await player.setTextTrackVisibility(true);
- expect(player.isTextTrackVisible()).toBe(true);
+ // This test is invalid if the text is not initially visible.
+ let textTracks = player.getTextTracks();
+ player.selectTextTrack(textTracks[0]);
+ textTracks = player.getTextTracks();
+ let activeTrack = textTracks.find((t) => t.active);
+ expect(activeTrack).toBeDefined();
const p = waiter.waitForEvent(controls, 'captionselectionupdated');
// Disable & verify the text.
- await player.setTextTrackVisibility(false);
- expect(player.isTextTrackVisible()).toBe(false);
+ player.selectTextTrack();
+ textTracks = player.getTextTracks();
+ activeTrack = textTracks.find((t) => t.active);
+ expect(activeTrack).toBeUndefined();
// Wait for the change to take effect
await p;
@@ -244,12 +277,10 @@ describe('UI', () => {
}); // describe('caption selection')
/**
- * @param {!Array} languagesAndRoles
+ * @param {!Array} langs
*/
- function setupLanguageTests(languagesAndRoles) {
- langsFromContent = languagesAndRoles.map((langAndRole) => {
- return langAndRole.language;
- });
+ function setupLanguageTests(langs) {
+ langsFromContent = langs;
languageButtons = filterButtons(languageMenu.childNodes,
['shaka-back-to-overflow-button', 'shaka-turn-captions-off-button']);
@@ -360,8 +391,12 @@ describe('UI', () => {
const selectedLanguage =
getSelectedTrack(player.getVariantTracks()).language;
if (selectedLanguage != preferredLanguage) {
- player.selectAudioLanguage(preferredLanguage);
- await waiter.waitForEvent(player, 'variantchanged');
+ const audioTracks = player.getAudioTracks();
+ const track = audioTracks.find((t) => t.language == preferredLanguage);
+ if (track) {
+ player.selectAudioTrack(track);
+ await waiter.waitForEvent(player, 'variantchanged');
+ }
}
resolutionsMenu = shaka.util.Dom.getElementByClassName(
diff --git a/test/util/tXml_unit.js b/test/util/tXml_unit.js
index 94ab8fee8..afa51b064 100644
--- a/test/util/tXml_unit.js
+++ b/test/util/tXml_unit.js
@@ -527,31 +527,6 @@ describe('tXml', () => {
]);
});
- it('txmlNodeToDomElement', () => {
- const node = {
- tagName: 'Event',
- parent: null,
- attributes: {
- 'presentationTime': '0',
- },
- children: [
- {
- tagName: 'scte35:Signal',
- parent: null,
- attributes: {},
- children: [],
- },
- ],
- };
- node.children[0].parent = node;
-
- const element = TXml.txmlNodeToDomElement(node);
- expect(element.tagName).toBe('Event');
- expect(element.getAttribute('presentationTime')).toBe('0');
- const signal = element.firstElementChild;
- expect(signal.tagName).toBe('scte35:Signal');
- });
-
it('cloneNode', () => {
expect(TXml.cloneNode(null)).toBe(null);
const root = {
diff --git a/ui/controls.js b/ui/controls.js
index 919e20369..3342cd842 100644
--- a/ui/controls.js
+++ b/ui/controls.js
@@ -2028,7 +2028,7 @@ shaka.ui.Controls = class extends shaka.util.FakeEventTarget {
const tracks = this.player_.getTextTracks();
const hasTrack = tracks.some((track) => track.active);
if (hasTrack) {
- this.player_.selectTextTrack(null);
+ this.player_.selectTextTrack();
} else {
this.player_.selectTextTrack(this.lastSelectedTextTrack_);
}
diff --git a/ui/text_selection.js b/ui/text_selection.js
index 4ff7d6539..f016a1959 100644
--- a/ui/text_selection.js
+++ b/ui/text_selection.js
@@ -158,7 +158,7 @@ shaka.ui.TextSelection = class extends shaka.ui.SettingsMenu {
const offButton = shaka.util.Dom.createButton();
offButton.classList.add('shaka-turn-captions-off-button');
this.eventManager.listen(offButton, 'click', () => {
- this.player.selectTextTrack(null);
+ this.player.selectTextTrack();
});
offButton.appendChild(this.captionsOffSpan_);