Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
032fff0
plexobjects: fix asURL
pannal Jun 9, 2018
0c35977
add includeToken passthrough for plexvalue.asURL
pannal Jun 9, 2018
a63b00e
hide audio player when playing theme music
pannal Jun 9, 2018
55a3048
add BGMPlayerHandler
pannal Jun 9, 2018
bfee121
properly implement BGM handling; gracefully stop BGM playback on exit…
pannal Jun 9, 2018
f272fc5
pepify old_volume
pannal Jun 9, 2018
83e5a8c
forgotten files
pannal Jun 9, 2018
dd6b458
add ListSetting base class for QualitySetting and ThemeMusicSetting; …
pannal Jun 10, 2018
5dc58f7
simplify percentages (reduce translations); don't play the same theme…
pannal Jun 10, 2018
4fc6fd2
fix german translation
pannal Jun 10, 2018
121b973
set theme_playing global property as early as possible
pannal Jun 10, 2018
07e5aee
opener: pass full unspecific kwargs to opened windows
pannal Jun 12, 2018
6ae2953
BGMPlayerHandler: add debug logging; don't show notification on playb…
pannal Jun 12, 2018
d8ca4c6
stop theme music when returning to library or home views; don't re-pl…
pannal Jun 12, 2018
11508af
show window: move BGM trigger to onInit
pannal Jun 12, 2018
2ac356b
episode/show windows: properly stop theme playback of related show wh…
pannal Jun 12, 2018
db2479b
BGM: run background music in a separate task to avoid blocking the UI
pannal Jul 4, 2018
e7a3708
fix quality selection original crashing
pannal Jul 13, 2018
9a1b58c
fix volume setting
pannal Aug 28, 2018
cbc5fa0
use PlayMedia for playing back BGM
pannal Aug 29, 2018
bd4b526
stop currently playing theme before starting to play a new one; resol…
pannal Jan 19, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/_included_packages/plexnet/plexobjects.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ def asDatetime(self, format_=None):

return dt.strftime(format_)

def asURL(self):
return self.parent.server.url(self)
def asURL(self, includeToken=False):
return self.parent.server.buildUrl(self, includeToken)

def asTranscodedImageURL(self, w, h, **extras):
return self.parent.server.getImageTranscodeURL(self, w, h, **extras)
Expand Down
127 changes: 118 additions & 9 deletions lib/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import xbmcgui
import kodijsonrpc
import colors
from lib import backgroundthread
from windows import seekdialog
import util
from plexnet import plexplayer
Expand Down Expand Up @@ -301,7 +302,6 @@ def seekAbsolute(self, seek=None):

def onPlayBackStarted(self):
util.DEBUG_LOG('SeekHandler: onPlayBackStarted - mode={0}'.format(self.mode))

self.updateNowPlaying(force=True, refreshQueue=True)

def onPlayBackResumed(self):
Expand Down Expand Up @@ -389,14 +389,20 @@ def setAudioTrack(self):
if self.mode == self.MODE_ABSOLUTE:
track = self.player.video.selectedAudioStream()
if track:
try:
playerID = kodijsonrpc.rpc.Player.GetActivePlayers()[0]["playerid"]
currIdx = kodijsonrpc.rpc.Player.GetProperties(playerid=playerID, properties=['currentaudiostream'])['currentaudiostream']['index']
if currIdx == track.typeIndex:
util.DEBUG_LOG('Audio track is correct index: {0}'.format(track.typeIndex))
return
except:
util.ERROR()
# only try finding the current audio stream when the BG music isn't playing and wasn't the last
# thing played, because currentaudiostream doesn't populate for audio-only items; in that case,
# always select the proper audio stream
if not self.player.lastPlayWasBGM:
try:
playerID = kodijsonrpc.rpc.Player.GetActivePlayers()[0]["playerid"]
currIdx = kodijsonrpc.rpc.Player.GetProperties(playerid=playerID, properties=['currentaudiostream'])['currentaudiostream']['index']
if currIdx == track.typeIndex:
util.DEBUG_LOG('Audio track is correct index: {0}'.format(track.typeIndex))
return
except:
util.ERROR()

self.player.lastPlayWasBGM = False

xbmc.sleep(100)
util.DEBUG_LOG('Switching audio track - index: {0}'.format(track.typeIndex))
Expand Down Expand Up @@ -584,6 +590,7 @@ def onMonitorInit(self):
self.updateNowPlaying(state='playing')

def onPlayBackStarted(self):
self.player.lastPlayWasBGM = False
self.updatePlayQueue(delay=True)
self.extractTrackInfo()
self.updateNowPlaying(state='playing')
Expand Down Expand Up @@ -616,6 +623,62 @@ def tick(self):
self.updateNowPlaying(force=True)


class BGMPlayerHandler(BasePlayerHandler):
def __init__(self, player, rating_key):
BasePlayerHandler.__init__(self, player)
self.timelineType = 'music'
self.currentlyPlaying = rating_key
util.setGlobalProperty('track.ID', '')
util.setGlobalProperty('theme_playing', '1')

self.oldVolume = util.rpc.Application.GetProperties(properties=["volume"])["volume"]

def onPlayBackStarted(self):
util.DEBUG_LOG("BGM: playing theme for %s" % self.currentlyPlaying)
self.player.bgmPlaying = True

def setVolume(self, volume=None, reset=False):
vlm = self.oldVolume if reset else volume
util.DEBUG_LOG("BGM: %ssetting volume to: %s" % ("re-" if reset else "", vlm))
xbmc.executebuiltin("SetVolume(%s)" % vlm)

def resetVolume(self):
self.setVolume(reset=True)

def onPlayBackStopped(self):
util.DEBUG_LOG("BGM: stopped theme for %s" % self.currentlyPlaying)
util.setGlobalProperty('theme_playing', '')
self.player.bgmPlaying = False
self.resetVolume()

def onPlayBackEnded(self):
self.onPlayBackStopped()

def onPlayBackFailed(self):
self.onPlayBackStopped()

def close(self):
self.player.stopAndWait()
self.onPlayBackStopped()


class BGMPlayerTask(backgroundthread.Task):
def setup(self, source, *args, **kwargs):
self.source = source
return self

def cancel(self):
self.player.stopAndWait()
self.player = None
backgroundthread.Task.cancel(self)

def run(self):
if self.isCanceled():
return

xbmc.executebuiltin("XBMC.PlayMedia(%s)" % self.source)


class PlexPlayer(xbmc.Player, signalsmixin.SignalsMixin):
STATE_STOPPED = "stopped"
STATE_PLAYING = "playing"
Expand All @@ -626,6 +689,9 @@ def init(self):
self._closed = False
self._nextItem = None
self.started = False
self.bgmPlaying = False
self.lastPlayWasBGM = False
self.BGMTask = None
self.pauseAfterPlaybackStarted = False
self.video = None
self.hasOSD = False
Expand All @@ -650,6 +716,7 @@ def close(self, shutdown=False):
def reset(self):
self.video = None
self.started = False
self.bgmPlaying = False
self.playerObject = None
self.pauseAfterPlaybackStarted = False
self.handler = AudioPlayerHandler(self)
Expand Down Expand Up @@ -708,7 +775,37 @@ def play(self, *args, **kwargs):
self.started = False
xbmc.Player.play(self, *args, **kwargs)

def playBackgroundMusic(self, source, volume, rating_key, *args, **kwargs):
if self.isPlaying():
if not self.lastPlayWasBGM:
return

else:
# don't re-queue the currently playing theme
if self.handler.currentlyPlaying == rating_key:
return

# cancel any currently playing theme before starting the new one
else:
self.stopAndWait()

if self.BGMTask and self.BGMTask.isValid():
self.BGMTask.cancel()

self.started = False
self.handler = BGMPlayerHandler(self, rating_key)

self.lastPlayWasBGM = True

self.handler.setVolume(volume)

self.BGMTask = BGMPlayerTask().setup(source, *args, **kwargs)
backgroundthread.BGThreader.addTask(self.BGMTask)

def playVideo(self, video, resume=False, force_update=False, session_id=None, handler=None):
if self.bgmPlaying:
self.stopAndWait()

self.handler = handler or SeekPlayerHandler(self, session_id)
self.video = video
self.open()
Expand Down Expand Up @@ -773,6 +870,9 @@ def _playVideo(self, offset=0, seeking=0, force_update=False, playerObject=None)
self.play(url, li)

def playVideoPlaylist(self, playlist, resume=True, handler=None, session_id=None):
if self.bgmPlaying:
self.stopAndWait()

if handler:
self.handler = handler
else:
Expand Down Expand Up @@ -808,12 +908,18 @@ def playVideoPlaylist(self, playlist, resume=True, handler=None, session_id=None
# return url, li

def playAudio(self, track, fanart=None):
if self.bgmPlaying:
self.stopAndWait()

self.handler = AudioPlayerHandler(self)
url, li = self.createTrackListItem(track, fanart)
self.stopAndWait()
self.play(url, li)

def playAlbum(self, album, startpos=-1, fanart=None):
if self.bgmPlaying:
self.stopAndWait()

self.handler = AudioPlayerHandler(self)
plist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC)
plist.clear()
Expand All @@ -827,6 +933,9 @@ def playAlbum(self, album, startpos=-1, fanart=None):
self.play(plist, startpos=startpos)

def playAudioPlaylist(self, playlist, startpos=-1, fanart=None):
if self.bgmPlaying:
self.stopAndWait()

self.handler = AudioPlayerHandler(self)
plist = xbmc.PlayList(xbmc.PLAYLIST_MUSIC)
plist.clear()
Expand Down
6 changes: 6 additions & 0 deletions lib/plex.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,12 @@ def getMaxResolution(self, quality_type, allow4k=False):
else:
return 360

def getThemeMusicValue(self):
index = 10 - self.getPreference("theme_music", 11)
if index > 0:
return index * 10
return 0


plexapp.setInterface(PlexInterface())
plexapp.setUserAgent(defaultUserAgent())
Expand Down
22 changes: 20 additions & 2 deletions lib/windows/episodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def doClose(self):
player.PLAYER.off('new.video', self.onNewVideo)

@busy.dialog()
def onFirstInit(self):
def _onFirstInit(self):
self.episodeListControl = kodigui.ManagedControlList(self, self.EPISODE_LIST_ID, 5)
self.progressImageControl = self.getControl(self.PROGRESS_IMAGE_ID)

Expand All @@ -123,6 +123,18 @@ def onFirstInit(self):
def doAutoPlay(self):
return self.playButtonClicked(force_episode=self.initialEpisode)

def onFirstInit(self):
self._onFirstInit()

# we've come from a home hub view, play the current item's show's theme song
if self.initialEpisode:
volume = self.initialEpisode.settings.getThemeMusicValue()
if volume > 0:
theme = self.initialEpisode.show().theme
if theme:
player.PLAYER.playBackgroundMusic(theme.asURL(True), volume,
self.initialEpisode.show().ratingKey)

def onReInit(self):
self.selectEpisode()

Expand Down Expand Up @@ -284,6 +296,9 @@ def onFocus(self, controlID):
elif xbmc.getCondVisibility('ControlGroup(50).HasFocus(0) + !ControlGroup(300).HasFocus(0)'):
self.setProperty('on.extras', '1')

if player.PLAYER.bgmPlaying and player.PLAYER.handler.currentlyPlaying != self.season.show().ratingKey:
player.PLAYER.stopAndWait()

def openItem(self, control=None, item=None):
if not item:
mli = control.getSelectedItem()
Expand Down Expand Up @@ -587,7 +602,10 @@ def optionsButtonClicked(self, from_item=False):
self.updateItems()
util.MONITOR.watchStatusChanged()
elif choice['key'] == 'to_show':
self.processCommand(opener.open(self.season.parentRatingKey))
self.processCommand(opener.open(
self.season.parentRatingKey,
came_from=self.season.parentRatingKey)
)
elif choice['key'] == 'to_section':
self.goHome(self.season.getLibrarySectionId())
elif choice['key'] == 'delete':
Expand Down
3 changes: 3 additions & 0 deletions lib/windows/home.py
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,9 @@ def onFocus(self, controlID):
elif controlID != 250 and xbmc.getCondVisibility('ControlGroup(50).HasFocus(0) + !ControlGroup(100).HasFocus(0)'):
util.setGlobalBoolProperty('off.sections', '1')

if player.PLAYER.bgmPlaying:
player.PLAYER.stopAndWait()

def confirmExit(self):
button = optionsdialog.show(
T(32334, 'Confirm Exit'),
Expand Down
4 changes: 4 additions & 0 deletions lib/windows/library.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from lib import colors
from lib import util
from lib import backgroundthread
from lib import player

import busy
import subitems
Expand Down Expand Up @@ -566,6 +567,9 @@ def onFocus(self, controlID):
if controlID == self.KEY_LIST_ID:
self.selectKey()

if player.PLAYER.bgmPlaying:
player.PLAYER.stopAndWait()

def onItemChanged(self, mli):
if not mli:
return
Expand Down
Loading