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

control remote players with now playing bar

This commit is contained in:
Luke Pulverenti 2014-04-12 13:27:53 -04:00
parent 85a08beb3e
commit 2835534c6d
6 changed files with 342 additions and 91 deletions

View file

@ -1010,6 +1010,7 @@
var self = this; var self = this;
var isPositionSliderActive = false; var isPositionSliderActive = false;
var currentPlaylistIndex;
self.name = PlayerName; self.name = PlayerName;
@ -1365,11 +1366,35 @@
} }
}; };
self.beginPlayerUpdates = function () {
// Setup polling here
};
self.endPlayerUpdates = function () {
// Stop polling here
};
self.volumeDown = function () { self.volumeDown = function () {
}; };
self.volumeUp = function () { self.volumeUp = function () {
}; };
self.getPlayerState = function () {
var deferred = $.Deferred();
var result = self.getPlayerStateInternal();
deferred.resolveWith(null, [result]);
return deferred.promise();
};
self.getPlayerStateInternal = function () {
return {};
};
} }
MediaController.registerPlayer(new chromecastPlayer()); MediaController.registerPlayer(new chromecastPlayer());

View file

@ -241,14 +241,12 @@
function onWebSocketMessageReceived(e, msg) { function onWebSocketMessageReceived(e, msg) {
var localPlayer = msg.MessageType === "Play" || var localPlayer;
msg.MessageType === "Playstate" ||
msg.MessageType === "GeneralCommand" ?
MediaController.getLocalPlayer() :
null;
if (msg.MessageType === "Play") { if (msg.MessageType === "Play") {
localPlayer = MediaController.getLocalPlayer();
if (msg.Data.PlayCommand == "PlayNext") { if (msg.Data.PlayCommand == "PlayNext") {
localPlayer.queueNext({ ids: msg.Data.ItemIds }); localPlayer.queueNext({ ids: msg.Data.ItemIds });
} }
@ -268,6 +266,8 @@
} }
else if (msg.MessageType === "Playstate") { else if (msg.MessageType === "Playstate") {
localPlayer = MediaController.getLocalPlayer();
if (msg.Data.Command === 'Stop') { if (msg.Data.Command === 'Stop') {
localPlayer.stop(); localPlayer.stop();
} }
@ -286,14 +286,13 @@
else if (msg.Data.Command === 'PreviousTrack') { else if (msg.Data.Command === 'PreviousTrack') {
localPlayer.previousTrack(); localPlayer.previousTrack();
} }
else if (msg.Data.Command === 'Fullscreen') {
localPlayer.remoteFullscreen();
}
} }
else if (msg.MessageType === "GeneralCommand") { else if (msg.MessageType === "GeneralCommand") {
var cmd = msg.Data; var cmd = msg.Data;
localPlayer = MediaController.getLocalPlayer();
if (cmd.Name === 'Mute') { if (cmd.Name === 'Mute') {
localPlayer.mute(); localPlayer.mute();
} }
@ -309,6 +308,12 @@
else if (cmd.Name === 'ToggleMute') { else if (cmd.Name === 'ToggleMute') {
localPlayer.toggleMute(); localPlayer.toggleMute();
} }
else if (msg.Data.Command === 'Fullscreen') {
localPlayer.remoteFullscreen();
}
else if (msg.Data.Command === 'SetVolume') {
localPlayer.setVolume(cmd.Arguments.Volume);
}
} }
} }

View file

@ -213,7 +213,7 @@
currentTimeElement.html(timeText); currentTimeElement.html(timeText);
} }
var state = self.getPlayerState(currentMediaElement, currentItem, currentMediaSource); var state = self.getPlayerStateInternal(currentMediaElement, currentItem, currentMediaSource);
$(self).trigger('positionchange', [state]); $(self).trigger('positionchange', [state]);
}; };
@ -481,7 +481,7 @@
var mediaControls = $("#videoControls"); var mediaControls = $("#videoControls");
var state = self.getPlayerState(currentMediaElement, item, currentMediaSource); var state = self.getPlayerStateInternal(currentMediaElement, item, currentMediaSource);
var url = ""; var url = "";
@ -865,6 +865,8 @@
elem.pause(); elem.pause();
var isVideo = currentItem.MediaType == "Video";
$(elem).off("ended.playnext").on("ended", function () { $(elem).off("ended.playnext").on("ended", function () {
$(this).off(); $(this).off();
@ -875,10 +877,12 @@
elem.src = ""; elem.src = "";
currentMediaElement = null; currentMediaElement = null;
currentItem = null;
currentMediaSource = null;
}).trigger("ended"); }).trigger("ended");
if (currentItem.MediaType == "Video") { if (isVideo) {
if (self.isFullScreen()) { if (self.isFullScreen()) {
self.exitFullScreen(); self.exitFullScreen();
} }
@ -890,13 +894,46 @@
return currentMediaElement; return currentMediaElement;
}; };
self.getPlayerState = function (playerElement, item, mediaSource) { self.getPlayerState = function() {
var deferred = $.Deferred();
var result = self.getPlayerStateInternal(currentMediaElement, currentItem, currentMediaSource);
deferred.resolveWith(null, [result]);
return deferred.promise();
};
self.getPlayerStateInternal = function (playerElement, item, mediaSource) {
var state = {};
if (playerElement) {
state.volumeLevel = playerElement.volume * 100;
state.isMuted = playerElement.volume == 0;
state.isPaused = playerElement.paused;
state.positionTicks = self.getCurrentTicks(playerElement);
}
if (mediaSource) {
state.mediaSourceId = mediaSource.Id;
state.runtimeTicks = mediaSource.RunTimeTicks;
state.canSeek = mediaSource.RunTimeTicks && mediaSource.RunTimeTicks > 0;
}
if (item) {
state.itemId = item.Id;
state.mediaType = item.MediaType;
state.itemType = item.Type;
var itemName = ''; var itemName = '';
var itemSubName = ''; var itemSubName = '';
if (item) {
var name = item.Name; var name = item.Name;
var seriesName = ''; var seriesName = '';
@ -928,22 +965,6 @@
if (!itemSubName && item.ProductionYear) { if (!itemSubName && item.ProductionYear) {
itemSubName = item.ProductionYear; itemSubName = item.ProductionYear;
} }
}
var state = {
itemId: item.Id,
mediaSourceId: mediaSource.Id,
volumeLevel: playerElement.volume * 100,
isMuted: playerElement.volume == 0,
isPaused: playerElement.paused,
runtimeTicks: mediaSource.RunTimeTicks,
positionTicks: self.getCurrentTicks(playerElement),
canSeek: mediaSource.RunTimeTicks && mediaSource.RunTimeTicks > 0,
mediaType: item.MediaType,
itemName: itemName,
itemSubName: itemSubName,
itemType: item.Type
};
var imageTags = item.ImageTags || {}; var imageTags = item.ImageTags || {};
@ -965,9 +986,21 @@
state.thumbImageTag = imageTags.Thumb; state.thumbImageTag = imageTags.Thumb;
} }
state.itemName = itemName;
state.itemSubName = itemSubName;
}
return state; return state;
}; };
self.beginPlayerUpdates = function () {
// Nothing to setup here
};
self.endPlayerUpdates = function () {
// Nothing to setup here
};
self.onPlaybackStart = function (playerElement, item, mediaSource) { self.onPlaybackStart = function (playerElement, item, mediaSource) {
self.updateCanClientSeek(playerElement); self.updateCanClientSeek(playerElement);
@ -976,7 +1009,7 @@
self.startProgressInterval(item.Id, mediaSource.Id); self.startProgressInterval(item.Id, mediaSource.Id);
var state = self.getPlayerState(playerElement, item, mediaSource); var state = self.getPlayerStateInternal(playerElement, item, mediaSource);
$(self).trigger('playbackstart', [state]); $(self).trigger('playbackstart', [state]);
}; };
@ -985,7 +1018,7 @@
self.saveVolume(playerElement.volume); self.saveVolume(playerElement.volume);
var state = self.getPlayerState(playerElement, currentItem, currentMediaSource); var state = self.getPlayerStateInternal(playerElement, currentItem, currentMediaSource);
$(self).trigger('volumechange', [state]); $(self).trigger('volumechange', [state]);
}; };
@ -1017,14 +1050,14 @@
self.resetEnhancements(); self.resetEnhancements();
} }
var state = self.getPlayerState(playerElement, item, mediaSource); var state = self.getPlayerStateInternal(playerElement, item, mediaSource);
$(self).trigger('playbackstop', [state]); $(self).trigger('playbackstop', [state]);
}; };
self.onPlaystateChange = function (playerElement) { self.onPlaystateChange = function (playerElement) {
var state = self.getPlayerState(playerElement, currentItem, currentMediaSource); var state = self.getPlayerStateInternal(playerElement, currentItem, currentMediaSource);
$(self).trigger('playstatechange', [state]); $(self).trigger('playstatechange', [state]);
}; };

View file

@ -154,6 +154,13 @@
function updatePlayerState(state) { function updatePlayerState(state) {
if (state.itemName) {
showNowPlayingBar();
} else {
hideNowPlayingBar();
return;
}
lastPlayerState = state; lastPlayerState = state;
if (!muteButton) { if (!muteButton) {
@ -211,6 +218,8 @@
} }
currentTimeElement.html(timeText); currentTimeElement.html(timeText);
updateNowPlayingInfo(state);
} }
function updateNowPlayingInfo(state) { function updateNowPlayingInfo(state) {
@ -271,24 +280,13 @@
var player = this; var player = this;
if (player.isDefaultPlayer && state.mediaType == 'Video') { player.beginPlayerUpdates();
return;
onStateChanged.call(player, e, state);
} }
showNowPlayingBar();
updatePlayerState(state);
updateNowPlayingInfo(state);
}
var nowPlayingBarTimeout;
function showNowPlayingBar() { function showNowPlayingBar() {
if (nowPlayingBarTimeout) {
clearTimeout(nowPlayingBarTimeout);
nowPlayingBarTimeout = null;
}
var nowPlayingBar = getNowPlayingBar(); var nowPlayingBar = getNowPlayingBar();
nowPlayingBar.show(); nowPlayingBar.show();
@ -296,24 +294,21 @@
function hideNowPlayingBar() { function hideNowPlayingBar() {
if (nowPlayingBarTimeout) {
clearTimeout(nowPlayingBarTimeout);
nowPlayingBarTimeout = null;
}
// Use a timeout to prevent the bar from hiding and showing quickly // Use a timeout to prevent the bar from hiding and showing quickly
// in the event of a stop->play command // in the event of a stop->play command
nowPlayingBarTimeout = setTimeout(function () {
getNowPlayingBar().hide(); getNowPlayingBar().hide();
}, 500);
} }
function onPlaybackStopped(e, state) { function onPlaybackStopped(e, state) {
var player = this;
player.endPlayerUpdates();
hideNowPlayingBar(); hideNowPlayingBar();
} }
function onVolumeChanged(e, state) { function onStateChanged(e, state) {
var player = this; var player = this;
@ -329,7 +324,10 @@
if (currentPlayer) { if (currentPlayer) {
$(currentPlayer).off('.nowplayingbar'); $(currentPlayer).off('.nowplayingbar');
currentPlayer.endPlayerUpdates();
currentPlayer = null; currentPlayer = null;
hideNowPlayingBar();
} }
} }
@ -339,11 +337,20 @@
currentPlayer = player; currentPlayer = player;
player.getPlayerState().done(function (state) {
if (state.itemName) {
player.beginPlayerUpdates();
}
onStateChanged.call(player, null, state);
});
$(player).on('playbackstart.nowplayingbar', onPlaybackStart) $(player).on('playbackstart.nowplayingbar', onPlaybackStart)
.on('playbackstop.nowplayingbar', onPlaybackStopped) .on('playbackstop.nowplayingbar', onPlaybackStopped)
.on('volumechange.nowplayingbar', onVolumeChanged) .on('volumechange.nowplayingbar', onStateChanged)
.on('playstatechange.nowplayingbar', onVolumeChanged) .on('playstatechange.nowplayingbar', onStateChanged)
.on('positionchange.nowplayingbar', onVolumeChanged); .on('positionchange.nowplayingbar', onStateChanged);
} }
$(function () { $(function () {

View file

@ -96,14 +96,14 @@
var id = $('#selectSession', popup).val(); var id = $('#selectSession', popup).val();
ApiClient.sendSystemCommand(id, 'GoHome'); ApiClient.sendCommand(id, 'GoHome');
}); });
$('.btnGoToSettings', popup).on('click', function () { $('.btnGoToSettings', popup).on('click', function () {
var id = $('#selectSession', popup).val(); var id = $('#selectSession', popup).val();
ApiClient.sendSystemCommand(id, 'GoToSettings'); ApiClient.sendCommand(id, 'GoToSettings');
}); });
$('.btnSendMessage', popup).on('click', function () { $('.btnSendMessage', popup).on('click', function () {
@ -129,21 +129,21 @@
var id = $('#selectSession', popup).val(); var id = $('#selectSession', popup).val();
ApiClient.sendSystemCommand(id, 'VolumeDown'); ApiClient.sendCommand(id, 'VolumeDown');
}); });
$('.btnVolumeUp', popup).on('click', function () { $('.btnVolumeUp', popup).on('click', function () {
var id = $('#selectSession', popup).val(); var id = $('#selectSession', popup).val();
ApiClient.sendSystemCommand(id, 'VolumeUp'); ApiClient.sendCommand(id, 'VolumeUp');
}); });
$('.btnToggleMute', popup).on('click', function () { $('.btnToggleMute', popup).on('click', function () {
var id = $('#selectSession', popup).val(); var id = $('#selectSession', popup).val();
ApiClient.sendSystemCommand(id, 'ToggleMute'); ApiClient.sendCommand(id, 'ToggleMute');
}); });
$('.btnStop', popup).on('click', function () { $('.btnStop', popup).on('click', function () {
@ -432,6 +432,20 @@
ApiClient.sendPlayCommand(sessionId, remoteOptions); ApiClient.sendPlayCommand(sessionId, remoteOptions);
} }
function sendPlayStateCommand(command, options) {
var sessionId = MediaController.getPlayerInfo().id;
ApiClient.sendPlayStateCommand(sessionId, command, options);
}
function sendCommand(command, options) {
var sessionId = MediaController.getPlayerInfo().id;
ApiClient.sendCommand(sessionId, command, options);
}
function remoteControlPlayer() { function remoteControlPlayer() {
var self = this; var self = this;
@ -469,19 +483,114 @@
}; };
self.stop = function () { self.stop = function () {
sendPlayStateCommand('stop');
};
self.nextTrack = function () {
sendPlayStateCommand('nextTrack');
};
self.previousTrack = function () {
sendPlayStateCommand('previousTrack');
};
self.seek = function (positionTicks) {
sendPlayStateCommand('seek',
{
SeekPositionTicks: positionTicks
});
};
self.pause = function () {
sendPlayStateCommand('Pause');
};
self.unpause = function () {
sendPlayStateCommand('Unpause');
}; };
self.mute = function () { self.mute = function () {
sendCommand('Mute');
}; };
self.unMute = function () { self.unMute = function () {
sendCommand('Unmnute');
}; };
self.toggleMute = function () { self.toggleMute = function () {
sendCommand('ToggleMute');
};
self.setVolume = function (vol) {
sendCommand('SetVolume', {
Volume: vol
});
};
self.getPlayerState = function () {
var deferred = $.Deferred();
ApiClient.getSessions().done(function (sessions) {
var currentTargetId = MediaController.getPlayerInfo().id;
// Update existing data
//updateSessionInfo(popup, msg.Data);
var session = sessions.filter(function (s) {
return s.Id == currentTargetId;
})[0];
if (session) {
session = getPlayerState(session);
}
deferred.resolveWith(null, [session]);
});
return deferred.promise();
};
function subscribeToPlayerUpdates() {
if (ApiClient.isWebSocketOpen()) {
ApiClient.sendWebSocketMessage("SessionsStart", "100,700");
}
}
function unsubscribeFromPlayerUpdates() {
if (ApiClient.isWebSocketOpen()) {
ApiClient.sendWebSocketMessage("SessionsStop");
}
}
var playerListenerCount = 0;
self.beginPlayerUpdates = function () {
if (playerListenerCount <= 0) {
playerListenerCount = 0;
subscribeToPlayerUpdates();
}
playerListenerCount++;
};
self.endPlayerUpdates = function () {
playerListenerCount--;
if (playerListenerCount <= 0) {
unsubscribeFromPlayerUpdates();
playerListenerCount = 0;
}
}; };
self.getTargets = function () { self.getTargets = function () {
@ -521,11 +630,67 @@
}; };
} }
MediaController.registerPlayer(new remoteControlPlayer()); var player = new remoteControlPlayer();
MediaController.registerPlayer(player);
function getPlayerState(session) {
var state = {
volumeLevel: session.VolumeLevel,
isMuted: session.IsMuted,
isPaused: session.IsPaused,
canSeek: session.CanSeek
};
var item = session.NowPlayingItem;
if (item) {
state.itemId = item.Id;
state.itemType = item.Type;
state.mediaType = item.MediaType;
state.runtimeTicks = item.RunTimeTicks;
state.mediaSource = item.MediaSourceId;
state.positionTicks = session.NowPlayingPositionTicks || 0;
state.itemName = item.Name;
state.primaryImageItemId = item.PrimaryImageItemId;
state.primaryImageTag = item.PrimaryImageTag;
state.backdropItemId = item.BackdropItemId;
state.backdropImageTag = item.BackdropImageTag;
state.thumbItemId = item.ThumbItemId;
state.thumbImageTag = item.ThumbImageTag;
}
return state;
}
function firePlaybackEvent(name, session) {
$(player).trigger(name, [getPlayerState(session)]);
}
function onWebSocketMessageReceived(e, msg) { function onWebSocketMessageReceived(e, msg) {
if (msg.MessageType === "SessionEnded") { if (msg.MessageType === "Sessions") {
var currentTargetId = MediaController.getPlayerInfo().id;
// Update existing data
//updateSessionInfo(popup, msg.Data);
var session = msg.Data.filter(function (s) {
return s.Id == currentTargetId;
})[0];
if (session) {
firePlaybackEvent('playstatechange', session);
}
}
else if (msg.MessageType === "SessionEnded") {
console.log("Server reports another session ended"); console.log("Server reports another session ended");
@ -533,6 +698,12 @@
MediaController.setDefaultPlayerActive(); MediaController.setDefaultPlayerActive();
} }
} }
else if (msg.MessageType === "PlaybackStart") {
firePlaybackEvent('playbackstart', msg.Data);
}
else if (msg.MessageType === "PlaybackStopped") {
firePlaybackEvent('playbackstop', msg.Data);
}
} }
$(ApiClient).on("websocketmessage", onWebSocketMessageReceived); $(ApiClient).on("websocketmessage", onWebSocketMessageReceived);

View file

@ -3794,7 +3794,7 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
}); });
}; };
self.sendSystemCommand = function (sessionId, command) { self.sendCommand = function (sessionId, command, options) {
if (!sessionId) { if (!sessionId) {
throw new Error("null sessionId"); throw new Error("null sessionId");
@ -3804,12 +3804,22 @@ MediaBrowser.ApiClient = function ($, navigator, JSON, WebSocket, setTimeout, wi
throw new Error("null command"); throw new Error("null command");
} }
var url = self.getUrl("Sessions/" + sessionId + "/System/" + command); var url = self.getUrl("Sessions/" + sessionId + "/Command");
return self.ajax({ var ajaxOptions = {
type: "POST", type: "POST",
url: url url: url
}); };
options = {
Arguments: options || {},
Name: command
};
ajaxOptions.data = JSON.stringify(options);
ajaxOptions.contentType = "application/json";
return self.ajax(ajaxOptions);
}; };
self.sendMessageCommand = function (sessionId, options) { self.sendMessageCommand = function (sessionId, options) {