Skip to content

Commit

Permalink
Create new class for handling message commands
Browse files Browse the repository at this point in the history
  • Loading branch information
YouKnowBlom committed Jun 8, 2020
1 parent 48b3be3 commit 4372e2b
Show file tree
Hide file tree
Showing 2 changed files with 186 additions and 62 deletions.
173 changes: 173 additions & 0 deletions src/components/commandHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import {
translateItems,
shuffle,
instantMix,
isPlaying,
playNextItem,
playPreviousItem,
setAudioStreamIndex,
setSubtitleStreamIndex,
seek,
stop
} from "./maincontroller";

import { getReportingParams } from "../helpers";

import { factory as jellyfinActions } from "./jellyfinactions";

export class commandHandler {
constructor(castContext, playerManager) {
this.castContext = castContext;
this.playerManager = playerManager;

this.supportedCommands = {
PlayNext: this.playNextHandler,
PlayLast: this.playLastHandler,
Shuffle: this.shuffleHandler,
InstantMix: this.instantMixHandler,
DisplayContent: this.displayContentHandler,
NextTrack: this.nextTrackHandler,
PreviousTrack: this.previousTrackHandler,
SetAudioStreamIndex: this.setAudioStreamIndexHandler,
SetSubtitleStreamIndex: this.setSubtitleStreamIndexHandler,
VolumeUp: this.VolumeUpHandler,
VolumeDown: this.VolumeDownHandler,
ToggleMute: this.ToggleMuteHandler,
Identify: this.IdentifyHandler,
SetVolume: this.SetVolumeHandler,
Seek: this.SeekHandler,
Mute: this.MuteHandler,
Unmute: this.MuteHandler,
Stop: this.StopHandler,
PlayPause: this.PlayPauseHandler,
Pause: this.PauseHandler,
SetRepeatMode: this.SetRepeatModeHandler,
Unpause: this.UnpauseHandler
};
}

playNextHandler(data) {
translateItems(data, data.options, data.options.items, data.command);
}

playLastHandler(data) {
translateItems(data, data.options, data.options.items, data.command);
}

shuffleHandler(data) {
shuffle(data, data.options, data.options.items[0]);
}

instantMixHandler(data) {
instantMix(data, data.options, data.options.items[0]);
}

displayContentHandler(data) {
if (!isPlaying()) {
jellyfinActions.displayItem($scope, data.serverAddress, data.accessToken, data.userId, data.options.ItemId);
}
}

nextTrackHandler() {
if (window.playlist && window.currentPlaylistIndex < window.playlist.length - 1) {
playNextItem({}, true);
}
}

previousTrackHandler() {
if (window.playlist && window.currentPlaylistIndex > 0) {
playPreviousItem({});
}
}

setAudioStreamIndexHandler(data) {
setAudioStreamIndex($scope, data.options.index);
}

setSubtitleStreamIndexHandler(data) {
setSubtitleStreamIndex($scope, data.options.index, data.serverAddress);
}

// VolumeUp, VolumeDown and ToggleMute commands seem to be handled on the sender in the current implementation.
// From what I can tell there's no convenient way for the receiver to get its own volume.
// We should probably remove these commands in the future.
VolumeUpHandler() {
console.log("VolumeUp handler not implemented");
}

VolumeDownHandler() {
console.log("VolumeDown handler not implemented");
}

ToggleMuteHandler() {
console.log("ToggleMute handler not implemented");
}

SetVolumeHandler(data) {
// Scale 0-100
this.castContext.setSystemVolumeLevel(data.options.volume / 100);
}

IdentifyHandler(data) {
if (!isPlaying()) {
jellyfinActions.displayUserInfo($scope, data.serverAddress, data.accessToken, data.userId);
} else {
// When a client connects send back the initial device state (volume etc) via a playbackstop message
jellyfinActions.reportPlaybackProgress($scope, getReportingParams($scope), true, "playbackstop");
}
}

SeekHandler(data) {
seek(data.options.position * 10000000);
}

MuteHandler() {
this.castContext.setSystemVolumeMuted(true);
}

UnmuteHandler() {
this.castContext.setSystemVolumeMuted(false);
}

StopHandler() {
stop();
}

PlayPauseHandler() {
if (this.playerManager.getPlayerState() === cast.framework.messages.PlayerState.PAUSED) {
this.playerManager.play();
} else {
this.playerManager.pause();
}
}

PauseHandler() {
this.playerManager.pause();
}

SetRepeatModeHandler(data) {
window.repeatMode = data.options.RepeatMode;
window.reportEventType = 'repeatmodechange';
}

UnpauseHandler() {
this.playerManager.play();
}

// We should avoid using a defaulthandler that has a purpose other than informing the dev/user
// Currently all unhandled commands will be treated as play commands.
defaultHandler(data) {
translateItems(data, data.options, data.options.items, 'play');
}

processMessage(data, command) {
const commandHandler = this.supportedCommands[command];
if (typeof commandHandler === "function") {
console.debug(`Command "${command}" received. Calling identified handler.`);
(commandHandler.bind(this))(data);
} else {
console.debug(`Command "${command}" received. Calling default handler.`);
this.defaultHandler(data);
}
}
}
75 changes: 13 additions & 62 deletions src/components/maincontroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import {
tagItems
} from "../helpers";

import { commandHandler } from "./commandHandler";

window.castReceiverContext = cast.framework.CastReceiverContext.getInstance();
window.mediaManager = window.castReceiverContext.getPlayerManager();
window.mediaManager.addEventListener(cast.framework.events.category.CORE,
Expand Down Expand Up @@ -252,73 +254,22 @@ export function processMessage(data) {

// Items will have properties - Id, Name, Type, MediaType, IsFolder

var reportEventType;
var systemVolume = window.castReceiverContext.getSystemVolume();

if (data.command == 'PlayLast' || data.command == 'PlayNext') {
translateItems(data, data.options, data.options.items, data.command);
} else if (data.command == 'Shuffle') {
shuffle(data, data.options, data.options.items[0]);
} else if (data.command == 'InstantMix') {
instantMix(data, data.options, data.options.items[0]);
} else if (data.command == 'DisplayContent' && !isPlaying()) {
console.log('DisplayContent');
jellyfinActions.displayItem($scope, data.serverAddress, data.accessToken, data.userId, data.options.ItemId);
} else if (data.command == 'NextTrack' && window.playlist && window.currentPlaylistIndex < window.playlist.length - 1) {
playNextItem({}, true);
} else if (data.command == 'PreviousTrack' && window.playlist && window.currentPlaylistIndex > 0) {
playPreviousItem({});
} else if (data.command == 'SetAudioStreamIndex') {
setAudioStreamIndex($scope, data.options.index);
} else if (data.command == 'SetSubtitleStreamIndex') {
setSubtitleStreamIndex($scope, data.options.index, data.serverAddress);
} else if (data.command == 'VolumeUp') {
window.castReceiverContext.setSystemVolumeLevel(Math.min(1, systemVolume.level + 0.2));
} else if (data.command == 'VolumeDown') {
window.castReceiverContext.setSystemVolumeLevel(Math.max(0, systemVolume.level - 0.2));
} else if (data.command == 'ToggleMute') {
window.castReceiverContext.setSystemVolumeMuted(!systemVolume.muted);
} else if (data.command == 'Identify') {
if (!isPlaying()) {
jellyfinActions.displayUserInfo($scope, data.serverAddress, data.accessToken, data.userId);
} else {
// when a client connects send back the initial device state (volume etc) via a playbackstop message
jellyfinActions.reportPlaybackProgress($scope, getReportingParams($scope), true, "playbackstop");
}
} else if (data.command == 'SetVolume') {
// Scale 0-100
window.castReceiverContext.setSystemVolumeLevel(data.options.volume / 100);
} else if (data.command == 'Seek') {
seek(data.options.position * 10000000);
} else if (data.command == 'Mute') {
window.castReceiverContext.setSystemVolumeMuted(true);
} else if (data.command == 'Unmute') {
window.castReceiverContext.setSystemVolumeMuted(false);
} else if (data.command == 'Stop') {
stop();
} else if (data.command == 'PlayPause') {

if (window.mediaManager.getPlayerState() === cast.framework.messages.PlayerState.PAUSED) {
window.mediaManager.play();
} else {
window.mediaManager.pause();
}
} else if (data.command == 'Pause') {
window.mediaManager.pause();
} else if (data.command == 'SetRepeatMode') {
window.repeatMode = data.options.RepeatMode;
reportEventType = 'repeatmodechange';
} else if (data.command == 'Unpause') {
window.mediaManager.play();
} else {
translateItems(data, data.options, data.options.items, 'play');
window.reportEventType;

let cmdHandler = window.commandHandler;

if (!cmdHandler) {
window.commandHandler = new commandHandler(window.castReceiverContext, window.mediaManager);
cmdHandler = window.commandHandler;
}

if (reportEventType) {
cmdHandler.processMessage(data, data.command);

if (window.reportEventType) {
var report = function () {
jellyfinActions.reportPlaybackProgress($scope, getReportingParams($scope));
};
jellyfinActions.reportPlaybackProgress($scope, getReportingParams($scope), true, reportEventType);
jellyfinActions.reportPlaybackProgress($scope, getReportingParams($scope), true, window.reportEventType);
setTimeout(report, 100);
setTimeout(report, 500);
}
Expand Down

0 comments on commit 4372e2b

Please sign in to comment.