Added audio/sub selection for transcoding

Also fixed transcoding not terminating as it should and leaving the
ffmpeg running.
This commit is contained in:
angelblue05 2015-08-06 03:09:45 -05:00
parent 68245268ba
commit ecaaa11deb
3 changed files with 132 additions and 176 deletions

View file

@ -210,11 +210,6 @@ class PlayUtils():
deviceId = self.clientInfo.getMachineId() deviceId = self.clientInfo.getMachineId()
playurl = "%s/mediabrowser/Videos/%s/master.m3u8?mediaSourceId=%s" % (server, id, id) playurl = "%s/mediabrowser/Videos/%s/master.m3u8?mediaSourceId=%s" % (server, id, id)
playurl = "%s&VideoCodec=h264&AudioCodec=aac,ac3&deviceId=%s&VideoBitrate=%s" % (playurl, deviceId, self.getVideoBitRate()*1000) playurl = "%s&VideoCodec=h264&AudioCodec=aac,ac3&deviceId=%s&VideoBitrate=%s" % (playurl, deviceId, self.getVideoBitRate()*1000)
mediaSources = result[u'MediaSources']
prefs = self.audioSubsPref(mediaSources)
playurl = "%s%s" % (playurl, prefs)
self.logMsg("Playurl: %s" % playurl) self.logMsg("Playurl: %s" % playurl)
return playurl return playurl
@ -313,109 +308,3 @@ class PlayUtils():
else: else:
self.logMsg("Path is detected as follow: %s. Try direct streaming." % path, 2) self.logMsg("Path is detected as follow: %s. Try direct streaming." % path, 2)
return False return False
def audioSubsPref(self, mediaSources):
addon = xbmcaddon.Addon()
defaultAudio = mediaSources[0][u'DefaultAudioStreamIndex']
playurlprefs = "&AudioStreamIndex=%s" % defaultAudio
codecs = [
# Possible codecs
u'und', u'ac3', u'dts', u'5.1', u'aac', u'mp3', u'dca'
]
try:
mediaStream = mediaSources[0].get('MediaStreams')
audiotracks = {}
substracks = {}
defaultSubs = None
for stream in mediaStream:
# Since Emby returns all possible tracks together, have to sort them.
if u'Audio' in stream[u'Type']:
if u'Language' in stream:
audiotracks[stream[u'Language']] = stream[u'Index']
else:
audiotracks[stream[u'Codec']] = stream[u'Index']
if u'Subtitle' in stream[u'Type']:
if u'Language' in stream:
substracks[stream[u'Language']] = stream[u'Index']
if stream[u'IsDefault'] == True:
defaultSubs = stream[u'Language']
else:
substracks[stream[u'Codec']] = stream[u'Index']
if stream[u'IsDefault']:
defaultSubs = stream[u'Codec']
self.logMsg("%s %s %s" % (defaultSubs, audiotracks, substracks), 1)
if len(audiotracks) == 1 and len(substracks) == 0:
# There's only one audio track and no subtitles
playurlprefs = "&AudioStreamIndex=%s" % defaultAudio
return playurlprefs
codec_intrack = False
for codec in codecs:
for track in audiotracks:
if codec in track:
codec_intrack = True
if self.audioPref in audiotracks:
self.logMsg("Door 1", 2)
# Audio pref is available
playurlprefs = "&AudioStreamIndex=%s" % audiotracks[self.audioPref]
if addon.getSetting('subsoverride') == "true":
# Subs are forced.
if self.subsPref in substracks:
self.logMsg("Door 1.1", 2)
playurlprefs = "%s&SubtitleStreamIndex=%s" % (playurlprefs, substracks[self.subsPref])
else:
# Use default subs
if defaultSubs != None:
self.logMsg("Door 1.2", 2)
playurlprefs = "%s&SubtitleStreamIndex=%s" % (playurlprefs, substracks[defaultSubs])
elif (len(audiotracks) == 1) and not codec_intrack:
self.logMsg("Door 2", 2)
# 1. There's one audio track.
# 2. The audio is defined as a language.
# 3. Audio pref is not available, guaranteed.
playurlprefs = "&AudioStreamIndex=%s" % defaultAudio
if self.subsPref in substracks:
self.logMsg("Door 2.1", 2)
# Subs pref is available.
playurlprefs = "%s&SubtitleStreamIndex=%s" % (playurlprefs, substracks[self.subsPref])
else:
# Use default subs
if defaultSubs != None:
self.logMsg("Door 2.2", 2)
playurlprefs = "%s&SubtitleStreamIndex=%s" % (playurlprefs, substracks[defaultSubs])
elif len(audiotracks) == 1 and codec_intrack:
self.logMsg("Door 3", 2)
# 1. There one audio track.
# 2. The audio is undefined or a codec.
# 3. Audio track is mislabeled.
playurlprefs = "&AudioStreamIndex=%s" % defaultAudio
if self.subsPref in substracks:
# If the subtitle is available, only display
# if the setting is enabled.
if addon.getSetting('subsoverride') == "true":
# Subs are forced.
self.logMsg("Door 3.1", 2)
playurlprefs = "%s&SubtitleStreamIndex=%s" % (playurlprefs, substracks[self.subsPref])
else:
# Use default subs
if defaultSubs != None:
self.logMsg("Door 3.2", 2)
playurlprefs = "%s&SubtitleStreamIndex=%s" % (playurlprefs, substracks[defaultSubs])
except: pass
return playurlprefs

View file

@ -97,6 +97,13 @@ class PlaybackUtils():
xbmc.log("Failed to retrieve the playback path/url.") xbmc.log("Failed to retrieve the playback path/url.")
return return
if WINDOW.getProperty("%splaymethod" % playurl) == "Transcode":
playurlprefs = self.audioSubsPref(playurl, result.get("MediaSources"))
if playurlprefs:
playurl = playurlprefs
else: # User cancelled dialog
return
thumbPath = API().getArtwork(result, "Primary") thumbPath = API().getArtwork(result, "Primary")
#if the file is a virtual strm file, we need to override the path by reading it's contents #if the file is a virtual strm file, we need to override the path by reading it's contents
@ -147,22 +154,6 @@ class PlaybackUtils():
WINDOW.setProperty(playurl+"type", result.get("Type")) WINDOW.setProperty(playurl+"type", result.get("Type"))
WINDOW.setProperty(playurl+"item_id", id) WINDOW.setProperty(playurl+"item_id", id)
'''mediaSources = result.get("MediaSources")
if(mediaSources != None):
mediaStream = mediaSources[0].get('MediaStreams')
defaultsubs = ""
for stream in mediaStream:
if u'Subtitle' in stream[u'Type'] and stream[u'IsDefault']:
if u'Language' in stream:
defaultsubs = stream[u'Language']
else:
defaultsubs = stream[u'Codec']
WINDOW.setProperty("%ssubs" % playurl, defaultsubs.encode('utf-8'))
if mediaSources[0].get('DefaultAudioStreamIndex') != None:
WINDOW.setProperty(playurl+"AudioStreamIndex", str(mediaSources[0].get('DefaultAudioStreamIndex')))
if mediaSources[0].get('DefaultSubtitleStreamIndex') != None:
WINDOW.setProperty(playurl+"SubtitleStreamIndex", str(mediaSources[0].get('DefaultSubtitleStreamIndex')))'''
#launch the playback - only set the listitem props if we're not using the setresolvedurl approach #launch the playback - only set the listitem props if we're not using the setresolvedurl approach
if setup == "service": if setup == "service":
self.setListItemProps(server, id, listItem, result) self.setListItemProps(server, id, listItem, result)
@ -174,6 +165,76 @@ class PlaybackUtils():
else: else:
xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listItem) xbmcplugin.setResolvedUrl(int(sys.argv[1]), True, listItem)
def audioSubsPref(self, url, mediaSources):
WINDOW = xbmcgui.Window(10000)
# Present the list of audio to select from
audioStreamsList = {}
audioStreams = []
selectAudioIndex = ""
subtitleStreamsList = {}
subtitleStreams = ['No subtitles']
selectSubsIndex = ""
playurlprefs = "%s" % url
mediaStream = mediaSources[0].get('MediaStreams')
for stream in mediaStream:
index = stream['Index']
# Since Emby returns all possible tracks together, have to sort them.
if 'Audio' in stream['Type']:
try:
track = stream['Language']
audioStreamsList[track] = index
audioStreams.append(track)
except:
track = stream['Codec']
audioStreamsList[track] = index
audioStreams.append(track)
elif 'Subtitle' in stream['Type']:
try:
track = stream['Language']
subtitleStreamsList[track] = index
subtitleStreams.append(track)
except:
track = stream['Codec']
subtitleStreamsList[track] = index
subtitleStreams.append(track)
if len(audioStreams) > 1:
resp = xbmcgui.Dialog().select("Choose the audio stream", audioStreams)
if resp > -1:
# User selected audio
selected = audioStreams[resp]
selected_audioIndex = audioStreamsList[selected]
playurlprefs += "&AudioStreamIndex=%s" % selected_audioIndex
selectAudioIndex = str(selected_audioIndex)
else: return False
else: # There's only one audiotrack.
audioIndex = audioStreamsList[audioStreams[0]]
playurlprefs += "&AudioStreamIndex=%s" % audioIndex
selectAudioIndex = str(audioIndex)
if len(subtitleStreams) > 1:
resp = xbmcgui.Dialog().select("Choose the subtitle stream", subtitleStreams)
if resp == 0:
# User selected no subtitles
pass
elif resp > -1:
# User selected subtitles
selected = subtitleStreams[resp]
selected_subsIndex = subtitleStreamsList[selected]
playurlprefs += "&SubtitleStreamIndex=%s" % selected_subsIndex
selectSubsIndex = str(selected_subsIndex)
else: return False
# Reset the method with the new playurl
WINDOW.setProperty("%splaymethod" % playurlprefs, "Transcode")
WINDOW.setProperty("%sAudioStreamIndex" % playurlprefs, selectAudioIndex)
WINDOW.setProperty("%sSubtitleStreamIndex" % playurlprefs, selectSubsIndex)
return playurlprefs
def setArt(self, list,name,path): def setArt(self, list,name,path):
if name=='thumb' or name=='fanart_image' or name=='small_poster' or name=='tiny_poster' or name == "medium_landscape" or name=='medium_poster' or name=='small_fanartimage' or name=='medium_fanartimage' or name=='fanart_noindicators': if name=='thumb' or name=='fanart_image' or name=='small_poster' or name=='tiny_poster' or name == "medium_landscape" or name=='medium_poster' or name=='small_fanartimage' or name=='medium_fanartimage' or name=='fanart_noindicators':
list.setProperty(name, path) list.setProperty(name, path)

View file

@ -68,6 +68,8 @@ class Player( xbmc.Player ):
def stopAll(self): def stopAll(self):
WINDOW = xbmcgui.Window(10000)
if(len(self.played_information) == 0): if(len(self.played_information) == 0):
return return
@ -86,6 +88,7 @@ class Player( xbmc.Player ):
refresh_id = data.get("refresh_id") refresh_id = data.get("refresh_id")
currentFile = data.get("currentfile") currentFile = data.get("currentfile")
type = data.get("Type") type = data.get("Type")
playMethod = data.get('playmethod')
# Prevent websocket feedback # Prevent websocket feedback
self.WINDOW.setProperty("played_itemId", item_id) self.WINDOW.setProperty("played_itemId", item_id)
@ -117,11 +120,11 @@ class Player( xbmc.Player ):
LibrarySync().removefromDB(listItem, True) LibrarySync().removefromDB(listItem, True)
# Stop transcoding # Stop transcoding
if self.WINDOW.getProperty("transcoding%s" % item_id) == "true": if playMethod == "Transcode":
self.logMsg("Transcoding for %s terminated." % item_id)
deviceId = self.clientInfo.getMachineId() deviceId = self.clientInfo.getMachineId()
url = "{server}/mediabrowser/Videos/ActiveEncodings?DeviceId=%s" % deviceId url = "{server}/mediabrowser/Videos/ActiveEncodings?DeviceId=%s" % deviceId
self.doUtils.downloadUrl(url, type="DELETE") self.doUtils.downloadUrl(url, type="DELETE")
self.WINDOW.clearProperty("transcoding%s" % item_id)
self.played_information.clear() self.played_information.clear()
@ -176,6 +179,21 @@ class Player( xbmc.Player ):
volume = result.get(u'result').get(u'volume') volume = result.get(u'result').get(u'volume')
muted = result.get(u'result').get(u'muted') muted = result.get(u'result').get(u'muted')
postdata = {
'QueueableMediaTypes': "Video",
'CanSeek': True,
'ItemId': item_id,
'MediaSourceId': item_id,
'PlayMethod': playMethod,
'IsPaused': paused,
'VolumeLevel': volume,
'IsMuted': muted
}
if playTime:
postdata['PositionTicks'] = int(playTime * 10000000)
if playMethod != "Transcode":
# Get current audio and subtitles track # Get current audio and subtitles track
track_query = '{"jsonrpc": "2.0", "method": "Player.GetProperties", "params": {"playerid":1,"properties": ["currentsubtitle","currentaudiostream","subtitleenabled"]} , "id": 1}' track_query = '{"jsonrpc": "2.0", "method": "Player.GetProperties", "params": {"playerid":1,"properties": ["currentsubtitle","currentaudiostream","subtitleenabled"]} , "id": 1}'
result = xbmc.executeJSONRPC(track_query) result = xbmc.executeJSONRPC(track_query)
@ -192,20 +210,6 @@ class Player( xbmc.Player ):
else: else:
indexSubs = "" indexSubs = ""
postdata = {
'QueueableMediaTypes': "Video",
'CanSeek': True,
'ItemId': item_id,
'MediaSourceId': item_id,
'PlayMethod': playMethod,
'IsPaused': paused,
'VolumeLevel': volume,
'IsMuted': muted
}
if playTime:
postdata['PositionTicks'] = int(playTime * 10000000)
if audioindex == indexAudio: if audioindex == indexAudio:
postdata['AudioStreamIndex'] = audioindex postdata['AudioStreamIndex'] = audioindex
else: else:
@ -218,6 +222,10 @@ class Player( xbmc.Player ):
postdata['SubtitleStreamIndex'] = indexSubs postdata['SubtitleStreamIndex'] = indexSubs
data['SubtitleStreamIndex'] = indexSubs data['SubtitleStreamIndex'] = indexSubs
else:
data['AudioStreamIndex'] = audioindex
data['SubtitleStreamIndex'] = subtitleindex
postdata = json.dumps(postdata) postdata = json.dumps(postdata)
self.logMsg("Report: %s" % postdata, 2) self.logMsg("Report: %s" % postdata, 2)
self.ws.sendProgressUpdate(postdata) self.ws.sendProgressUpdate(postdata)
@ -249,7 +257,7 @@ class Player( xbmc.Player ):
def onPlayBackStarted( self ): def onPlayBackStarted( self ):
# Will be called when xbmc starts playing a file # Will be called when xbmc starts playing a file
WINDOW = self.WINDOW WINDOW = xbmcgui.Window(10000)
addon = self.addon addon = self.addon
xbmcplayer = self.xbmcplayer xbmcplayer = self.xbmcplayer
self.stopAll() self.stopAll()
@ -277,8 +285,6 @@ class Player( xbmc.Player ):
# only ever use the win props here, use the data map in all other places # only ever use the win props here, use the data map in all other places
runtime = WINDOW.getProperty(currentFile + "runtimeticks") runtime = WINDOW.getProperty(currentFile + "runtimeticks")
refresh_id = WINDOW.getProperty(currentFile + "refresh_id") refresh_id = WINDOW.getProperty(currentFile + "refresh_id")
audioindex = WINDOW.getProperty(currentFile + "AudioStreamIndex")
subtitleindex = WINDOW.getProperty(currentFile + "SubtitleStreamIndex")
playMethod = WINDOW.getProperty(currentFile + "playmethod") playMethod = WINDOW.getProperty(currentFile + "playmethod")
itemType = WINDOW.getProperty(currentFile + "type") itemType = WINDOW.getProperty(currentFile + "type")
@ -289,14 +295,6 @@ class Player( xbmc.Player ):
volume = result.get(u'result').get(u'volume') volume = result.get(u'result').get(u'volume')
muted = result.get(u'result').get(u'muted') muted = result.get(u'result').get(u'muted')
# Get the current audio track and subtitles
track_query = '{"jsonrpc": "2.0", "method": "Player.GetProperties", "params": {"playerid":1,"properties": ["currentsubtitle","currentaudiostream","subtitleenabled"]} , "id": 1}'
result = xbmc.executeJSONRPC(track_query)
result = json.loads(result)
indexAudio = result['result']['currentaudiostream']['index']
indexSubs = result['result']['currentsubtitle']['index']
subsEnabled = result['result']['subtitleenabled']
seekTime = xbmc.Player().getTime() seekTime = xbmc.Player().getTime()
url = "{server}/mediabrowser/Sessions/Playing" url = "{server}/mediabrowser/Sessions/Playing"
@ -311,14 +309,22 @@ class Player( xbmc.Player ):
'IsMuted': muted 'IsMuted': muted
} }
if audioindex: # Get the current audio track and subtitles
if playMethod == "Transcode":
audioindex = WINDOW.getProperty(currentFile + "AudioStreamIndex")
subtitleindex = WINDOW.getProperty(currentFile + "SubtitleStreamIndex")
postdata['AudioStreamIndex'] = audioindex postdata['AudioStreamIndex'] = audioindex
else:
postdata['AudioStreamIndex'] = indexAudio + 1
if subtitleindex:
postdata['SubtitleStreamIndex'] = subtitleindex postdata['SubtitleStreamIndex'] = subtitleindex
else: else:
track_query = '{"jsonrpc": "2.0", "method": "Player.GetProperties", "params": {"playerid": 1,"properties": ["currentsubtitle","currentaudiostream","subtitleenabled"]} , "id": 1}'
result = xbmc.executeJSONRPC(track_query)
result = json.loads(result)
indexAudio = result['result']['currentaudiostream']['index']
indexSubs = result['result']['currentsubtitle']['index']
subsEnabled = result['result']['subtitleenabled']
postdata['AudioStreamIndex'] = indexAudio + 1
if subsEnabled: if subsEnabled:
audioTracks = len(xbmc.Player().getAvailableAudioStreams()) audioTracks = len(xbmc.Player().getAvailableAudioStreams())
postdata['SubtitleStreamIndex'] = indexSubs + audioTracks + 1 postdata['SubtitleStreamIndex'] = indexSubs + audioTracks + 1