102 lines
3.6 KiB
Python
102 lines
3.6 KiB
Python
|
import mediachoice
|
||
|
import util
|
||
|
|
||
|
|
||
|
class DecisionFailure(Exception):
|
||
|
def __init__(self, code, reason):
|
||
|
self.code = code
|
||
|
self.reason = reason
|
||
|
|
||
|
|
||
|
class ServerDecision(object):
|
||
|
DECISION_DIRECT_PLAY = "directplay"
|
||
|
DECISION_COPY = "copy"
|
||
|
DECISION_TRANSCODE = "transcode"
|
||
|
DIRECT_PLAY_OK = 1000
|
||
|
TRANSCODE_OK = 1001
|
||
|
|
||
|
def __init__(self, original, response, player):
|
||
|
self.original = original
|
||
|
self.response = response
|
||
|
self.player = player
|
||
|
self.item = None
|
||
|
|
||
|
self.init()
|
||
|
|
||
|
def init(self):
|
||
|
self.isSupported = self.response.server.supportsFeature("streamingBrain")
|
||
|
for item in self.response.items:
|
||
|
if item and item.media:
|
||
|
self.item = item
|
||
|
self.original.transcodeDecision = mediachoice.MediaChoice(self.item.media[0])
|
||
|
|
||
|
# Decision codes and text
|
||
|
self.decisionsCodes = {}
|
||
|
self.decisionsTexts = {}
|
||
|
for key in ["directPlayDecision", "generalDecision", "mdeDecision", "transcodeDecision", "termination"]:
|
||
|
self.decisionsCodes[key] = self.response.container.get(key + "Code", "-1").asInt()
|
||
|
self.decisionsTexts[key] = self.response.container.get(key + "Text")
|
||
|
|
||
|
util.DEBUG_LOG("Decision codes: {0}".format(self.decisionsCodes))
|
||
|
|
||
|
def __str__(self):
|
||
|
if self.isSupported:
|
||
|
obj = []
|
||
|
for v in self.decisionsTexts.values():
|
||
|
if v:
|
||
|
obj.append(v)
|
||
|
return ' '.join(obj)
|
||
|
else:
|
||
|
return "Server version does not support decisions."
|
||
|
|
||
|
def __repr__(self):
|
||
|
return self.__str__()
|
||
|
|
||
|
def getDecision(self, requireDecision=True):
|
||
|
if not self.item:
|
||
|
# Return no decision. The player will either continue with the original
|
||
|
# or terminate if a valid decision was required.
|
||
|
|
||
|
if requireDecision:
|
||
|
# Terminate the player by default if there was no decision returned.
|
||
|
code = self.decisionsCodes["generalDecision"]
|
||
|
reason = ' '.join([self.decisionsTexts["transcodeDecision"], self.decisionsTexts["generalDecision"]])
|
||
|
raise DecisionFailure(code, reason)
|
||
|
|
||
|
return None
|
||
|
|
||
|
# Rebuild the original item with the new item.
|
||
|
util.WARN_LOG("Server requested new playback decision: {0}".format(self))
|
||
|
self.original.rebuild(self.item, self)
|
||
|
return self.original
|
||
|
|
||
|
def isSuccess(self):
|
||
|
code = self.decisionsCodes["mdeDecision"]
|
||
|
return not self.isSupported or 1000 <= code < 2000
|
||
|
|
||
|
def isDecision(self, requireItem=False):
|
||
|
# Server has provided a valid decision if there was a valid decision code
|
||
|
# or if the response returned zero items (could not play).
|
||
|
return self.isSupported and (self.decisionsCodes["mdeDecision"] > -1 or requireItem and not self.item)
|
||
|
|
||
|
def isTimelineDecision(self):
|
||
|
return self.isSupported and self.item
|
||
|
|
||
|
def isTermination(self):
|
||
|
return self.isSupported and self.decisionsCodes["termination"] > -1
|
||
|
|
||
|
def directPlayOK(self):
|
||
|
return self.decisionsCodes["mdeDecision"] == 1000
|
||
|
|
||
|
def getTermination(self):
|
||
|
return {
|
||
|
'code': str(self.decisionsCodes["termination"]),
|
||
|
'text': self.decisionsTexts["termination"] or "Unknown" # TODO: Translate Unknown
|
||
|
}
|
||
|
|
||
|
def getDecisionText(self):
|
||
|
for key in ["mdeDecision", "directPlayDecision", "generalDecision", "transcodeDecision"]:
|
||
|
if self.decisionsTexts.get(key):
|
||
|
return self.decisionsTexts[key]
|
||
|
return None
|