mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Cast updates
This commit is contained in:
parent
32c1badcd9
commit
a500f154d8
4 changed files with 176 additions and 69 deletions
|
@ -139,7 +139,7 @@
|
|||
text-align: left;
|
||||
margin-left: 0;
|
||||
right: 0;
|
||||
bottom: 83px;
|
||||
bottom: 85px;
|
||||
}
|
||||
|
||||
/* Media queries
|
||||
|
@ -259,7 +259,7 @@
|
|||
}
|
||||
|
||||
#mediaPlayer #videoControls .mediaPlayerFlyout {
|
||||
bottom: 148px;
|
||||
bottom: 150px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,17 @@
|
|||
|
||||
this.hasReceivers = false;
|
||||
|
||||
this.currentMediaOffset = 0;
|
||||
|
||||
// Progress bar element id
|
||||
this.progressBar = "positionSlider";
|
||||
|
||||
// Timec display element id
|
||||
this.duration = "currentTime";
|
||||
|
||||
// Playback display element id
|
||||
this.playback = "playTime";
|
||||
|
||||
this.initializeCastPlayer();
|
||||
};
|
||||
|
||||
|
@ -617,6 +628,8 @@
|
|||
return;
|
||||
}
|
||||
|
||||
this.currentMediaOffset = startTimeTicks;
|
||||
|
||||
var maxBitrate = 12000000;
|
||||
var mediaInfo = getMediaSourceInfo(user, item, maxBitrate, mediaSourceId, audioStreamIndex, subtitleStreamIndex);
|
||||
|
||||
|
@ -653,40 +666,62 @@
|
|||
|
||||
console.log("chromecast new media session ID:" + mediaSession.mediaSessionId + ' (' + how + ')');
|
||||
this.currentMediaSession = mediaSession;
|
||||
this.currentMediaTime = this.session.media[0].currentTime;
|
||||
|
||||
if (how == 'loadMedia') {
|
||||
this.castPlayerState = PLAYER_STATE.PLAYING;
|
||||
clearInterval(this.timer);
|
||||
this.startProgressTimer(this.incrementMediaTime);
|
||||
}
|
||||
|
||||
if (how == 'activeSession') {
|
||||
this.castPlayerState = this.session.media[0].playerState;
|
||||
this.currentMediaTime = this.session.media[0].currentTime;
|
||||
}
|
||||
|
||||
if (this.castPlayerState == PLAYER_STATE.PLAYING) {
|
||||
// start progress timer
|
||||
//this.startProgressTimer(this.incrementMediaTime);
|
||||
this.startProgressTimer(this.incrementMediaTime);
|
||||
}
|
||||
|
||||
this.currentMediaSession.addUpdateListener(this.onMediaStatusUpdate.bind(this));
|
||||
this.currentMediaDuration = this.currentMediaSession.media.duration;
|
||||
|
||||
//this.currentMediaDuration = this.currentMediaSession.media.duration;
|
||||
//var duration = this.currentMediaDuration;
|
||||
//var hr = parseInt(duration / 3600);
|
||||
//duration -= hr * 3600;
|
||||
//var min = parseInt(duration / 60);
|
||||
//var sec = parseInt(duration % 60);
|
||||
//if (hr > 0) {
|
||||
// duration = hr + ":" + min + ":" + sec;
|
||||
//}
|
||||
//else {
|
||||
// if (min > 0) {
|
||||
// duration = min + ":" + sec;
|
||||
// }
|
||||
// else {
|
||||
// duration = sec;
|
||||
// }
|
||||
//}
|
||||
//document.getElementById("duration").innerHTML = duration;
|
||||
var playTime = document.getElementById(this.playback);
|
||||
if (!playTime) {
|
||||
// Set duration time
|
||||
var totalTime = document.getElementById(this.duration);
|
||||
totalTime.innerHTML = " / " + formatTime(this.currentMediaDuration);
|
||||
|
||||
// Set play time
|
||||
playTime = document.createElement("div");
|
||||
playTime.id = this.playback;
|
||||
playTime.className = "currentTime";
|
||||
playTime.style.marginRight = "5px";
|
||||
totalTime.parentNode.insertBefore(playTime, totalTime);
|
||||
playTime.innerHTML = formatTime(this.currentMediaTime);
|
||||
}
|
||||
};
|
||||
|
||||
function formatTime(duration) {
|
||||
var hr = parseInt(duration / 3600);
|
||||
duration -= hr * 3600;
|
||||
var min = parseInt(duration / 60);
|
||||
var sec = parseInt(duration % 60);
|
||||
|
||||
hr = "" + hr;
|
||||
min = "" + min;
|
||||
sec = "" + sec;
|
||||
var hh = pad(hr);
|
||||
var mm = pad(min);
|
||||
var ss = pad(sec);
|
||||
|
||||
duration = hh + ":" + mm + ":" + ss;
|
||||
|
||||
return duration;
|
||||
};
|
||||
|
||||
function pad(s) {
|
||||
return "00".substring(0, 2 - s.length) + s;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -707,7 +742,7 @@
|
|||
this.castPlayerState = PLAYER_STATE.IDLE;
|
||||
}
|
||||
console.log("chromecast updating media");
|
||||
//this.updateProgressBar(e);
|
||||
this.updateProgressBarByTimer();
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -745,6 +780,7 @@
|
|||
this.currentMediaSession.addUpdateListener(this.onMediaStatusUpdate.bind(this));
|
||||
this.castPlayerState = PLAYER_STATE.PLAYING;
|
||||
// start progress timer
|
||||
clearInterval(this.timer);
|
||||
this.startProgressTimer(this.incrementMediaTime);
|
||||
break;
|
||||
case PLAYER_STATE.IDLE:
|
||||
|
@ -850,18 +886,9 @@
|
|||
*/
|
||||
CastPlayer.prototype.seekMedia = function (event) {
|
||||
var pos = parseInt(event.offsetX);
|
||||
var pi = document.getElementById("progress_indicator");
|
||||
var p = document.getElementById("progress");
|
||||
if (event.currentTarget.id == 'progress_indicator') {
|
||||
var curr = parseInt(this.currentMediaTime + this.currentMediaDuration * pos / PROGRESS_BAR_WIDTH);
|
||||
var pp = parseInt(pi.style.marginLeft) + pos;
|
||||
var pw = parseInt(p.style.width) + pos;
|
||||
}
|
||||
else {
|
||||
var curr = parseInt(pos * this.currentMediaDuration / PROGRESS_BAR_WIDTH);
|
||||
var pp = pos - 21 - PROGRESS_BAR_WIDTH;
|
||||
var pw = pos;
|
||||
}
|
||||
var p = document.getElementById(this.progressBar);
|
||||
var curr = parseInt(this.currentMediaTime + this.currentMediaDuration * pos);
|
||||
var pw = parseInt(p.value) + pos;
|
||||
|
||||
if (this.castPlayerState != PLAYER_STATE.PLAYING && this.castPlayerState != PLAYER_STATE.PAUSED) {
|
||||
return;
|
||||
|
@ -899,20 +926,16 @@
|
|||
* @param {Object} e An media status update object
|
||||
*/
|
||||
CastPlayer.prototype.updateProgressBar = function (e) {
|
||||
var p = document.getElementById("progress");
|
||||
var pi = document.getElementById("progress_indicator");
|
||||
var p = document.getElementById(this.progressBar);
|
||||
if (e.idleReason == 'FINISHED' && e.playerState == 'IDLE') {
|
||||
p.style.width = '0px';
|
||||
pi.style.marginLeft = -21 - PROGRESS_BAR_WIDTH + 'px';
|
||||
p.value = 0;
|
||||
clearInterval(this.timer);
|
||||
this.castPlayerState = PLAYER_STATE.STOPPED;
|
||||
}
|
||||
else {
|
||||
p.style.width = Math.ceil(PROGRESS_BAR_WIDTH * e.currentTime / this.currentMediaSession.media.duration + 1) + 'px';
|
||||
p.value = Number(e.currentTime / this.currentMediaSession.media.duration + 1).toFixed(3);
|
||||
this.progressFlag = false;
|
||||
setTimeout(this.setProgressFlag.bind(this), 1000); // don't update progress in 1 second
|
||||
var pp = Math.ceil(PROGRESS_BAR_WIDTH * e.currentTime / this.currentMediaSession.media.duration);
|
||||
pi.style.marginLeft = -21 - PROGRESS_BAR_WIDTH + pp + 'px';
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -928,47 +951,73 @@
|
|||
* Update progress bar based on timer
|
||||
*/
|
||||
CastPlayer.prototype.updateProgressBarByTimer = function () {
|
||||
var p = document.getElementById("progress");
|
||||
if (isNaN(parseInt(p.style.width))) {
|
||||
p.style.width = 0;
|
||||
var p = document.getElementById(this.progressBar);
|
||||
if (isNaN(parseInt(p.value))) {
|
||||
p.value = 0;
|
||||
}
|
||||
|
||||
if (this.currentMediaDuration > 0) {
|
||||
var pp = Math.floor(PROGRESS_BAR_WIDTH * this.currentMediaTime / this.currentMediaDuration);
|
||||
var pp = Number(this.currentMediaTime / this.currentMediaDuration).toFixed(3);
|
||||
var startTime = this.currentMediaOffset / 10000000;
|
||||
document.getElementById(this.playback).innerHTML = formatTime(startTime + this.currentMediaTime);
|
||||
}
|
||||
|
||||
if (this.progressFlag) {
|
||||
// don't update progress if it's been updated on media status update event
|
||||
p.style.width = pp + 'px';
|
||||
var pi = document.getElementById("progress_indicator");
|
||||
pi.style.marginLeft = -21 - PROGRESS_BAR_WIDTH + pp + 'px';
|
||||
p.value = pp;
|
||||
}
|
||||
|
||||
if (pp > PROGRESS_BAR_WIDTH) {
|
||||
if (pp > 100) {
|
||||
clearInterval(this.timer);
|
||||
this.deviceState = DEVICE_STATE.IDLE;
|
||||
this.castPlayerState = PLAYER_STATE.IDLE;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {function} A callback function for the fucntion to start timer
|
||||
*/
|
||||
CastPlayer.prototype.startProgressTimer = function(callback) {
|
||||
if(this.timer) {
|
||||
clearInterval(this.timer);
|
||||
this.timer = null;
|
||||
}
|
||||
|
||||
// start progress timer
|
||||
this.timer = setInterval(callback.bind(this), this.timerStep);
|
||||
};
|
||||
|
||||
var castPlayer = new CastPlayer();
|
||||
|
||||
function chromecastPlayer() {
|
||||
function chromecastPlayer(castPlayer) {
|
||||
|
||||
var self = this;
|
||||
|
||||
self.name = PlayerName;
|
||||
|
||||
self.isPaused = false;
|
||||
|
||||
self.play = function (options) {
|
||||
|
||||
if (options.items) {
|
||||
$("#nowPlayingBar", "#footer").show();
|
||||
|
||||
if (self.isPaused) {
|
||||
|
||||
console.log("unpause");
|
||||
self.isPaused = !self.isPaused;
|
||||
castPlayer.playMedia();
|
||||
|
||||
} else if (options.items) {
|
||||
|
||||
console.log("play1", options);
|
||||
Dashboard.getCurrentUser().done(function (user) {
|
||||
|
||||
castPlayer.loadMedia(user, options.items[0], options.startTimeTicks);
|
||||
castPlayer.loadMedia(user, options.items[0], options.startPositionTicks);
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
console.log("play2");
|
||||
var userId = Dashboard.getCurrentUserId();
|
||||
|
||||
var query = {};
|
||||
|
@ -988,6 +1037,18 @@
|
|||
|
||||
};
|
||||
|
||||
self.unpause = function () {
|
||||
console.log("unpause");
|
||||
self.isPaused = !self.isPaused;
|
||||
castPlayer.playMedia();
|
||||
};
|
||||
|
||||
self.pause = function () {
|
||||
console.log("pause");
|
||||
self.isPaused = true;
|
||||
castPlayer.pauseMedia();
|
||||
};
|
||||
|
||||
self.shuffle = function (id) {
|
||||
self.play({ ids: [id] });
|
||||
};
|
||||
|
@ -1005,7 +1066,9 @@
|
|||
};
|
||||
|
||||
self.stop = function () {
|
||||
castPlayer.stop();
|
||||
console.log("stop");
|
||||
$("#nowPlayingBar", "#footer").hide();
|
||||
castPlayer.stopMedia();
|
||||
};
|
||||
|
||||
self.canQueueMediaType = function (mediaType) {
|
||||
|
@ -1051,9 +1114,37 @@
|
|||
appName: appName
|
||||
};
|
||||
};
|
||||
|
||||
self.setCurrentTime = function (ticks, item, updateSlider) {
|
||||
|
||||
// Convert to ticks
|
||||
ticks = Math.floor(ticks);
|
||||
|
||||
var timeText = Dashboard.getDisplayTime(ticks);
|
||||
|
||||
if (self.currentDurationTicks) {
|
||||
|
||||
timeText += " / " + Dashboard.getDisplayTime(self.currentDurationTicks);
|
||||
|
||||
if (updateSlider) {
|
||||
var percent = ticks / self.currentDurationTicks;
|
||||
percent *= 100;
|
||||
|
||||
self.positionSlider.val(percent).slider('enable').slider('refresh');
|
||||
}
|
||||
} else {
|
||||
self.positionSlider.slider('disable').slider('refresh');
|
||||
}
|
||||
|
||||
MediaController.registerPlayer(new chromecastPlayer());
|
||||
self.currentTimeElement.html(timeText);
|
||||
};
|
||||
|
||||
self.changeStream = function (position) {
|
||||
console.log("seek", position);
|
||||
};
|
||||
}
|
||||
|
||||
MediaController.registerPlayer(new chromecastPlayer(castPlayer));
|
||||
|
||||
$(MediaController).on('playerchange', function () {
|
||||
|
||||
|
|
|
@ -174,6 +174,22 @@
|
|||
return p.isDefaultPlayer;
|
||||
})[0];
|
||||
};
|
||||
|
||||
self.pause = function () {
|
||||
currentPlayer.pause();
|
||||
};
|
||||
|
||||
self.stop = function () {
|
||||
currentPlayer.stop();
|
||||
};
|
||||
|
||||
self.unpause = function () {
|
||||
currentPlayer.unpause();
|
||||
};
|
||||
|
||||
self.seek = function (position) {
|
||||
self.changeStream(position);
|
||||
};
|
||||
}
|
||||
|
||||
window.MediaController = new mediaController();
|
||||
|
|
|
@ -1330,42 +1330,42 @@ $(function () {
|
|||
footerHtml += '<div class="barBackground ui-bar-b"></div>';
|
||||
footerHtml += '<div style="display:inline-block;width:12px;"></div>';
|
||||
footerHtml += '<a id="playlistButton" class="mediaButton playlistButton" href="playlist.html" data-role="button" data-icon="bullets" data-iconpos="notext" data-inline="true" title="Playlist">Playlist</a>';
|
||||
footerHtml += '<button id="previousTrackButton" class="mediaButton previousTrackButton" title="Previous Track" type="button" onclick="MediaPlayer.previousTrack();" data-icon="previous-track" data-iconpos="notext" data-inline="true">Previous Track</button>';
|
||||
footerHtml += '<button id="playButton" class="mediaButton" title="Play" type="button" onclick="MediaPlayer.unpause();" data-icon="play" data-iconpos="notext" data-inline="true">Play</button>';
|
||||
footerHtml += '<button id="pauseButton" class="mediaButton" title="Pause" type="button" onclick="MediaPlayer.pause();" data-icon="pause" data-iconpos="notext" data-inline="true">Pause</button>';
|
||||
footerHtml += '<button id="previousTrackButton" class="mediaButton previousTrackButton" title="Previous Track" type="button" onclick="MediaController.previousTrack();" data-icon="previous-track" data-iconpos="notext" data-inline="true">Previous Track</button>';
|
||||
footerHtml += '<button id="playButton" class="mediaButton" title="Play" type="button" onclick="MediaController.unpause();" data-icon="play" data-iconpos="notext" data-inline="true">Play</button>';
|
||||
footerHtml += '<button id="pauseButton" class="mediaButton" title="Pause" type="button" onclick="MediaController.pause();" data-icon="pause" data-iconpos="notext" data-inline="true">Pause</button>';
|
||||
|
||||
footerHtml += '<div id="mediaElement"></div>';
|
||||
|
||||
footerHtml += '<button id="stopButton" class="mediaButton" title="Stop" type="button" onclick="MediaPlayer.stop();" data-icon="stop" data-iconpos="notext" data-inline="true">Stop</button>';
|
||||
footerHtml += '<button id="nextTrackButton" class="mediaButton nextTrackButton" title="Next Track" type="button" onclick="MediaPlayer.nextTrack();" data-icon="next-track" data-iconpos="notext" data-inline="true">Next Track</button>';
|
||||
footerHtml += '<button id="stopButton" class="mediaButton" title="Stop" type="button" onclick="MediaController.stop();" data-icon="stop" data-iconpos="notext" data-inline="true">Stop</button>';
|
||||
footerHtml += '<button id="nextTrackButton" class="mediaButton nextTrackButton" title="Next Track" type="button" onclick="MediaController.nextTrack();" data-icon="next-track" data-iconpos="notext" data-inline="true">Next Track</button>';
|
||||
|
||||
footerHtml += '<div class="positionSliderContainer sliderContainer">';
|
||||
footerHtml += '<input type="range" class="mediaSlider positionSlider slider" step=".001" min="0" max="100" value="0" style="display:none;" data-mini="true" data-theme="a" data-highlight="true" />';
|
||||
footerHtml += '<input id="positionSlider" type="range" class="mediaSlider positionSlider slider" step=".001" min="0" max="100" value="0" style="display:none;" data-mini="true" data-theme="a" data-highlight="true" />';
|
||||
footerHtml += '</div>';
|
||||
|
||||
footerHtml += '<div class="currentTime"></div>';
|
||||
footerHtml += '<div class="currentTime" id="currentTime"></div>';
|
||||
footerHtml += '<div class="nowPlayingMediaInfo"></div>';
|
||||
|
||||
footerHtml += '<button id="muteButton" class="mediaButton muteButton" title="Mute" type="button" onclick="MediaPlayer.mute();" data-icon="audio" data-iconpos="notext" data-inline="true">Mute</button>';
|
||||
footerHtml += '<button id="unmuteButton" class="mediaButton unmuteButton" title="Unmute" type="button" onclick="MediaPlayer.unMute();" data-icon="volume-off" data-iconpos="notext" data-inline="true">Unmute</button>';
|
||||
footerHtml += '<button id="muteButton" class="mediaButton muteButton" title="Mute" type="button" onclick="MediaController.mute();" data-icon="audio" data-iconpos="notext" data-inline="true">Mute</button>';
|
||||
footerHtml += '<button id="unmuteButton" class="mediaButton unmuteButton" title="Unmute" type="button" onclick="MediaController.unMute();" data-icon="volume-off" data-iconpos="notext" data-inline="true">Unmute</button>';
|
||||
|
||||
footerHtml += '<div class="volumeSliderContainer sliderContainer">';
|
||||
footerHtml += '<input type="range" class="mediaSlider volumeSlider slider" step=".05" min="0" max="1" value="0" style="display:none;" data-mini="true" data-theme="a" data-highlight="true" />';
|
||||
footerHtml += '</div>';
|
||||
|
||||
footerHtml += '<button onclick="MediaPlayer.showQualityFlyout();" id="qualityButton" class="mediaButton qualityButton" title="Quality" type="button" data-icon="gear" data-iconpos="notext" data-inline="true">Quality</button>';
|
||||
footerHtml += '<button onclick="MediaController.showQualityFlyout();" id="qualityButton" class="mediaButton qualityButton" title="Quality" type="button" data-icon="gear" data-iconpos="notext" data-inline="true">Quality</button>';
|
||||
footerHtml += '<div class="mediaFlyoutContainer"><div id="qualityFlyout" style="display:none;" class="mediaPlayerFlyout"></div></div>';
|
||||
|
||||
footerHtml += '<button onclick="MediaPlayer.showAudioTracksFlyout();" id="audioTracksButton" class="imageButton mediaButton audioTracksButton" title="Audio tracks" type="button" data-icon="audiocd" data-iconpos="notext" data-inline="true">Audio Tracks</button>';
|
||||
footerHtml += '<button onclick="MediaController.showAudioTracksFlyout();" id="audioTracksButton" class="imageButton mediaButton audioTracksButton" title="Audio tracks" type="button" data-icon="audiocd" data-iconpos="notext" data-inline="true">Audio Tracks</button>';
|
||||
footerHtml += '<div class="mediaFlyoutContainer"><div id="audioTracksFlyout" style="display:none;" class="mediaPlayerFlyout audioTracksFlyout"></div></div>';
|
||||
|
||||
footerHtml += '<button onclick="MediaPlayer.showSubtitleMenu();" id="subtitleButton" class="imageButton mediaButton subtitleButton" title="Subtitles" type="button" data-icon="subtitles" data-iconpos="notext" data-inline="true">Subtitles</button>';
|
||||
footerHtml += '<button onclick="MediaController.showSubtitleMenu();" id="subtitleButton" class="imageButton mediaButton subtitleButton" title="Subtitles" type="button" data-icon="subtitles" data-iconpos="notext" data-inline="true">Subtitles</button>';
|
||||
footerHtml += '<div class="mediaFlyoutContainer"><div id="subtitleFlyout" style="display:none;" class="mediaPlayerFlyout subtitleFlyout"></div></div>';
|
||||
|
||||
footerHtml += '<button onclick="MediaPlayer.showChaptersFlyout();" id="chaptersButton" class="mediaButton chaptersButton" title="Scenes" type="button" data-icon="video" data-iconpos="notext" data-inline="true">Scenes</button>';
|
||||
footerHtml += '<button onclick="MediaController.showChaptersFlyout();" id="chaptersButton" class="mediaButton chaptersButton" title="Scenes" type="button" data-icon="video" data-iconpos="notext" data-inline="true">Scenes</button>';
|
||||
footerHtml += '<div class="mediaFlyoutContainer"><div id="chaptersFlyout" style="display:none;" class="mediaPlayerFlyout chaptersFlyout"></div></div>';
|
||||
|
||||
footerHtml += '<button onclick="MediaPlayer.toggleFullscreen();" id="fullscreenButton" class="mediaButton fullscreenButton" title="Fullscreen" type="button" data-icon="action" data-iconpos="notext" data-inline="true">Fullscreen</button>';
|
||||
footerHtml += '<button onclick="MediaController.toggleFullscreen();" id="fullscreenButton" class="mediaButton fullscreenButton" title="Fullscreen" type="button" data-icon="action" data-iconpos="notext" data-inline="true">Fullscreen</button>';
|
||||
|
||||
footerHtml += '</div>';
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue