mirror of
https://github.com/tubearchivist/tubearchivist-frontend.git
synced 2024-12-28 21:00:11 +00:00
Improved Cast Support (#143)
* Added cast integration requirements. HTTPS and a supported browser are required for this integration. * Improved cast handeling. * Theme cast button. * Improved cast support. * Added proper cast button. * Moved cast button location * Moved button location * Reorder cast button * Fix typo * Revert cast setting description. * Match master branch * Added comments * Added id `cast-script` to cast-videos.js * Reworked event listener * Add cast button to home player * Check if active media on cast, pause browser video * Commented out console logging * Uncommented cast failed console log * Cast video at current playback position * use theme vars for cast color buttons * add cast variable to base ArchivistViewConfig class Co-authored-by: simon <simobilleter@gmail.com>
This commit is contained in:
parent
c703105c5e
commit
b7922d171d
@ -29,15 +29,8 @@
|
||||
{% endif %}
|
||||
<script type="text/javascript" src="{% static 'script.js' %}"></script>
|
||||
{% if cast %}
|
||||
<script src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
|
||||
<script>
|
||||
window['__onGCastApiAvailable'] = function(isAvailable) {
|
||||
if (isAvailable) {
|
||||
initializeCastApi();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<script type="text/javascript" src="{% static 'cast-videos.js' %}"></script>
|
||||
<script type="text/javascript" src="https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1"></script>
|
||||
<script id="cast-script" type="text/javascript" src="{% static 'cast-videos.js' %}"></script>
|
||||
{% endif %}
|
||||
</head>
|
||||
<body>
|
||||
|
@ -107,8 +107,8 @@
|
||||
{{ app_form.downloads_integrate_ryd }}
|
||||
</div>
|
||||
<div class="settings-item">
|
||||
<p><span class="danger-zone">Untested!</span> Current Cast integration: <span class="settings-current">{{ config.application.enable_cast }}</span></p>
|
||||
<i>Enabling Cast will load an additional JS library from google.</i><br>
|
||||
<p>Current Cast integration: <span class="settings-current">{{ config.application.enable_cast }}</span></p>
|
||||
<i>Enabling Cast will load an additional JS library from Google. HTTPS and a supported browser are required for this integration.</i><br>
|
||||
{{ app_form.application_enable_cast }}
|
||||
</div>
|
||||
</div>
|
||||
@ -293,4 +293,4 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
<script type="text/javascript" src="{% static 'progress.js' %}"></script>
|
||||
{% endblock content %}
|
||||
{% endblock content %}
|
||||
|
@ -11,11 +11,10 @@
|
||||
</div>
|
||||
<div class="boxed-content">
|
||||
<div class="title-bar">
|
||||
<h1>{{ video.title }}</h1>
|
||||
{% if cast %}
|
||||
<button onclick="startCast()">Start Cast</button>
|
||||
<button onclick="stopCast()">Stop Cast</button>
|
||||
<google-cast-launcher id="castbutton"></google-cast-launcher>
|
||||
{% endif %}
|
||||
<h1 id="video-title">{{ video.title }}</h1>
|
||||
</div>
|
||||
<div class="info-box info-box-3">
|
||||
<div class="info-box-item">
|
||||
|
@ -111,6 +111,7 @@ class ArchivistViewConfig(View):
|
||||
|
||||
self.context = {
|
||||
"colors": self.default_conf["application"]["colors"],
|
||||
"cast": self.default_conf["application"]["enable_cast"],
|
||||
"sort_by": self._get_sort_by(),
|
||||
"sort_order": self._get_sort_order(),
|
||||
"view_style": self._get_view_style(),
|
||||
|
@ -1,91 +1,82 @@
|
||||
var session = null;
|
||||
|
||||
function initializeCastApi() {
|
||||
var applicationID = chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID;
|
||||
var sessionRequest = new chrome.cast.SessionRequest(applicationID);
|
||||
var apiConfig = new chrome.cast.ApiConfig(sessionRequest,
|
||||
sessionListener,
|
||||
receiverListener);
|
||||
chrome.cast.initialize(apiConfig, onInitSuccess, onInitError);
|
||||
};
|
||||
cast.framework.CastContext.getInstance().setOptions({
|
||||
receiverApplicationId: chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID, // Use built in reciver app on cast device, see https://developers.google.com/cast/docs/styled_receiver if you want to be able to add a theme, splash screen or watermark. Has a $5 one time fee.
|
||||
autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED
|
||||
});
|
||||
|
||||
function sessionListener(e) {
|
||||
session = e;
|
||||
console.log('New session');
|
||||
if (session.media.length != 0) {
|
||||
console.log('Found ' + session.media.length + ' sessions.');
|
||||
}
|
||||
}
|
||||
|
||||
function receiverListener(e) {
|
||||
if( e === 'available' ) {
|
||||
console.log("Chromecast was found on the network.");
|
||||
}
|
||||
else {
|
||||
console.log("There are no Chromecasts available.");
|
||||
var player = new cast.framework.RemotePlayer();
|
||||
var playerController = new cast.framework.RemotePlayerController(player);
|
||||
|
||||
// Add event listerner to check if a connection to a cast device is initiated
|
||||
playerController.addEventListener(
|
||||
cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED, function() {
|
||||
castConnectionChange(player)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function onInitSuccess() {
|
||||
console.log("Initialization succeeded");
|
||||
|
||||
function castConnectionChange(player) {
|
||||
// If cast connection is initialized start cast
|
||||
if (player.isConnected) {
|
||||
// console.log("Cast Connected.");
|
||||
castStart();
|
||||
} else if (!player.isConnected) {
|
||||
// console.log("Cast Disconnected.");
|
||||
}
|
||||
}
|
||||
|
||||
function onInitError() {
|
||||
console.log("Initialization failed");
|
||||
function castStart() {
|
||||
var castSession = cast.framework.CastContext.getInstance().getCurrentSession();
|
||||
|
||||
// Check if there is already media playing on the cast target to prevent recasting on page reload or switching to another video page
|
||||
if (!castSession.getMediaSession()) {
|
||||
contentId = document.getElementById("video-item").src; // Get video URL
|
||||
contentTitle = document.getElementById('video-title').innerHTML; // Get video title
|
||||
contentImage = document.getElementById("video-item").poster; // Get video thumbnail URL
|
||||
contentType = 'video/mp4'; // Set content type, only videos right now so it is hard coded
|
||||
contentCurrentTime = document.getElementById("video-item").currentTime; // Get video's current position
|
||||
|
||||
mediaInfo = new chrome.cast.media.MediaInfo(contentId, contentType); // Create MediaInfo var that contains url and content type
|
||||
// mediaInfo.streamType = chrome.cast.media.StreamType.BUFFERED; // Set type of stream, BUFFERED, LIVE, OTHER
|
||||
mediaInfo.metadata = new chrome.cast.media.GenericMediaMetadata(); // Create metadata var and add it to MediaInfo
|
||||
mediaInfo.metadata.title = contentTitle; // Set the video title
|
||||
mediaInfo.metadata.images = [new chrome.cast.Image(contentImage)]; // Set the video thumbnail
|
||||
|
||||
var request = new chrome.cast.media.LoadRequest(mediaInfo); // Create request with the previously set MediaInfo.
|
||||
// request.queueData = new chrome.cast.media.QueueData(); // See https://developers.google.com/cast/docs/reference/web_sender/chrome.cast.media.QueueData for playlist support.
|
||||
request.currentTime = shiftCurrentTime(contentCurrentTime); // Set video start position based on the browser video position
|
||||
// request.autoplay = false; // Set content to auto play, true by default
|
||||
castSession.loadMedia(request).then(
|
||||
function() {
|
||||
castSuccessful();
|
||||
},
|
||||
function() {
|
||||
castFailed(errorCode);
|
||||
}
|
||||
); // Send request to cast device
|
||||
}
|
||||
}
|
||||
|
||||
function startCast() {
|
||||
console.log("Starting cast...");
|
||||
chrome.cast.requestSession(onRequestSessionSuccess, onLaunchError);
|
||||
function shiftCurrentTime(contentCurrentTime) { // Shift media back 3 seconds to prevent missing some of the content
|
||||
if (contentCurrentTime > 5) {
|
||||
return(contentCurrentTime - 3);
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
function onRequestSessionSuccess(e) {
|
||||
console.log("Successfully created session: " + e.sessionId);
|
||||
session = e;
|
||||
function castSuccessful() {
|
||||
// console.log('Cast Successful.');
|
||||
document.getElementById("video-item").pause(); // Pause browser video on successful cast
|
||||
}
|
||||
|
||||
function onLaunchError() {
|
||||
console.log("Error connecting to the Chromecast.");
|
||||
function castFailed(errorCode) {
|
||||
console.log('Error code: ' + errorCode);
|
||||
}
|
||||
|
||||
function onRequestSessionSuccess(e) {
|
||||
console.log("Successfully created session: " + e.sessionId);
|
||||
session = e;
|
||||
loadMedia();
|
||||
}
|
||||
|
||||
function loadMedia() {
|
||||
if (!session) {
|
||||
console.log("No session.");
|
||||
return;
|
||||
}
|
||||
|
||||
var videoSrc = document.getElementById("video-item").src;
|
||||
var mediaInfo = new chrome.cast.media.MediaInfo(videoSrc);
|
||||
mediaInfo.contentType = 'video/mp4';
|
||||
|
||||
var request = new chrome.cast.media.LoadRequest(mediaInfo);
|
||||
request.autoplay = true;
|
||||
|
||||
session.loadMedia(request, onLoadSuccess, onLoadError);
|
||||
}
|
||||
|
||||
function onLoadSuccess() {
|
||||
console.log('Successfully loaded video.');
|
||||
}
|
||||
|
||||
function onLoadError() {
|
||||
console.log('Failed to load video.');
|
||||
}
|
||||
|
||||
function stopCast() {
|
||||
session.stop(onStopCastSuccess, onStopCastError);
|
||||
}
|
||||
|
||||
function onStopCastSuccess() {
|
||||
console.log('Successfully stopped casting.');
|
||||
}
|
||||
|
||||
function onStopCastError() {
|
||||
console.log('Error stopping cast.');
|
||||
window['__onGCastApiAvailable'] = function(isAvailable) {
|
||||
if (isAvailable) {
|
||||
initializeCastApi();
|
||||
}
|
||||
}
|
||||
|
@ -267,6 +267,14 @@ button:hover {
|
||||
filter: var(--img-filter);
|
||||
}
|
||||
|
||||
#castbutton {
|
||||
float: right;
|
||||
width: 40px;
|
||||
padding: 0 5px;
|
||||
--disconnected-color: var(--accent-font-dark);
|
||||
--connected-color: var(--accent-font-light);
|
||||
}
|
||||
|
||||
/* top of page */
|
||||
.title-bar {
|
||||
padding-top: 30px;
|
||||
|
@ -309,6 +309,7 @@ function createPlayer(button) {
|
||||
videoPlayer.setAttribute('width', '100%');
|
||||
videoPlayer.setAttribute('playsinline', true);
|
||||
videoPlayer.setAttribute('poster', mediaThumb);
|
||||
videoPlayer.setAttribute('id', 'video-item'); // Set ID to get URL for casting
|
||||
playerElement.appendChild(videoPlayer);
|
||||
// title bar
|
||||
var titleBar = document.createElement('div');
|
||||
@ -335,7 +336,14 @@ function createPlayer(button) {
|
||||
var videoTitleLink = document.createElement('a');
|
||||
videoTitleLink.setAttribute('href', '/video/' + dataId + '/');
|
||||
var videoTitle = document.createElement('h2');
|
||||
videoTitle.setAttribute('id', "video-title"); // Set ID to get title for casting
|
||||
videoTitle.innerText = mediaTitle;
|
||||
var castScript = document.getElementById('cast-script'); // Get cast-script
|
||||
if(typeof(castScript) != 'undefined' && castScript != null) { // Check if cast integration is enabled
|
||||
var castButton = document.createElement("google-cast-launcher"); // Create cast button
|
||||
castButton.setAttribute('id', "castbutton"); // Set ID to apply theme
|
||||
titleBar.appendChild(castButton); // Add cast button to title
|
||||
}
|
||||
videoTitleLink.appendChild(videoTitle);
|
||||
titleBar.appendChild(videoTitleLink);
|
||||
// add titlebar
|
||||
|
Loading…
Reference in New Issue
Block a user