mirror of
https://github.com/jellyfin/jellycon.git
synced 2024-11-23 14:09:55 +00:00
add direct path, direct http and transcode http to playback types
make device id global
This commit is contained in:
parent
561f2f1245
commit
899ed9f95a
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<addon id="plugin.video.embycon"
|
||||
name="EmbyCon"
|
||||
version="1.0.7"
|
||||
version="1.0.8"
|
||||
provider-name="null_pointer">
|
||||
<requires>
|
||||
<import addon="xbmc.python" version="2.1.0"/>
|
||||
|
@ -9,7 +9,7 @@
|
||||
<string id="30008">Samba Password: </string>
|
||||
<string id="30010">Enable performance profiling</string>
|
||||
|
||||
<string id="30014">EmbyCon</string>
|
||||
<string id="30014">Emby</string>
|
||||
<string id="30015">Network</string>
|
||||
<string id="30016">Device Name</string>
|
||||
|
||||
@ -50,6 +50,10 @@
|
||||
<string id="30200">Select User</string>
|
||||
<string id="30203">Error in ArtworkRotationThread</string>
|
||||
<string id="30204">Unable to connect to host</string>
|
||||
<string id="30205">Error in LoadMenuOptionsThread</string>
|
||||
<string id="30205">Error in LoadMenuOptionsThread</string>
|
||||
|
||||
<string id="30206">Playback Type</string>
|
||||
<string id="30207">Playback</string>
|
||||
<string id="30208">Playback Bitrate (Kbits)</string>
|
||||
|
||||
</strings>
|
@ -2,6 +2,7 @@ from uuid import uuid4 as uuid4
|
||||
import xbmcaddon
|
||||
import xbmc
|
||||
import xbmcgui
|
||||
import xbmcvfs
|
||||
|
||||
from simple_logging import SimpleLogging
|
||||
|
||||
@ -9,29 +10,29 @@ log = SimpleLogging("EmbyCon." + __name__)
|
||||
|
||||
class ClientInformation():
|
||||
|
||||
def getMachineId(self):
|
||||
def getDeviceId(self):
|
||||
|
||||
WINDOW = xbmcgui.Window( 10000 )
|
||||
|
||||
clientId = WINDOW.getProperty("client_id")
|
||||
|
||||
if(clientId == None or clientId == ""):
|
||||
log.info("CLIENT_ID - > No Client ID in WINDOW")
|
||||
addonSettings = xbmcaddon.Addon(id='plugin.video.embycon')
|
||||
clientId = addonSettings.getSetting("client_id")
|
||||
|
||||
if(clientId == None or clientId == ""):
|
||||
log.info("CLIENT_ID - > No Client ID in SETTINGS")
|
||||
uuid = uuid4()
|
||||
clientId = "%012X" % uuid
|
||||
WINDOW.setProperty("client_id", clientId)
|
||||
addonSettings.setSetting("client_id",clientId)
|
||||
log.info("CLIENT_ID - > New Client ID : " + clientId)
|
||||
else:
|
||||
WINDOW.setProperty("client_id", clientId)
|
||||
log.info("CLIENT_ID - > Client ID saved to WINDOW from Settings : " + clientId)
|
||||
|
||||
return clientId
|
||||
client_id = WINDOW.getProperty("client_id")
|
||||
|
||||
if client_id:
|
||||
return client_id
|
||||
|
||||
emby_guid_path = xbmc.translatePath("special://temp/emby_guid").decode('utf-8')
|
||||
log.info("emby_guid_path: " + emby_guid_path)
|
||||
guid = xbmcvfs.File(emby_guid_path)
|
||||
client_id = guid.read()
|
||||
guid.close()
|
||||
|
||||
if not client_id:
|
||||
client_id = str("%012X" % uuid4())
|
||||
log.info("Generating a new guid: " + client_id)
|
||||
guid = xbmcvfs.File(emby_guid_path, 'w')
|
||||
guid.write(client_id)
|
||||
guid.close()
|
||||
|
||||
WINDOW.setProperty("client_id", client_id)
|
||||
return client_id
|
||||
|
||||
def getVersion(self):
|
||||
version = xbmcaddon.Addon(id="plugin.video.embycon").getAddonInfo("version")
|
||||
|
@ -180,7 +180,7 @@ class DownloadUtils():
|
||||
url = "http://" + self.addonSettings.getSetting("ipaddress") + ":" + self.addonSettings.getSetting("port") + "/emby/Users/AuthenticateByName?format=json"
|
||||
|
||||
clientInfo = ClientInformation()
|
||||
txt_mac = clientInfo.getMachineId()
|
||||
txt_mac = clientInfo.getDeviceId()
|
||||
version = clientInfo.getVersion()
|
||||
|
||||
deviceName = self.addonSettings.getSetting('deviceName')
|
||||
@ -212,7 +212,7 @@ class DownloadUtils():
|
||||
|
||||
def getAuthHeader(self, authenticate=True):
|
||||
clientInfo = ClientInformation()
|
||||
txt_mac = clientInfo.getMachineId()
|
||||
txt_mac = clientInfo.getDeviceId()
|
||||
version = clientInfo.getVersion()
|
||||
|
||||
deviceName = self.addonSettings.getSetting('deviceName')
|
||||
|
@ -156,9 +156,6 @@ def mainEntryPoint():
|
||||
|
||||
pluginhandle = int(sys.argv[1])
|
||||
|
||||
WINDOW = xbmcgui.Window( 10000 )
|
||||
WINDOW.clearProperty("heading")
|
||||
|
||||
log.info("EmbyCon -> Mode: " + str(mode))
|
||||
log.info("EmbyCon -> URL: " + str(param_url))
|
||||
|
||||
@ -172,17 +169,14 @@ def mainEntryPoint():
|
||||
else:
|
||||
displaySections()
|
||||
|
||||
WINDOW = xbmcgui.Window( 10000 )
|
||||
#WINDOW.clearProperty("MB3.Background.Item.FanArt")
|
||||
|
||||
dataManager.canRefreshNow = True
|
||||
|
||||
if(pr):
|
||||
pr.disable()
|
||||
|
||||
|
||||
fileTimeStamp = time.strftime("%Y-%m-%d %H-%M-%S")
|
||||
tabFileName = __addondir__ + "profile_(" + fileTimeStamp + ").txt"
|
||||
fileTimeStamp = time.strftime("%Y%m%d-%H%M%S")
|
||||
tabFileName = __addondir__ + "profile(" + fileTimeStamp + ").txt"
|
||||
f = open(tabFileName, 'wb')
|
||||
|
||||
s = StringIO.StringIO()
|
||||
@ -529,29 +523,27 @@ def addContextMenu(details, extraData, folder):
|
||||
item_id = extraData.get('id')
|
||||
if item_id != None:
|
||||
scriptToRun = PLUGINPATH + "/default.py"
|
||||
|
||||
pluginCastLink = "XBMC.Container.Update(plugin://plugin.video.embycon?mode=CAST_LIST&id=" + str(extraData.get('id')) + ")"
|
||||
commands.append(("Show People", pluginCastLink))
|
||||
|
||||
|
||||
# watched/unwatched
|
||||
if extraData.get("playcount") == "0":
|
||||
argsToPass = 'markWatched,' + extraData.get('id')
|
||||
commands.append(("Mark Watched", "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
|
||||
else:
|
||||
argsToPass = 'markUnwatched,' + extraData.get('id')
|
||||
commands.append(("Mark Unwatched", "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
|
||||
#if extraData.get("playcount") == "0":
|
||||
argsToPass = 'markWatched,' + extraData.get('id')
|
||||
commands.append(("Emby: Mark Watched", "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
|
||||
#else:
|
||||
argsToPass = 'markUnwatched,' + extraData.get('id')
|
||||
commands.append(("Emby: Mark Unwatched", "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
|
||||
|
||||
# favourite add/remove
|
||||
if extraData.get('favorite') != 'true':
|
||||
argsToPass = 'markFavorite,' + extraData.get('id')
|
||||
commands.append(("Add to Favourites", "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
|
||||
else:
|
||||
argsToPass = 'unmarkFavorite,' + extraData.get('id')
|
||||
commands.append(("Remove from Favourites", "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
|
||||
|
||||
#if extraData.get('favorite') != 'true':
|
||||
# argsToPass = 'markFavorite,' + extraData.get('id')
|
||||
# commands.append(("Add to Favourites", "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
|
||||
#else:
|
||||
# argsToPass = 'unmarkFavorite,' + extraData.get('id')
|
||||
# commands.append(("Remove from Favourites", "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
|
||||
|
||||
# delete
|
||||
argsToPass = 'delete,' + extraData.get('id')
|
||||
commands.append(("Delete", "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
|
||||
commands.append(("Emby: Delete", "XBMC.RunScript(" + scriptToRun + ", " + argsToPass + ")"))
|
||||
|
||||
return(commands)
|
||||
|
||||
|
@ -13,6 +13,7 @@ from downloadutils import DownloadUtils
|
||||
import urllib
|
||||
import sys
|
||||
from simple_logging import SimpleLogging
|
||||
from clientinfo import ClientInformation
|
||||
|
||||
#define our global download utils
|
||||
downloadUtils = DownloadUtils()
|
||||
@ -20,123 +21,50 @@ log = SimpleLogging("EmbyCon." + __name__)
|
||||
|
||||
###########################################################################
|
||||
class PlayUtils():
|
||||
|
||||
def getPlayUrl(self, server, id, result):
|
||||
|
||||
addonSettings = xbmcaddon.Addon(id='plugin.video.embycon')
|
||||
# if the path is local and depending on the video quality play we can direct play it do so-
|
||||
log.info("EmbyCon getPlayUrl")
|
||||
|
||||
playurl = result.get("Path")
|
||||
if playurl != None:
|
||||
#We have a path to play so play it
|
||||
USER_AGENT = 'QuickTime/7.7.4'
|
||||
|
||||
# If the file it is not a media stub
|
||||
if (result.get("IsPlaceHolder") != True):
|
||||
if (result.get("VideoType") == "Dvd"):
|
||||
playurl = playurl + "/VIDEO_TS/VIDEO_TS.IFO"
|
||||
elif (result.get("VideoType") == "BluRay"):
|
||||
playurl = playurl + "/BDMV/index.bdmv"
|
||||
if addonSettings.getSetting('smbusername') == '':
|
||||
playurl = playurl.replace("\\\\", "smb://")
|
||||
else:
|
||||
playurl = playurl.replace("\\\\", "smb://" + addonSettings.getSetting('smbusername') + ':' + addonSettings.getSetting('smbpassword') + '@')
|
||||
playurl = playurl.replace("\\", "/")
|
||||
|
||||
if ("apple.com" in playurl):
|
||||
playurl += '?|User-Agent=%s' % USER_AGENT
|
||||
if addonSettings.getSetting('playFromStream') == "true":
|
||||
playurl = 'http://' + server + '/emby/Videos/' + id + '/stream?static=true'
|
||||
mediaSources = result.get("MediaSources")
|
||||
if(mediaSources != None):
|
||||
if mediaSources[0].get('DefaultAudioStreamIndex') != None:
|
||||
playurl = playurl + "&AudioStreamIndex=" +str(mediaSources[0].get('DefaultAudioStreamIndex'))
|
||||
if mediaSources[0].get('DefaultSubtitleStreamIndex') != None:
|
||||
playurl = playurl + "&SubtitleStreamIndex=" + str(mediaSources[0].get('DefaultAudioStreamIndex'))
|
||||
|
||||
return playurl.encode('utf-8')
|
||||
|
||||
# Works out if we are direct playing or not
|
||||
def isDirectPlay(self, result):
|
||||
if result.get("LocationType") == "FileSystem" and self.isNetworkQualitySufficient(result) == True and self.isLocalPath(result) == False:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
# Works out if the network quality can play directly or if transcoding is needed
|
||||
def isNetworkQualitySufficient(self, result):
|
||||
settingsVideoBitRate = self.getVideoBitRate()
|
||||
settingsVideoBitRate = int(settingsVideoBitRate) * 1000
|
||||
mediaSources = result.get("MediaSources")
|
||||
if(mediaSources != None):
|
||||
if mediaSources[0].get('Bitrate') != None:
|
||||
if settingsVideoBitRate < int(mediaSources[0].get('Bitrate')):
|
||||
log.info("EmbyCon isNetworkQualitySufficient -> FALSE bit rate - settingsVideoBitRate: " + str(settingsVideoBitRate) + " mediasource bitrate: " + str(mediaSources[0].get('Bitrate')))
|
||||
return False
|
||||
else:
|
||||
log.info("EmbyCon isNetworkQualitySufficient -> TRUE bit rate")
|
||||
return True
|
||||
|
||||
# Any thing else is ok
|
||||
log.info("EmbyCon isNetworkQualitySufficient -> TRUE default")
|
||||
return True
|
||||
|
||||
|
||||
# get the addon video quality
|
||||
def getVideoBitRate(self):
|
||||
log.info("getPlayUrl")
|
||||
addonSettings = xbmcaddon.Addon(id='plugin.video.embycon')
|
||||
videoQuality = addonSettings.getSetting('videoBitRate')
|
||||
if (videoQuality == "0"):
|
||||
return '664'
|
||||
elif (videoQuality == "1"):
|
||||
return '996'
|
||||
elif (videoQuality == "2"):
|
||||
return '1320'
|
||||
elif (videoQuality == "3"):
|
||||
return '2000'
|
||||
elif (videoQuality == "4"):
|
||||
return '3200'
|
||||
elif (videoQuality == "5"):
|
||||
return '4700'
|
||||
elif (videoQuality == "6"):
|
||||
return '6200'
|
||||
elif (videoQuality == "7"):
|
||||
return '7700'
|
||||
elif (videoQuality == "8"):
|
||||
return '9200'
|
||||
elif (videoQuality == "9"):
|
||||
return '10700'
|
||||
elif (videoQuality == "10"):
|
||||
return '12200'
|
||||
elif (videoQuality == "11"):
|
||||
return '13700'
|
||||
elif (videoQuality == "12"):
|
||||
return '15200'
|
||||
elif (videoQuality == "13"):
|
||||
return '16700'
|
||||
elif (videoQuality == "14"):
|
||||
return '18200'
|
||||
elif (videoQuality == "15"):
|
||||
return '20000'
|
||||
elif (videoQuality == "16"):
|
||||
return '40000'
|
||||
elif (videoQuality == "17"):
|
||||
return '100000'
|
||||
elif (videoQuality == "18"):
|
||||
return '1000000'
|
||||
|
||||
# Works out if the network quality can play directly or if transcoding is needed
|
||||
def isLocalPath(self, result):
|
||||
playurl = result.get("Path")
|
||||
if playurl != None:
|
||||
#We have a path to play so play it
|
||||
if ":\\" in playurl:
|
||||
return True
|
||||
playback_type = addonSettings.getSetting("playback_type")
|
||||
playback_bitrate = addonSettings.getSetting("playback_bitrate")
|
||||
server = addonSettings.getSetting('ipaddress') + ":" + addonSettings.getSetting('port')
|
||||
log.info("playback_type: " + playback_type)
|
||||
playurl = None
|
||||
|
||||
# do direct path playback
|
||||
if playback_type == "0":
|
||||
playurl = result.get("Path")
|
||||
|
||||
# handle DVD structure
|
||||
if (result.get("VideoType") == "Dvd"):
|
||||
playurl = playurl + "/VIDEO_TS/VIDEO_TS.IFO"
|
||||
elif (result.get("VideoType") == "BluRay"):
|
||||
playurl = playurl + "/BDMV/index.bdmv"
|
||||
|
||||
# add smb creds
|
||||
if addonSettings.getSetting('smbusername') == '':
|
||||
playurl = playurl.replace("\\\\", "smb://")
|
||||
else:
|
||||
return False
|
||||
|
||||
# default to not local
|
||||
return False
|
||||
|
||||
playurl = playurl.replace("\\\\", "smb://" + addonSettings.getSetting(
|
||||
'smbusername') + ':' + addonSettings.getSetting('smbpassword') + '@')
|
||||
|
||||
playurl = playurl.replace("\\", "/")
|
||||
|
||||
# do direct http streaming playback
|
||||
elif playback_type == "1":
|
||||
playurl = "http://%s/emby/Videos/%s/stream?static=true" % (server, id)
|
||||
|
||||
# do transcode http streaming playback
|
||||
elif playback_type == "2":
|
||||
log.info("playback_bitrate: " + playback_bitrate)
|
||||
|
||||
clientInfo = ClientInformation()
|
||||
deviceId = clientInfo.getDeviceId()
|
||||
bitrate = int(playback_bitrate) * 1000;
|
||||
|
||||
playurl = (
|
||||
"http://%s/emby/Videos/%s/master.m3u8?MediaSourceId=%s&VideoCodec=h264&AudioCodec=ac3&MaxAudioChannels=6&deviceId=%s&VideoBitrate=%s"
|
||||
% (server, id, id, deviceId, bitrate))
|
||||
|
||||
log.info("Playback URL: " + playurl)
|
||||
return playurl.encode('utf-8')
|
||||
|
||||
|
@ -156,7 +156,7 @@ class WebSocketThread(threading.Thread):
|
||||
def on_open(self, ws):
|
||||
try:
|
||||
clientInfo = ClientInformation()
|
||||
machineId = clientInfo.getMachineId()
|
||||
machineId = clientInfo.getDeviceId()
|
||||
version = clientInfo.getVersion()
|
||||
messageData = {}
|
||||
messageData["MessageType"] = "Identity"
|
||||
|
@ -8,18 +8,22 @@
|
||||
<setting id="username" type="text" label="30024" />
|
||||
<setting id="password" type="text" option="hidden" label="30025" />
|
||||
<setting id="deviceName" type="text" label="30016" default="EmbyCon" visible="true" enable="true" />
|
||||
|
||||
</category>
|
||||
<category label="30207">
|
||||
<setting id="playback_type" type="enum" label="30206" values="Path Direct|Http Direct|Http Transcode" default="0" />
|
||||
<setting id="playback_bitrate" type="slider" label="30208" default="6000" range="400,100,10000" option="int" visible="eq(-1,2)"/>
|
||||
<setting id="resumeJumpBack" type="number" label="30114" default="10" visible="true" enable="true" />
|
||||
<setting type="sep" />
|
||||
<setting id="smbusername" type="text" label="30007" default="" visible="true" enable="true" />
|
||||
<setting id="smbpassword" type="text" label="30008" default="" option="hidden" visible="true" enable="true" />
|
||||
</category>
|
||||
<category label="30110">
|
||||
<setting id="resumeJumpBack" type="number" label="30114" default="10" visible="true" enable="true" />
|
||||
<setting id="addCounts" type="bool" label="30116" default="true" visible="true" enable="true" />
|
||||
<setting id="addSeasonNumber" type="bool" label="30162" default="false" visible="true" enable="true" />
|
||||
<setting id="addEpisodeNumber" type="bool" label="30119" default="true" visible="true" enable="true" />
|
||||
<setting id="addResumePercent" type="bool" label="30118" default="true" visible="true" enable="true" />
|
||||
<setting id="showLoadProgress" type="bool" label="30120" default="false" visible="true" enable="true" />
|
||||
<setting id="backgroundRefresh" type="number" label="30117" default="30" visible="true" enable="true" />
|
||||
</category>
|
||||
<category label="30022"> <!-- Advanced -->
|
||||
<setting id="logLevel" type="enum" label="30004" values="None|Info|Debug" default="0" />
|
||||
|
@ -33,19 +33,19 @@ def stopAll(played_information):
|
||||
if(len(played_information) == 0):
|
||||
return
|
||||
|
||||
log.info("EmbyCon Service -> played_information : " + str(played_information))
|
||||
log.info("played_information : " + str(played_information))
|
||||
|
||||
for item_url in played_information:
|
||||
data = played_information.get(item_url)
|
||||
if(data != None):
|
||||
log.info("EmbyCon Service -> item_url : " + item_url)
|
||||
log.info("EmbyCon Service -> item_data : " + str(data))
|
||||
log.info("item_url : " + item_url)
|
||||
log.info("item_data : " + str(data))
|
||||
|
||||
currentPossition = data.get("currentPossition")
|
||||
item_id = data.get("item_id")
|
||||
|
||||
if(hasData(item_id)):
|
||||
log.info("EmbyCon Service -> Playback Stopped at :" + str(int(currentPossition * 10000000)))
|
||||
log.info("Playback Stopped at: " + str(int(currentPossition * 10000000)))
|
||||
newWebSocketThread.playbackStopped(item_id, str(int(currentPossition * 10000000)))
|
||||
|
||||
played_information.clear()
|
||||
|
Loading…
Reference in New Issue
Block a user