Skip to content

Commit

Permalink
Create playbackManager class and move play related functions
Browse files Browse the repository at this point in the history
  • Loading branch information
YouKnowBlom committed Jun 10, 2020
1 parent c682482 commit 03dd0b2
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 128 deletions.
9 changes: 4 additions & 5 deletions src/components/commandHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ import {
shuffle,
instantMix,
isPlaying,
playNextItem,
playPreviousItem,
setAudioStreamIndex,
setSubtitleStreamIndex,
seek,
Expand All @@ -16,9 +14,10 @@ import { getReportingParams } from "../helpers";
import { factory as jellyfinActions } from "./jellyfinactions";

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

this.supportedCommands = {
PlayNext: this.playNextHandler,
Expand Down Expand Up @@ -70,13 +69,13 @@ export class commandHandler {

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

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

Expand Down
130 changes: 7 additions & 123 deletions src/components/maincontroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@ import {
getUrl,
getCurrentPositionTicks,
getReportingParams,
getNextPlaybackItemInfo,
resetPlaybackScope,
getMetadata,
createStreamInfo,
getStreamByIndex,
getSecurityHeaders,
getShuffleItems,
getInstantMixItems,
getIntros,
translateRequestedItems,
setAppStatus,
extend,
Expand All @@ -26,6 +24,7 @@ import {
} from "../helpers";

import { commandHandler } from "./commandHandler";
import { playbackManager } from "./playbackManager";

window.castReceiverContext = cast.framework.CastReceiverContext.getInstance();
window.mediaManager = window.castReceiverContext.getPlayerManager();
Expand All @@ -35,6 +34,8 @@ window.mediaManager.addEventListener(cast.framework.events.category.CORE,
console.log(event);
});

const playbackMgr = new playbackManager();

const playbackConfig = new cast.framework.PlaybackConfig();
// Set the player to start playback as soon as there are five seconds of
// media content buffered. Default is 10.
Expand Down Expand Up @@ -112,10 +113,6 @@ export function disableTimeUpdateListener() {

enableTimeUpdateListener();

export function isPlaying() {
return window.mediaManager.getPlayerState() === cast.framework.messages.PlayerState.PLAYING;
}

window.addEventListener('beforeunload', function () {
// Try to cleanup after ourselves before the page closes
disableTimeUpdateListener();
Expand Down Expand Up @@ -432,7 +429,7 @@ export function translateItems(data, options, items, method) {
if (method == 'PlayNext' || method == 'PlayLast') {
queue(options.items, method);
} else {
playFromOptions(data.options);
playbackMgr.playFromOptions(data.options);
}
};

Expand All @@ -445,15 +442,15 @@ export function instantMix(data, options, item) {

options.items = result.Items;
tagItems(options.items, data);
playFromOptions(data.options);
playbackMgr.playFromOptions(data.options);
});
}

export function shuffle(data, options, item) {
getShuffleItems(data.serverAddress, data.accessToken, data.userId, item).then(function (result) {
options.items = result.Items;
tagItems(options.items, data);
playFromOptions(data.options);
playbackMgr.playFromOptions(data.options);
});
}

Expand All @@ -463,82 +460,6 @@ export function queue(items) {
}
}

export function playFromOptions(options) {
var firstItem = options.items[0];

if (options.startPositionTicks || firstItem.MediaType !== 'Video') {
playFromOptionsInternal(options);
return;
}

getIntros(firstItem.serverAddress, firstItem.accessToken, firstItem.userId, firstItem).then(function (intros) {

tagItems(intros.Items, {
userId: firstItem.userId,
accessToken: firstItem.accessToken,
serverAddress: firstItem.serverAddress
});

options.items = intros.Items.concat(options.items);
playFromOptionsInternal(options);
});
}

export function playFromOptionsInternal(options) {

var stopPlayer = window.playlist && window.playlist.length > 0;

window.playlist = options.items;
window.currentPlaylistIndex = -1;
playNextItem(options, stopPlayer);
}

// Plays the next item in the list
export function playNextItem(options, stopPlayer) {

var nextItemInfo = getNextPlaybackItemInfo();

if (nextItemInfo) {
window.currentPlaylistIndex = nextItemInfo.index;

var item = nextItemInfo.item;

playItem(item, options || {}, stopPlayer);
return true;
}

return false;
}

export function playPreviousItem(options) {

var playlist = window.playlist;

if (playlist && window.currentPlaylistIndex > 0) {
window.currentPlaylistIndex--;

var item = playlist[window.currentPlaylistIndex];

playItem(item, options || {}, true);
return true;
}
return false;
}

export function playItem(item, options, stopPlayer) {

var callback = function () {
onStopPlayerBeforePlaybackDone(item, options);
};

if (stopPlayer) {

stop("none").then(callback);
} else {
callback();
}
}

export function onStopPlayerBeforePlaybackDone(item, options) {

var requestUrl = getUrl(item.serverAddress, 'Users/' + item.userId + '/Items/' + item.Id);
Expand All @@ -555,7 +476,7 @@ export function onStopPlayerBeforePlaybackDone(item, options) {
// Attach the custom properties we created like userId, serverAddress, itemId, etc
extend(data, item);

playItemInternal(data, options);
playbackMgr.playItemInternal(data, options);

}, broadcastConnectionErrorMessage);
}
Expand All @@ -573,43 +494,6 @@ export function getDeviceProfile(maxBitrate) {

}

export function playItemInternal(item, options) {

$scope.isChangingStream = false;
setAppStatus('loading');

getMaxBitrate(item.MediaType).then(function (maxBitrate) {

var deviceProfile = getDeviceProfile(maxBitrate);

jellyfinActions.getPlaybackInfo(item, maxBitrate, deviceProfile, options.startPositionTicks, options.mediaSourceId, options.audioStreamIndex, options.subtitleStreamIndex).then(function (result) {

if (validatePlaybackInfoResult(result)) {

var mediaSource = getOptimalMediaSource(result.MediaSources);

if (mediaSource) {

if (mediaSource.RequiresOpening) {

jellyfinActions.getLiveStream(item, result.PlaySessionId, maxBitrate, deviceProfile, options.startPositionTicks, mediaSource, null, null).then(function (openLiveStreamResult) {

openLiveStreamResult.MediaSource.enableDirectPlay = supportsDirectPlay(openLiveStreamResult.MediaSource);
playMediaSource(result.PlaySessionId, item, openLiveStreamResult.MediaSource, options);
});

} else {
playMediaSource(result.PlaySessionId, item, mediaSource, options);
}
} else {
showPlaybackInfoErrorMessage('NoCompatibleStream');
}
}

}, broadcastConnectionErrorMessage);
});
}

var lastBitrateDetect = 0;
var detectedBitrate = 0;
export function getMaxBitrate(mediaType) {
Expand Down
145 changes: 145 additions & 0 deletions src/components/playbackManager.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import {
getNextPlaybackItemInfo,
getIntros,
setAppStatus,
broadcastConnectionErrorMessage,
tagItems
} from "../helpers";

import {
onStopPlayerBeforePlaybackDone,
getMaxBitrate,
getDeviceProfile,
getOptimalMediaSource,
validatePlaybackInfoResult,
showPlaybackInfoErrorMessage,
supportsDirectPlay
} from "./maincontroller";

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

export class playbackManager {
constructor(castContext, playerManager) {
// Parameters
this.castContext = castContext;
this.playerManager = playerManager;

// Properties
this.activePlaylist = [];
this.activePlaylistIndex = 0;
}

isPlaying() {
return this.playerManager.getPlayerState() === cast.framework.messages.PlayerState.PLAYING;
}

playFromOptions(options) {
var firstItem = options.items[0];

if (options.startPositionTicks || firstItem.MediaType !== 'Video') {
this.playFromOptionsInternal(options);
return;
}

getIntros(firstItem.serverAddress, firstItem.accessToken, firstItem.userId, firstItem).then(function (intros) {

tagItems(intros.Items, {
userId: firstItem.userId,
accessToken: firstItem.accessToken,
serverAddress: firstItem.serverAddress
});

options.items = intros.Items.concat(options.items);
this.playFromOptionsInternal(options);
});
}

playFromOptionsInternal(options) {

var stopPlayer = this.activePlaylist && this.activePlaylist.length > 0;

this.activePlaylist = options.items;
this.activePlaylist.currentPlaylistIndex = -1;
this.playNextItem(options, stopPlayer);
}

// Plays the next item in the list
playNextItem(options, stopPlayer) {

var nextItemInfo = getNextPlaybackItemInfo();

if (nextItemInfo) {
this.activePlaylistIndex = nextItemInfo.index;

var item = nextItemInfo.item;

this.playItem(item, options || {}, stopPlayer);
return true;
}

return false;
}

playPreviousItem(options) {
if (this.activePlaylist && this.activePlaylistIndex > 0) {
this.activePlaylistIndex--;

var item = this.activePlaylist[this.activePlaylistIndex];

this.playItem(item, options || {}, true);
return true;
}
return false;
}

playItem(item, options, stopPlayer) {

var callback = function () {
onStopPlayerBeforePlaybackDone(item, options);
};

if (stopPlayer) {

stop("none").then(callback);
} else {
callback();
}
}

playItemInternal(item, options) {

$scope.isChangingStream = false;
setAppStatus('loading');

getMaxBitrate(item.MediaType).then(function (maxBitrate) {

var deviceProfile = getDeviceProfile(maxBitrate);

jellyfinActions.getPlaybackInfo(item, maxBitrate, deviceProfile, options.startPositionTicks, options.mediaSourceId, options.audioStreamIndex, options.subtitleStreamIndex).then(function (result) {

if (validatePlaybackInfoResult(result)) {

var mediaSource = getOptimalMediaSource(result.MediaSources);

if (mediaSource) {

if (mediaSource.RequiresOpening) {

jellyfinActions.getLiveStream(item, result.PlaySessionId, maxBitrate, deviceProfile, options.startPositionTicks, mediaSource, null, null).then(function (openLiveStreamResult) {

openLiveStreamResult.MediaSource.enableDirectPlay = supportsDirectPlay(openLiveStreamResult.MediaSource);
this.playMediaSource(result.PlaySessionId, item, openLiveStreamResult.MediaSource, options);
});

} else {
this.playMediaSource(result.PlaySessionId, item, mediaSource, options);
}
} else {
showPlaybackInfoErrorMessage('NoCompatibleStream');
}
}

}, broadcastConnectionErrorMessage);
});
}
}

0 comments on commit 03dd0b2

Please sign in to comment.