mirror of
https://github.com/shaka-project/shaka-player.git
synced 2026-06-20 16:57:25 +03:00
5eb9310d3a
Change-Id: Iae1f129d9f02ff47f09d9aacd60fb9a80ff8459c
297 lines
7.2 KiB
JavaScript
297 lines
7.2 KiB
JavaScript
/**
|
|
* @license
|
|
* Copyright 2015 Google Inc.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by receiverApplicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
|
|
/**
|
|
* Implements the receiverApplication layer of the receiver.
|
|
* @class
|
|
*/
|
|
var receiverApp = function() {};
|
|
|
|
|
|
/**
|
|
* The video element owned by the receiverApp.
|
|
*
|
|
* @private {HTMLVideoElement}
|
|
*/
|
|
receiverApp.video_ = null;
|
|
|
|
|
|
/**
|
|
* The video resolution debug element owned by the receiverApp.
|
|
*
|
|
* @private {?string}
|
|
*/
|
|
receiverApp.videoResDebug_ = null;
|
|
|
|
|
|
/**
|
|
* The buffered ahead debug element owned by the receiverApp.
|
|
*
|
|
* @private {?string}
|
|
*/
|
|
receiverApp.bufferedAheadDebug_ = null;
|
|
|
|
|
|
/**
|
|
* The buffered behind debug element owned by the receiverApp.
|
|
*
|
|
* @private {?string}
|
|
*/
|
|
receiverApp.bufferedBehindDebug_ = null;
|
|
|
|
|
|
/**
|
|
* The player object owned by the receiverApp.
|
|
*
|
|
* @private {shaka.player.Player}
|
|
*/
|
|
receiverApp.player_ = null;
|
|
|
|
|
|
/**
|
|
* The receiverApp's bandwidth estimator, which will persist across playbacks.
|
|
* This will allow second and subsequent playbacks to benefit from earlier
|
|
* bandwidth estimations and avoid starting at a low-quality stream.
|
|
*
|
|
* @private {shaka.util.IBandwidthEstimator}
|
|
*/
|
|
receiverApp.estimator_ = null;
|
|
|
|
|
|
/**
|
|
* The current video configuration.
|
|
*/
|
|
receiverApp.config = {
|
|
'forcePrefixed' : false,
|
|
'preferredLanguage': 'en-US',
|
|
'wvLicenseServerUrlInput' : null
|
|
};
|
|
|
|
|
|
/**
|
|
* Initializes the receiverApplication.
|
|
*/
|
|
receiverApp.init = function() {
|
|
receiverApp.video_ =
|
|
/** @type {!HTMLVideoElement} */ (document.getElementById('video'));
|
|
|
|
window.setInterval(receiverApp.updateDebugInfo_, 50);
|
|
|
|
receiver.initialize();
|
|
|
|
// current time updates
|
|
receiverApp.video_.addEventListener('timeupdate', function() {
|
|
receiver.broadcast('currentTime', receiverApp.video_.currentTime);
|
|
var buffered = receiverApp.video_.buffered;
|
|
receiver.broadcast('buffered', {
|
|
'length': buffered.length,
|
|
'start': buffered.start(0),
|
|
'end': buffered.end(0)
|
|
});
|
|
});
|
|
receiverApp.video_.addEventListener('playing', function() {
|
|
receiverApp.onBuffering(false);
|
|
receiver.broadcast('playing', receiverApp.video_.duration);
|
|
receiver.cancelIdleTimeout();
|
|
});
|
|
receiverApp.video_.addEventListener('pause', function() {
|
|
receiver.broadcast('paused', null);
|
|
receiver.setIdleTimeout(receiver.IDLE_TIMEOUT_);
|
|
});
|
|
receiverApp.video_.addEventListener('volumechange', function() {
|
|
receiver.broadcast('volume', {
|
|
'volume': receiverApp.video_.volume,
|
|
'muted': receiverApp.video_.muted
|
|
});
|
|
});
|
|
receiverApp.video_.addEventListener('ended', function() {
|
|
receiver.setIdleTimeout(receiver.IDLE_TIMEOUT_);
|
|
});
|
|
};
|
|
|
|
|
|
/**
|
|
* Loads a dash stream.
|
|
* @param {appUtils.StreamState} streamInfo
|
|
*/
|
|
receiverApp.loadDashStream = function(streamInfo) {
|
|
receiverApp.onBuffering(true);
|
|
if (!receiverApp.player_) {
|
|
receiverApp.installPolyfills_();
|
|
receiverApp.initPlayer_();
|
|
}
|
|
|
|
console.assert(receiverApp.estimator_);
|
|
if (receiverApp.estimator_.getDataAge() >= 3600) {
|
|
// Disregard any bandwidth data older than one hour. The user may have
|
|
// changed networks if they are on a laptop or mobile device.
|
|
receiverApp.estimator_ = new shaka.util.EWMABandwidthEstimator();
|
|
}
|
|
|
|
var estimator = /** @type {!shaka.util.IBandwidthEstimator} */(
|
|
receiverApp.estimator_);
|
|
var abrManager = new shaka.media.SimpleAbrManager();
|
|
receiverApp.load_(
|
|
new shaka.player.DashVideoSource(
|
|
streamInfo.manifest,
|
|
appUtils.interpretContentProtection.bind(
|
|
null,
|
|
receiverApp.player_,
|
|
receiverApp.config.wvLicenseServerUrlInput),
|
|
estimator,
|
|
abrManager), streamInfo.time);
|
|
};
|
|
|
|
|
|
/**
|
|
* Plays the video.
|
|
*/
|
|
receiverApp.play = function() {
|
|
receiverApp.video_.play();
|
|
};
|
|
|
|
|
|
/**
|
|
* Pauses the video.
|
|
*/
|
|
receiverApp.pause = function() {
|
|
receiverApp.video_.pause();
|
|
};
|
|
|
|
|
|
/**
|
|
* Sets the current time of the video.
|
|
* @param {number} time
|
|
*/
|
|
receiverApp.setCurrentTime = function(time) {
|
|
receiverApp.video_.currentTime = time;
|
|
};
|
|
|
|
|
|
/**
|
|
* Updates the buffering display.
|
|
* @param {boolean} buffering True if the video is buffering.
|
|
*/
|
|
receiverApp.onBuffering = function(buffering) {
|
|
var bufferingSpinner = document.getElementById('bufferingSpinner');
|
|
bufferingSpinner.style.display = buffering ? 'inherit' : 'none';
|
|
};
|
|
|
|
|
|
/**
|
|
* Sets the current volume of the video.
|
|
* @param {number} volume
|
|
*/
|
|
receiverApp.setVolume = function(volume) {
|
|
receiverApp.video_.volume = volume;
|
|
};
|
|
|
|
|
|
/**
|
|
* Mutes the video.
|
|
* @param {boolean} mute
|
|
*/
|
|
receiverApp.mute = function(mute) {
|
|
receiverApp.video_.muted = mute;
|
|
};
|
|
|
|
|
|
/**
|
|
* Loads the given video source into the player.
|
|
* @param {!shaka.player.IVideoSource} videoSource
|
|
* @param {number} time The time the video should start at.
|
|
* @private
|
|
*/
|
|
receiverApp.load_ = function(videoSource, time) {
|
|
console.assert(receiverApp.player_ != null);
|
|
|
|
receiverApp.player_.configure(
|
|
{'preferredLanguage': receiverApp.config.preferredLanguage});
|
|
receiverApp.player_.setPlaybackStartTime(time);
|
|
|
|
// Error already handled through error event.
|
|
receiverApp.player_.load(videoSource).catch(function() {});
|
|
};
|
|
|
|
|
|
/**
|
|
* Update the debug information.
|
|
* @private
|
|
*/
|
|
receiverApp.updateDebugInfo_ = function() {
|
|
var debugMsg = appUtils.getVideoResDebug(receiverApp.video_);
|
|
var bufferInfo = appUtils.getBufferDebug(receiverApp.video_);
|
|
var debugInfo = {
|
|
'videoResDebug': debugMsg,
|
|
'bufferedAheadDebug': bufferInfo[0],
|
|
'bufferedBehindDebug': bufferInfo[1]
|
|
};
|
|
receiver.broadcast('debugInfo', debugInfo);
|
|
};
|
|
|
|
|
|
/**
|
|
* Installs the polyfills if the have not yet been installed.
|
|
* @private
|
|
*/
|
|
receiverApp.installPolyfills_ = function() {
|
|
appUtils.installPolyfills(receiverApp.config.forcePrefixed);
|
|
};
|
|
|
|
|
|
/**
|
|
* Initializes the Player instance.
|
|
* If the Player instance already exists then it is reinitialized.
|
|
* @private
|
|
*/
|
|
receiverApp.initPlayer_ = function() {
|
|
console.assert(receiverApp.player_ == null);
|
|
if (receiverApp.player_) {
|
|
return;
|
|
}
|
|
|
|
receiverApp.player_ = new shaka.player.Player(
|
|
/** @type {!HTMLVideoElement} */ (receiverApp.video_));
|
|
receiverApp.player_.addEventListener('error', receiverApp.onPlayerError_);
|
|
|
|
receiverApp.estimator_ = new shaka.util.EWMABandwidthEstimator();
|
|
};
|
|
|
|
|
|
/**
|
|
* Called when the player generates an error.
|
|
* @param {!Event} event
|
|
* @private
|
|
*/
|
|
receiverApp.onPlayerError_ = function(event) {
|
|
console.error('Player error', event);
|
|
receiverApp.player_.unload();
|
|
receiverApp.player_ = null;
|
|
receiverApp.onBuffering(false);
|
|
receiver.broadcast('error', event.detail.name + ': ' + event.detail.message);
|
|
receiver.setIdleTimeout(receiver.IDLE_TIMEOUT_);
|
|
};
|
|
|
|
|
|
if (document.readyState == 'complete' ||
|
|
document.readyState == 'interactive') {
|
|
receiverApp.init();
|
|
} else {
|
|
document.addEventListener('DOMContentLoaded', receiverApp.init);
|
|
}
|