Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
 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