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;
margin-left: 0;
right: 0;
bottom: 83px;
bottom: 85px;
}
/* Media queries
@ -259,7 +259,7 @@
}
#mediaPlayer #videoControls .mediaPlayerFlyout {
bottom: 148px;
bottom: 150px;
}
}

View file

@ -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 () {

View file

@ -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();

View file

@ -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>';