1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Cast updates

This commit is contained in:
Tim Hobbs 2014-04-09 16:58:09 -07:00
parent 32c1badcd9
commit a500f154d8
4 changed files with 176 additions and 69 deletions

View file

@ -139,7 +139,7 @@
text-align: left; text-align: left;
margin-left: 0; margin-left: 0;
right: 0; right: 0;
bottom: 83px; bottom: 85px;
} }
/* Media queries /* Media queries
@ -259,7 +259,7 @@
} }
#mediaPlayer #videoControls .mediaPlayerFlyout { #mediaPlayer #videoControls .mediaPlayerFlyout {
bottom: 148px; bottom: 150px;
} }
} }

View file

@ -66,6 +66,17 @@
this.hasReceivers = false; 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(); this.initializeCastPlayer();
}; };
@ -617,6 +628,8 @@
return; return;
} }
this.currentMediaOffset = startTimeTicks;
var maxBitrate = 12000000; var maxBitrate = 12000000;
var mediaInfo = getMediaSourceInfo(user, item, maxBitrate, mediaSourceId, audioStreamIndex, subtitleStreamIndex); var mediaInfo = getMediaSourceInfo(user, item, maxBitrate, mediaSourceId, audioStreamIndex, subtitleStreamIndex);
@ -653,40 +666,62 @@
console.log("chromecast new media session ID:" + mediaSession.mediaSessionId + ' (' + how + ')'); console.log("chromecast new media session ID:" + mediaSession.mediaSessionId + ' (' + how + ')');
this.currentMediaSession = mediaSession; this.currentMediaSession = mediaSession;
this.currentMediaTime = this.session.media[0].currentTime;
if (how == 'loadMedia') { if (how == 'loadMedia') {
this.castPlayerState = PLAYER_STATE.PLAYING; this.castPlayerState = PLAYER_STATE.PLAYING;
clearInterval(this.timer);
this.startProgressTimer(this.incrementMediaTime);
} }
if (how == 'activeSession') { if (how == 'activeSession') {
this.castPlayerState = this.session.media[0].playerState; this.castPlayerState = this.session.media[0].playerState;
this.currentMediaTime = this.session.media[0].currentTime;
} }
if (this.castPlayerState == PLAYER_STATE.PLAYING) { if (this.castPlayerState == PLAYER_STATE.PLAYING) {
// start progress timer // start progress timer
//this.startProgressTimer(this.incrementMediaTime); this.startProgressTimer(this.incrementMediaTime);
} }
this.currentMediaSession.addUpdateListener(this.onMediaStatusUpdate.bind(this)); this.currentMediaSession.addUpdateListener(this.onMediaStatusUpdate.bind(this));
this.currentMediaDuration = this.currentMediaSession.media.duration;
//this.currentMediaDuration = this.currentMediaSession.media.duration; var playTime = document.getElementById(this.playback);
//var duration = this.currentMediaDuration; if (!playTime) {
//var hr = parseInt(duration / 3600); // Set duration time
//duration -= hr * 3600; var totalTime = document.getElementById(this.duration);
//var min = parseInt(duration / 60); totalTime.innerHTML = " / " + formatTime(this.currentMediaDuration);
//var sec = parseInt(duration % 60);
//if (hr > 0) { // Set play time
// duration = hr + ":" + min + ":" + sec; playTime = document.createElement("div");
//} playTime.id = this.playback;
//else { playTime.className = "currentTime";
// if (min > 0) { playTime.style.marginRight = "5px";
// duration = min + ":" + sec; totalTime.parentNode.insertBefore(playTime, totalTime);
// } playTime.innerHTML = formatTime(this.currentMediaTime);
// else { }
// duration = sec; };
// }
//} function formatTime(duration) {
//document.getElementById("duration").innerHTML = 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; this.castPlayerState = PLAYER_STATE.IDLE;
} }
console.log("chromecast updating media"); console.log("chromecast updating media");
//this.updateProgressBar(e); this.updateProgressBarByTimer();
}; };
/** /**
@ -745,6 +780,7 @@
this.currentMediaSession.addUpdateListener(this.onMediaStatusUpdate.bind(this)); this.currentMediaSession.addUpdateListener(this.onMediaStatusUpdate.bind(this));
this.castPlayerState = PLAYER_STATE.PLAYING; this.castPlayerState = PLAYER_STATE.PLAYING;
// start progress timer // start progress timer
clearInterval(this.timer);
this.startProgressTimer(this.incrementMediaTime); this.startProgressTimer(this.incrementMediaTime);
break; break;
case PLAYER_STATE.IDLE: case PLAYER_STATE.IDLE:
@ -850,18 +886,9 @@
*/ */
CastPlayer.prototype.seekMedia = function (event) { CastPlayer.prototype.seekMedia = function (event) {
var pos = parseInt(event.offsetX); var pos = parseInt(event.offsetX);
var pi = document.getElementById("progress_indicator"); var p = document.getElementById(this.progressBar);
var p = document.getElementById("progress"); var curr = parseInt(this.currentMediaTime + this.currentMediaDuration * pos);
if (event.currentTarget.id == 'progress_indicator') { var pw = parseInt(p.value) + pos;
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;
}
if (this.castPlayerState != PLAYER_STATE.PLAYING && this.castPlayerState != PLAYER_STATE.PAUSED) { if (this.castPlayerState != PLAYER_STATE.PLAYING && this.castPlayerState != PLAYER_STATE.PAUSED) {
return; return;
@ -899,20 +926,16 @@
* @param {Object} e An media status update object * @param {Object} e An media status update object
*/ */
CastPlayer.prototype.updateProgressBar = function (e) { CastPlayer.prototype.updateProgressBar = function (e) {
var p = document.getElementById("progress"); var p = document.getElementById(this.progressBar);
var pi = document.getElementById("progress_indicator");
if (e.idleReason == 'FINISHED' && e.playerState == 'IDLE') { if (e.idleReason == 'FINISHED' && e.playerState == 'IDLE') {
p.style.width = '0px'; p.value = 0;
pi.style.marginLeft = -21 - PROGRESS_BAR_WIDTH + 'px';
clearInterval(this.timer); clearInterval(this.timer);
this.castPlayerState = PLAYER_STATE.STOPPED; this.castPlayerState = PLAYER_STATE.STOPPED;
} }
else { 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; this.progressFlag = false;
setTimeout(this.setProgressFlag.bind(this), 1000); // don't update progress in 1 second 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 * Update progress bar based on timer
*/ */
CastPlayer.prototype.updateProgressBarByTimer = function () { CastPlayer.prototype.updateProgressBarByTimer = function () {
var p = document.getElementById("progress"); var p = document.getElementById(this.progressBar);
if (isNaN(parseInt(p.style.width))) { if (isNaN(parseInt(p.value))) {
p.style.width = 0; p.value = 0;
} }
if (this.currentMediaDuration > 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) { if (this.progressFlag) {
// don't update progress if it's been updated on media status update event // don't update progress if it's been updated on media status update event
p.style.width = pp + 'px'; p.value = pp;
var pi = document.getElementById("progress_indicator");
pi.style.marginLeft = -21 - PROGRESS_BAR_WIDTH + pp + 'px';
} }
if (pp > PROGRESS_BAR_WIDTH) { if (pp > 100) {
clearInterval(this.timer); clearInterval(this.timer);
this.deviceState = DEVICE_STATE.IDLE; this.deviceState = DEVICE_STATE.IDLE;
this.castPlayerState = PLAYER_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(); var castPlayer = new CastPlayer();
function chromecastPlayer() { function chromecastPlayer(castPlayer) {
var self = this; var self = this;
self.name = PlayerName; self.name = PlayerName;
self.isPaused = false;
self.play = function (options) { 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) { Dashboard.getCurrentUser().done(function (user) {
castPlayer.loadMedia(user, options.items[0], options.startTimeTicks); castPlayer.loadMedia(user, options.items[0], options.startPositionTicks);
}); });
} else { } else {
console.log("play2");
var userId = Dashboard.getCurrentUserId(); var userId = Dashboard.getCurrentUserId();
var query = {}; 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.shuffle = function (id) {
self.play({ ids: [id] }); self.play({ ids: [id] });
}; };
@ -1005,7 +1066,9 @@
}; };
self.stop = function () { self.stop = function () {
castPlayer.stop(); console.log("stop");
$("#nowPlayingBar", "#footer").hide();
castPlayer.stopMedia();
}; };
self.canQueueMediaType = function (mediaType) { self.canQueueMediaType = function (mediaType) {
@ -1051,9 +1114,37 @@
appName: appName 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');
}
self.currentTimeElement.html(timeText);
};
self.changeStream = function (position) {
console.log("seek", position);
};
} }
MediaController.registerPlayer(new chromecastPlayer()); MediaController.registerPlayer(new chromecastPlayer(castPlayer));
$(MediaController).on('playerchange', function () { $(MediaController).on('playerchange', function () {

View file

@ -174,6 +174,22 @@
return p.isDefaultPlayer; return p.isDefaultPlayer;
})[0]; })[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(); window.MediaController = new mediaController();

View file

@ -1330,42 +1330,42 @@ $(function () {
footerHtml += '<div class="barBackground ui-bar-b"></div>'; footerHtml += '<div class="barBackground ui-bar-b"></div>';
footerHtml += '<div style="display:inline-block;width:12px;"></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 += '<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="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="MediaPlayer.unpause();" data-icon="play" data-iconpos="notext" data-inline="true">Play</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="MediaPlayer.pause();" data-icon="pause" data-iconpos="notext" data-inline="true">Pause</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 += '<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="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="MediaPlayer.nextTrack();" data-icon="next-track" data-iconpos="notext" data-inline="true">Next Track</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 += '<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>';
footerHtml += '<div class="currentTime"></div>'; footerHtml += '<div class="currentTime" id="currentTime"></div>';
footerHtml += '<div class="nowPlayingMediaInfo"></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="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="MediaPlayer.unMute();" data-icon="volume-off" data-iconpos="notext" data-inline="true">Unmute</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 += '<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 += '<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 += '</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 += '<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 += '<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 += '<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 += '<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>'; footerHtml += '</div>';