Commit 467e7ece by Clinton Blackburn

fixup! WIP: Added Chromecast support to video XModule

parent 8267597b
......@@ -330,6 +330,231 @@ function(_) {
// Place the <video> element on the page.
this.videoEl.appendTo(el.find('.video-player > div:first-child'));
// $.getScript('https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1');
window['__onGCastApiAvailable'] = this.onGCastApiAvailable.bind(this);
};
Player.prototype.onGCastApiAvailable = function (isAvailable) {
debugger;
if (isAvailable) {
cast.framework.CastContext.getInstance().setOptions({
receiverApplicationId: chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID,
autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED
});
this.remotePlayer = new cast.framework.RemotePlayer();
this.remotePlayerController = new cast.framework.RemotePlayerController(this.remotePlayer);
this.remotePlayerController.addEventListener(
cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED,
this.switchPlayer.bind(this)
);
}
};
Player.prototype.switchPlayer = function () {
// this.stopProgressTimer();
// this.resetVolumeSlider();
// this.playerHandler.stop();
// this.playerState = PLAYER_STATE.IDLE;
if (cast && cast.framework) {
if (this.remotePlayer.isConnected) {
this.setupRemotePlayer();
return;
}
}
this.setupLocalPlayer();
};
/**
* Makes human-readable message from chrome.cast.Error
* @param {chrome.cast.Error} error
* @return {string} error message
*/
Player.getErrorMessage = function (error) {
switch (error.code) {
case chrome.cast.ErrorCode.API_NOT_INITIALIZED:
return 'The API is not initialized.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.CANCEL:
return 'The operation was canceled by the user' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.CHANNEL_ERROR:
return 'A channel to the receiver is not available.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.EXTENSION_MISSING:
return 'The Cast extension is not available.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.INVALID_PARAMETER:
return 'The parameters to the operation were not valid.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.RECEIVER_UNAVAILABLE:
return 'No receiver was compatible with the session request.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.SESSION_ERROR:
return 'A session could not be created, or a session was invalid.' +
(error.description ? ' :' + error.description : '');
case chrome.cast.ErrorCode.TIMEOUT:
return 'The operation timed out.' +
(error.description ? ' :' + error.description : '');
}
};
Player.prototype.setupRemotePlayer = function () {
var castSession = cast.framework.CastContext.getInstance().getCurrentSession();
// Add event listeners for player changes which may occur outside sender app
this.remotePlayerController.addEventListener(
cast.framework.RemotePlayerEventType.IS_PAUSED_CHANGED,
function () {
if (this.remotePlayer.isPaused) {
this.onPause();
} else {
this.onPlay();
}
}.bind(this)
);
// this.remotePlayerController.addEventListener(
// cast.framework.RemotePlayerEventType.IS_MUTED_CHANGED,
// function () {
// if (this.remotePlayer.isMuted) {
// this.playerHandler.mute();
// } else {
// this.playerHandler.unMute();
// }
// }.bind(this)
// );
//
// this.remotePlayerController.addEventListener(
// cast.framework.RemotePlayerEventType.VOLUME_LEVEL_CHANGED,
// function () {
// var newVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
// var p = document.getElementById('audio_bg_level');
// p.style.height = newVolume + 'px';
// p.style.marginTop = -newVolume + 'px';
// }.bind(this)
// );
// This object will implement PlayerHandler callbacks with
// remotePlayerController, and makes necessary UI updates specific
// to remote playback
var playerTarget = {};
playerTarget.play = function () {
if (this.remotePlayer.isPaused) {
this.remotePlayerController.playOrPause();
}
var vi = document.getElementById('video_image');
vi.style.display = 'block';
var localPlayer = document.getElementById('video_element');
localPlayer.style.display = 'none';
}.bind(this);
playerTarget.pause = function () {
if (!this.remotePlayer.isPaused) {
this.remotePlayerController.playOrPause();
}
}.bind(this);
playerTarget.stop = function () {
this.remotePlayerController.stop();
}.bind(this);
playerTarget.load = function (mediaIndex) {
console.log('Loading...' + this.mediaContents[mediaIndex]['title']);
var mediaInfo = new chrome.cast.media.MediaInfo(this.config.videoSources[0], 'video/mp4');
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata();
mediaInfo.metadata.metadataType = chrome.cast.media.MetadataType.GENERIC;
// mediaInfo.metadata.title = this.mediaContents[mediaIndex]['title'];
// mediaInfo.metadata.images = [
// {'url': MEDIA_SOURCE_ROOT + this.mediaContents[mediaIndex]['thumb']}];
var request = new chrome.cast.media.LoadRequest(mediaInfo);
castSession.loadMedia(request).then(
this.playerHandler.loaded.bind(this.playerHandler),
function (errorCode) {
this.playerState = PLAYER_STATE.ERROR;
console.log('Remote media load error: ' +
Player.getErrorMessage(errorCode));
}.bind(this));
}.bind(this);
playerTarget.getCurrentMediaTime = function () {
return this.remotePlayer.currentTime;
}.bind(this);
playerTarget.getMediaDuration = function () {
return this.remotePlayer.duration;
}.bind(this);
playerTarget.updateDisplayMessage = function () {
document.getElementById('playerstate').style.display = 'block';
document.getElementById('playerstatebg').style.display = 'block';
document.getElementById('video_image_overlay').style.display = 'block';
document.getElementById('playerstate').innerHTML =
this.mediaContents[this.currentMediaIndex]['title'] + ' ' +
this.playerState + ' on ' + castSession.getCastDevice().friendlyName;
}.bind(this);
playerTarget.setVolume = function (volumeSliderPosition) {
// Add resistance to avoid loud volume
var currentVolume = this.remotePlayer.volumeLevel;
var p = document.getElementById('audio_bg_level');
if (volumeSliderPosition < FULL_VOLUME_HEIGHT) {
var vScale = this.currentVolume * FULL_VOLUME_HEIGHT;
if (volumeSliderPosition > vScale) {
volumeSliderPosition = vScale + (pos - vScale) / 2;
}
p.style.height = volumeSliderPosition + 'px';
p.style.marginTop = -volumeSliderPosition + 'px';
currentVolume = volumeSliderPosition / FULL_VOLUME_HEIGHT;
} else {
currentVolume = 1;
}
this.remotePlayer.volumeLevel = currentVolume;
this.remotePlayerController.setVolumeLevel();
}.bind(this);
playerTarget.mute = function () {
if (!this.remotePlayer.isMuted) {
this.remotePlayerController.muteOrUnmute();
}
}.bind(this);
playerTarget.unMute = function () {
if (this.remotePlayer.isMuted) {
this.remotePlayerController.muteOrUnmute();
}
}.bind(this);
playerTarget.isMuted = function () {
return this.remotePlayer.isMuted;
}.bind(this);
playerTarget.seekTo = function (time) {
this.remotePlayer.currentTime = time;
this.remotePlayerController.seek();
}.bind(this);
this.playerHandler.setTarget(playerTarget);
// Setup remote player volume right on setup
// The remote player may have had a volume set from previous playback
if (this.remotePlayer.isMuted) {
this.playerHandler.mute();
}
var currentVolume = this.remotePlayer.volumeLevel * FULL_VOLUME_HEIGHT;
var p = document.getElementById('audio_bg_level');
p.style.height = currentVolume + 'px';
p.style.marginTop = -currentVolume + 'px';
this.hideFullscreenButton();
this.playerHandler.play();
};
return Player;
......
......@@ -17,6 +17,8 @@ from openedx.core.djangolib.js_utils import js_escaped_string
tabindex="-1"
>
<div class="focus_grabber first"></div>
<!-- TODO Integrate into video player UI -->
<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
<button is="google-cast-button"></button>
<div class="tc-wrapper">
<div class="video-wrapper">
......@@ -87,46 +89,6 @@ from openedx.core.djangolib.js_utils import js_escaped_string
% endif
</div>
<!-- BEGIN Chromecast -->
<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
<script>
window['__onGCastApiAvailable'] = function (isAvailable) {
initializeCastApi = function () {
cast.framework.CastContext.getInstance().setOptions({
receiverApplicationId: chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID,
autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED
});
};
if (isAvailable) {
initializeCastApi();
$('button.video_control.play').on('click', function () {
var castSession = cast.framework.CastContext.getInstance().getCurrentSession();
var mediaInfo = new chrome.cast.media.MediaInfo('https://d2f1egay8yehza.cloudfront.net/BERGG101/BERGG101T314-V011300_DTH.mp4', 'video/mp4t');
var request = new chrome.cast.media.LoadRequest(mediaInfo);
castSession.loadMedia(request).then(
function () {
console.log('Load succeed');
},
function (errorCode) {
console.log('Error code: ' + errorCode);
});
});
/*var castSession = cast.framework.CastContext.getInstance().getCurrentSession();
var mediaInfo = new chrome.cast.media.MediaInfo('CCxmtcICYNc', 'yt');
var request = new chrome.cast.media.LoadRequest(mediaInfo);
castSession.loadMedia(request).then(
function () {
console.log('Load succeed');
},
function (errorCode) {
console.log('Error code: ' + errorCode);
});*/
}
};
</script>
<!-- END Chromecast -->
% if cdn_eval:
<script>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment