def __init__(self, item): self.containerFormats = {'aac': "es.aac-adts"} self.item = item self.choice = mediadecisionengine.MediaDecisionEngine().chooseMedia( item) if self.choice: self.media = self.choice.media self.lyrics = None # createLyrics(item, self.media)
def _build(self, directPlay=None, directStream=True, currentPartIndex=None): isForced = directPlay is not None if isForced: util.LOG( directPlay and "Forced Direct Play" or "Forced Transcode; allowDirectStream={0}".format(directStream)) directPlay = directPlay or self.choice.isDirectPlayable server = self.item.getServer() # A lot of our content metadata is independent of the direct play decision. # Add that first. obj = util.AttributeDict() obj.duration = self.media.duration.asInt() videoRes = self.media.getVideoResolution() obj.fullHD = videoRes >= 1080 obj.streamQualities = ( videoRes >= 480 and self.item.settings.getGlobal("IsHD")) and ["HD"] or ["SD"] frameRate = self.media.videoFrameRate or "24p" if frameRate == "24p": obj.frameRate = 24 elif frameRate == "NTSC": obj.frameRate = 30 # Add soft subtitle info if self.choice.subtitleDecision == self.choice.SUBTITLES_SOFT_ANY: obj.subtitleUrl = server.buildUrl( self.choice.subtitleStream.getSubtitlePath(), True) elif self.choice.subtitleDecision == self.choice.SUBTITLES_SOFT_DP: obj.subtitleConfig = { 'TrackName': "mkv/" + str(self.choice.subtitleStream.index.asInt() + 1) } # Create one content metadata object for each part and store them as a # linked list. We probably want a doubly linked list, except that it # becomes a circular reference nuisance, so we make the current item the # base object and singly link in each direction from there. baseObj = obj prevObj = None startOffset = 0 startPartIndex = currentPartIndex or 0 for partIndex in range(startPartIndex, len(self.media.parts)): isCurrentPart = (currentPartIndex is not None and partIndex == currentPartIndex) partObj = util.AttributeDict() partObj.update(baseObj) partObj.live = False partObj.partIndex = partIndex partObj.startOffset = startOffset part = self.media.parts[partIndex] partObj.partDuration = part.duration.asInt() if part.isIndexed(): partObj.sdBifPath = part.getIndexPath("sd") partObj.hdBifPath = part.getIndexPath("hd") # We have to evaluate every part before playback. Normally we'd expect # all parts to be identical, but in reality they can be different. if partIndex > 0 and (not isForced and directPlay or not isCurrentPart): choice = mediadecisionengine.MediaDecisionEngine( ).evaluateMediaVideo(self.item, self.media, partIndex) canDirectPlay = (choice.isDirectPlayable is True) else: canDirectPlay = directPlay if canDirectPlay: partObj = self.buildDirectPlay(partObj, partIndex) else: transcodeServer = self.item.getTranscodeServer(True, "video") if transcodeServer is None: return None partObj = self.buildTranscode(transcodeServer, partObj, partIndex, directStream, isCurrentPart) # Set up our linked list references. If we couldn't build an actual # object: fail fast. Otherwise, see if we're at our start offset # yet in order to decide if we need to link forwards or backwards. # We also need to account for parts missing a duration, by verifying # the prevObj is None or if the startOffset has incremented. if partObj is None: obj = None break elif prevObj is None or (startOffset > 0 and int( self.seekValue / 1000) >= startOffset): obj = partObj partObj.prevObj = prevObj elif prevObj is not None: prevObj.nextPart = partObj startOffset = startOffset + int(part.duration.asInt() / 1000) prevObj = partObj # Only set PlayStart for the initial part, and adjust for the part's offset if obj is not None: if obj.live: # Start the stream at the end. Per Roku, this can be achieved using # a number higher than the duration. Using the current time should # ensure it's definitely high enough. obj.playStart = util.now() + 1800 else: obj.playStart = int(self.seekValue / 1000) - obj.startOffset self.metadata = obj util.LOG("Constructed video item for playback: {0}".format(dict(obj))) return self.metadata
def init(self, item, forceUpdate=False): self.item = item self.choice = mediadecisionengine.MediaDecisionEngine().chooseMedia( item, forceUpdate=forceUpdate) if self.choice: self.media = self.choice.media