Exemplo n.º 1
0
    def push_one_file(self, f):
        file_info = VideoDetails()
        file_info['valid'] = transcode.supported_format(f['path'])

        temp_share = config.get_server('temp_share', '')
        temp_share_path = ''
        if temp_share:
            for name, data in config.getShares():
                if temp_share == name:
                    temp_share_path = data.get('path')

        mime = 'video/mpeg'
        if config.isHDtivo(f['tsn']):
            for m in ['video/mp4', 'video/bif']:
                if transcode.tivo_compatible(f['path'], f['tsn'], m)[0]:
                    mime = m
                    break

            if (mime == 'video/mpeg' and
                transcode.mp4_remuxable(f['path'], f['tsn'])):
                new_path = transcode.mp4_remux(f['path'], f['name'], f['tsn'], temp_share_path)
                if new_path:
                    mime = 'video/mp4'
                    f['name'] = new_path
                    if temp_share_path:
                        ip = config.get_ip()
                        port = config.getPort()
                        container = quote(temp_share) + '/'
                        f['url'] = 'http://%s:%s/%s' % (ip, port, container)

        if file_info['valid']:
            file_info.update(self.metadata_full(f['path'], f['tsn'], mime))

        url = f['url'] + quote(f['name'])

        title = file_info['seriesTitle']
        if not title:
            title = file_info['title']

        source = file_info['seriesId']
        if not source:
            source = title

        subtitle = file_info['episodeTitle']
        try:
            m = mind.getMind(f['tsn'])
            m.pushVideo(
                tsn = f['tsn'],
                url = url,
                description = file_info['description'],
                duration = file_info['duration'] / 1000,
                size = file_info['size'],
                title = title,
                subtitle = subtitle,
                source = source,
                mime = mime,
                tvrating = file_info['tvRating'])
        except Exception, msg:
            logger.error(msg)
Exemplo n.º 2
0
    def __est_size(self, full_path, tsn="", mime=""):
        # Size is estimated by taking audio and video bit rate adding 2%

        if transcode.tivo_compatible(full_path, tsn, mime)[0]:
            return int(os.stat(unicode(full_path, "utf-8")).st_size)
        else:
            # Must be re-encoded
            audioBPS = config.getMaxAudioBR(tsn) * 1000
            # audioBPS = config.strtod(config.getAudioBR(tsn))
            videoBPS = transcode.select_videostr(full_path, tsn)
            bitrate = audioBPS + videoBPS
            return int((self.__duration(full_path) / 1000) * (bitrate * 1.02 / 8))
Exemplo n.º 3
0
    def __est_size(self, full_path, tsn='', mime=''):
        # Size is estimated by taking audio and video bit rate adding 2%

        if transcode.tivo_compatible(full_path, tsn, mime)[0]:
            return os.path.getsize(unicode(full_path, 'utf-8'))
        else:
            # Must be re-encoded
            audioBPS = config.getMaxAudioBR(tsn) * 1000
            #audioBPS = config.strtod(config.getAudioBR(tsn))
            videoBPS = transcode.select_videostr(full_path, tsn)
            bitrate = audioBPS + videoBPS
            return int(
                (self.__duration(full_path) / 1000) * (bitrate * 1.02 / 8))
Exemplo n.º 4
0
    def push_one_file(self, f):
        file_info = VideoDetails()
        file_info['valid'] = transcode.supported_format(f['path'])

        mime = 'video/mpeg'
        if config.isHDtivo(f['tsn']):
            for m in ['video/mp4', 'video/bif']:
                if transcode.tivo_compatible(f['path'], f['tsn'], m)[0]:
                    mime = m
                    break

            if (mime == 'video/mpeg' and
                transcode.mp4_remuxable(f['path'], f['tsn'])):
                new_path = transcode.mp4_remux(f['path'], f['name'], f['tsn'])
                if new_path:
                    mime = 'video/mp4'
                    f['name'] = new_path

        if file_info['valid']:
            file_info.update(self.metadata_full(f['path'], f['tsn'], mime))

        url = f['url'] + quote(f['name'])

        title = file_info['seriesTitle']
        if not title:
            title = file_info['title']

        source = file_info['seriesId']
        if not source:
            source = title

        subtitle = file_info['episodeTitle']
        try:
            m = mind.getMind(f['tsn'])
            m.pushVideo(
                tsn = f['tsn'],
                url = url,
                description = file_info['description'],
                duration = file_info['duration'] / 1000,
                size = file_info['size'],
                title = title,
                subtitle = subtitle,
                source = source,
                mime = mime,
                tvrating = file_info['tvRating'])
        except Exception, msg:
            logger.error(msg)
Exemplo n.º 5
0
    def push_one_file(self, f):
        file_info = VideoDetails()
        file_info["valid"] = transcode.supported_format(f["path"])

        mime = "video/mpeg"
        if config.isHDtivo(f["tsn"]):
            for m in ["video/mp4", "video/bif"]:
                if transcode.tivo_compatible(f["path"], f["tsn"], m)[0]:
                    mime = m
                    break

            if mime == "video/mpeg" and transcode.mp4_remuxable(f["path"], f["tsn"]):
                new_path = transcode.mp4_remux(f["path"], f["name"], f["tsn"])
                if new_path:
                    mime = "video/mp4"
                    f["name"] = new_path

        if file_info["valid"]:
            file_info.update(self.metadata_full(f["path"], f["tsn"], mime))

        url = f["url"] + quote(f["name"])

        title = file_info["seriesTitle"]
        if not title:
            title = file_info["title"]

        source = file_info["seriesId"]
        if not source:
            source = title

        subtitle = file_info["episodeTitle"]
        try:
            m = mind.getMind(f["tsn"])
            m.pushVideo(
                tsn=f["tsn"],
                url=url,
                description=file_info["description"],
                duration=file_info["duration"] / 1000,
                size=file_info["size"],
                title=title,
                subtitle=subtitle,
                source=source,
                mime=mime,
                tvrating=file_info["tvRating"],
            )
        except Exception, msg:
            logger.error(msg)
Exemplo n.º 6
0
    def push_one_file(self, f):
        file_info = VideoDetails()
        file_info['valid'] = transcode.supported_format(f['path'])

        mime = 'video/mpeg'
        if config.isHDtivo(f['tsn']):
            for m in ['video/mp4', 'video/bif']:
                if transcode.tivo_compatible(f['path'], f['tsn'], m)[0]:
                    mime = m
                    break

            if (mime == 'video/mpeg' and
                transcode.mp4_remuxable(f['path'], f['tsn'])):
                new_path = transcode.mp4_remux(f['path'], f['name'], f['tsn'])
                if new_path:
                    mime = 'video/mp4'
                    f['name'] = new_path

        if file_info['valid']:
            file_info.update(self.metadata_full(f['path'], f['tsn'], mime))

        url = f['url'] + quote(f['name'])

        title = file_info['seriesTitle']
        if not title:
            title = file_info['title']

        source = file_info['seriesId']
        if not source:
            source = title

        subtitle = file_info['episodeTitle']
        try:
            m = mind.getMind(f['tsn'])
            m.pushVideo(
                tsn = f['tsn'],
                url = url,
                description = file_info['description'],
                duration = file_info['duration'] / 1000,
                size = file_info['size'],
                title = title,
                subtitle = subtitle,
                source = source,
                mime = mime,
                tvrating = file_info['tvRating'])
        except Exception, msg:
            logger.error(msg)
Exemplo n.º 7
0
    def push_one_file(self, f):
        file_info = VideoDetails()
        file_info['valid'] = transcode.supported_format(f['path'])

        temp_share = config.get_server('temp_share', '')
        temp_share_path = ''
        remux_path = os.path.dirname(f['path'])
        if temp_share:
            for name, data in config.getShares():
                if temp_share == name:
                    temp_share_path = data.get('path')
                    remux_path = temp_share_path

        mime = 'video/mpeg'
        if config.isHDtivo(f['tsn']):
            for m in ['video/mp4', 'video/bif']:
                if transcode.tivo_compatible(f['path'], f['tsn'], m)[0]:
                    mime = m
                    break

            if (mime == 'video/mpeg' and
                transcode.mp4_remuxable(f['path'], f['tsn'])):
                if config.get_freeSpace(remux_path, f['path']):
                    new_path = transcode.mp4_remux(f['path'], f['name'], f['tsn'], temp_share_path)
                    if new_path:
                        mime = 'video/mp4'
                        f['name'] = new_path
                        if temp_share_path:
                            ip = config.get_ip()
                            port = config.getPort()
                            container = quote(temp_share) + '/'
                            f['url'] = 'http://%s:%s/%s' % (ip, port, container)
                else:
                    logger.warning('Not enough disk space to perform remux, ' +
                                   'transcoding instead.')

        if file_info['valid']:
            file_info.update(self.metadata_full(f['path'], f['tsn'], mime))

        url = f['url'] + quote(f['name'])

        title = file_info['seriesTitle']
        if not title:
            title = file_info['title']

        source = file_info['seriesId']
        if not source:
            source = title

        subtitle = file_info['episodeTitle']
        try:
            m = mind.getMind(f['tsn'])
            m.pushVideo(
                tsn = f['tsn'],
                url = url,
                description = file_info['description'],
                duration = file_info['duration'] / 1000,
                size = file_info['size'],
                title = title,
                subtitle = subtitle,
                source = source,
                mime = mime,
                tvrating = file_info['tvRating'])
        except ValueError, msg:
            if 'usernamePasswordError' in msg:
                if f['name'].endswith('.pyTivo-temp'):
                    fname = os.path.join(remux_path, os.path.basename(f['name']))
                    fname = unicode(fname, 'utf-8')
                    os.remove(fname)
                    logger.debug(fname + ' has been removed')
Exemplo n.º 8
0
    def metadata_full(self, full_path, tsn='', mime=''):
        data = {}
        vInfo = transcode.video_info(full_path)

        if ((int(vInfo['vHeight']) >= 720 and
             config.getTivoHeight >= 720) or
            (int(vInfo['vWidth']) >= 1280 and
             config.getTivoWidth >= 1280)):
            data['showingBits'] = '4096'

        data.update(metadata.basic(full_path))
        if full_path[-5:].lower() == '.tivo':
            data.update(metadata.from_tivo(full_path))
        if full_path[-4:].lower() == '.wtv':
            data.update(metadata.from_mscore(vInfo['rawmeta']))

        if 'episodeNumber' in data:
            try:
                ep = int(data['episodeNumber'])
            except:
                ep = 0
            data['episodeNumber'] = str(ep)

        if config.getDebug() and 'vHost' not in data:
            compatible, reason = transcode.tivo_compatible(full_path, tsn, mime)
            if compatible:
                transcode_options = {}
            else:
                transcode_options = transcode.transcode(True, full_path,
                                                        '', tsn, mime)
            data['vHost'] = (
                ['TRANSCODE=%s, %s' % (['YES', 'NO'][compatible], reason)] +
                ['SOURCE INFO: '] +
                ["%s=%s" % (k, v)
                 for k, v in sorted(vInfo.items(), reverse=True)] +
                ['TRANSCODE OPTIONS: '] +
                ["%s" % (v) for k, v in transcode_options.items()] +
                ['SOURCE FILE: ', os.path.basename(full_path)]
            )

        now = datetime.utcnow()
        if 'time' in data:
            if data['time'].lower() == 'file':
                mtime = os.stat(unicode(full_path, 'utf-8')).st_mtime
                if (mtime < 0):
                    mtime = 0
                try:
                    now = datetime.utcfromtimestamp(mtime)
                except:
                    logger.warning('Bad file time on ' + full_path)
            elif data['time'].lower() == 'oad':
                    now = isodt(data['originalAirDate'])
            else:
                try:
                    now = isodt(data['time'])
                except:
                    logger.warning('Bad time format: ' + data['time'] +
                                   ' , using current time')

        duration = self.__duration(full_path)
        duration_delta = timedelta(milliseconds = duration)
        min = duration_delta.seconds / 60
        sec = duration_delta.seconds % 60
        hours = min / 60
        min = min % 60

        data.update({'time': now.isoformat(),
                     'startTime': now.isoformat(),
                     'stopTime': (now + duration_delta).isoformat(),
                     'size': self.__est_size(full_path, tsn, mime),
                     'duration': duration,
                     'iso_duration': ('P%sDT%sH%sM%sS' % 
                          (duration_delta.days, hours, min, sec))})

        return data
Exemplo n.º 9
0
    def send_file(self, handler, path, query):
        mime = 'video/x-tivo-mpeg'
        tsn = handler.headers.getheader('tsn', '')
        tivo_name = config.tivo_names.get(tsn, tsn)

        is_tivo_file = (path[-5:].lower() == '.tivo')

        if 'Format' in query:
            mime = query['Format'][0]

        needs_tivodecode = (is_tivo_file and mime == 'video/mpeg')
        compatible = (not needs_tivodecode and
                      transcode.tivo_compatible(path, tsn, mime)[0])

        try:  # "bytes=XXX-"
            offset = int(handler.headers.getheader('Range')[6:-1])
        except:
            offset = 0

        if needs_tivodecode:
            valid = bool(config.get_bin('tivodecode') and
                         config.get_server('tivo_mak'))
        else:
            valid = True

        if valid and offset:
            valid = ((compatible and offset < os.stat(path).st_size) or
                     (not compatible and transcode.is_resumable(path, offset)))

        #faking = (mime in ['video/x-tivo-mpeg-ts', 'video/x-tivo-mpeg'] and
        faking = (mime == 'video/x-tivo-mpeg' and
                  not (is_tivo_file and compatible))
        fname = unicode(path, 'utf-8')
        thead = ''
        if faking:
            thead = self.tivo_header(tsn, path, mime)
        if compatible:
            size = os.stat(fname).st_size + len(thead)
            handler.send_response(200)
            handler.send_header('Content-Length', size - offset)
            handler.send_header('Content-Range', 'bytes %d-%d/%d' % 
                                (offset, size - offset - 1, size))
        else:
            handler.send_response(206)
            handler.send_header('Transfer-Encoding', 'chunked')
        handler.send_header('Content-Type', mime)
        handler.end_headers()

        logger.info('[%s] Start sending "%s" to %s' %
                    (time.strftime('%d/%b/%Y %H:%M:%S'), fname, tivo_name))
        start = time.time()
        count = 0

        if valid:
            if compatible:
                if faking and not offset:
                    handler.wfile.write(thead)
                logger.debug('"%s" is tivo compatible' % fname)
                f = open(fname, 'rb')
                try:
                    if mime == 'video/mp4':
                        count = qtfaststart.process(f, handler.wfile, offset)
                    else:
                        if offset:
                            offset -= len(thead)
                            f.seek(offset)
                        while True:
                            block = f.read(512 * 1024)
                            if not block:
                                break
                            handler.wfile.write(block)
                            count += len(block)
                except Exception, msg:
                    logger.info(msg)
                f.close()
            else:
                logger.debug('"%s" is not tivo compatible' % fname)
                if offset:
                    count = transcode.resume_transfer(path, handler.wfile, 
                                                      offset)
                else:
                    count = transcode.transcode(False, path, handler.wfile,
                                                tsn, mime, thead)
Exemplo n.º 10
0
    def Push(self, handler, query):
        tsn = query['tsn'][0]
        for key in config.tivo_names:
            if config.tivo_names[key] == tsn:
                tsn = key
                break
        tivo_name = config.tivo_names.get(tsn, tsn)

        container = quote(query['Container'][0].split('/')[0])
        ip = config.get_ip()
        port = config.getPort()

        baseurl = 'http://%s:%s' % (ip, port)
        if config.getIsExternal(tsn):
            exturl = config.get_server('externalurl')
            if exturl:
                baseurl = exturl
            else:
                ip = self.readip()
                baseurl = 'http://%s:%s' % (ip, port)
 
        path = self.get_local_base_path(handler, query)

        files = query.get('File', [])
        for f in files:
            file_path = path + os.path.normpath(f)

            file_info = VideoDetails()
            file_info['valid'] = transcode.supported_format(file_path)

            mime = 'video/mpeg'
            if config.isHDtivo(tsn):
                for m in ['video/mp4', 'video/bif']:
                    if transcode.tivo_compatible(file_path, tsn, m)[0]:
                        mime = m
                        break

            if file_info['valid']:
                file_info.update(self.metadata_full(file_path, tsn, mime))

            url = baseurl + '/%s%s' % (container, quote(f))

            title = file_info['seriesTitle']
            if not title:
                title = file_info['title']

            source = file_info['seriesId']
            if not source:
                source = title

            subtitle = file_info['episodeTitle']
            try:
                m = mind.getMind(tsn)
                m.pushVideo(
                    tsn = tsn,
                    url = url,
                    description = file_info['description'],
                    duration = file_info['duration'] / 1000,
                    size = file_info['size'],
                    title = title,
                    subtitle = subtitle,
                    source = source,
                    mime = mime,
                    tvrating = file_info['tvRating'])
            except Exception, e:
                handler.send_response(500)
                handler.end_headers()
                handler.wfile.write('%s\n\n%s' % (e, traceback.format_exc() ))
                raise

            logger.info('[%s] Queued "%s" for Push to %s' %
                        (time.strftime('%d/%b/%Y %H:%M:%S'),
                         unicode(file_path, 'utf-8'), tivo_name))
Exemplo n.º 11
0
    def metadata_full(self, full_path, tsn='', mime='', mtime=None):
        data = {}
        vInfo = transcode.video_info(full_path)

        if ((int(vInfo['vHeight']) >= 720 and config.getTivoHeight >= 720) or
            (int(vInfo['vWidth']) >= 1280 and config.getTivoWidth >= 1280)):
            data['showingBits'] = '4096'

        data.update(metadata.basic(full_path, mtime))
        if full_path[-5:].lower() == '.tivo':
            data.update(metadata.from_tivo(full_path))
        if full_path[-4:].lower() == '.wtv':
            data.update(metadata.from_mscore(vInfo['rawmeta']))

        if 'episodeNumber' in data:
            try:
                ep = int(data['episodeNumber'])
            except:
                ep = 0
            data['episodeNumber'] = str(ep)

        if config.getDebug() and 'vHost' not in data:
            compatible, reason = transcode.tivo_compatible(
                full_path, tsn, mime)
            if compatible:
                transcode_options = []
            else:
                transcode_options = transcode.transcode(
                    True, full_path, '', None, False, tsn, mime)
            data['vHost'] = (
                ['TRANSCODE=%s, %s' %
                 (['YES', 'NO'][compatible], reason)] + ['SOURCE INFO: '] + [
                     "%s=%s" % (k, v)
                     for k, v in sorted(vInfo.items(), reverse=True)
                 ] + ['TRANSCODE OPTIONS: '] + transcode_options +
                ['SOURCE FILE: ', os.path.basename(full_path)])

        now = datetime.utcnow()
        if 'time' in data:
            if data['time'].lower() == 'file':
                if not mtime:
                    mtime = os.path.getmtime(unicode(full_path, 'utf-8'))
                try:
                    now = datetime.utcfromtimestamp(mtime)
                except:
                    logger.warning('Bad file time on ' + full_path)
            elif data['time'].lower() == 'oad':
                now = isodt(data['originalAirDate'])
            else:
                try:
                    now = isodt(data['time'])
                except:
                    logger.warning('Bad time format: ' + data['time'] +
                                   ' , using current time')

        duration = self.__duration(full_path)
        duration_delta = timedelta(milliseconds=duration)
        min = duration_delta.seconds / 60
        sec = duration_delta.seconds % 60
        hours = min / 60
        min = min % 60

        data.update({
            'time':
            now.isoformat(),
            'startTime':
            now.isoformat(),
            'stopTime': (now + duration_delta).isoformat(),
            'size':
            self.__est_size(full_path, tsn, mime),
            'duration':
            duration,
            'iso_duration':
            ('P%sDT%sH%sM%sS' % (duration_delta.days, hours, min, sec))
        })

        return data
Exemplo n.º 12
0
        tivo_mak = config.get_tsn('tivo_mak', tsn)
        has_tivolibre = bool(config.get_bin('tivolibre'))
        has_tivodecode = bool(config.get_bin('tivodecode'))

        use_tivolibre = False
        if has_tivolibre and bool(config.get_server('tivolibre_upload', True)):
            use_tivolibre = True

        if 'Format' in query:
            mime = query['Format'][0]

        needs_converion = (((is_tivo_file and is_tivo_ts) or
                            (is_tivo_file and not has_tivolibre))
                           and mime == 'video/mpeg')
        compatible = (not needs_converion
                      and transcode.tivo_compatible(path, tsn, mime)[0])

        try:  # "bytes=XXX-"
            offset = int(handler.headers.getheader('Range')[6:-1])
        except:
            offset = 0

        if needs_converion:
            valid = bool((has_tivodecode or has_tivolibre) and tivo_mak)
        else:
            valid = True

        if valid and offset:
            valid = ((compatible and offset < os.path.getsize(path)) or
                     (not compatible and transcode.is_resumable(path, offset)))
Exemplo n.º 13
0
    def send_file(self, handler, path, query):
        mime = 'video/x-tivo-mpeg'
        tsn = handler.headers.getheader('tsn', '')
        try:
            assert (tsn)
            tivo_name = config.tivos[tsn].get('name', tsn)
        except:
            tivo_name = handler.address_string()

        is_tivo_file = (path[-5:].lower() == '.tivo')

        if 'Format' in query:
            mime = query['Format'][0]

        needs_tivodecode = (is_tivo_file and mime == 'video/mpeg')
        compatible = (not needs_tivodecode
                      and transcode.tivo_compatible(path, tsn, mime)[0])

        try:  # "bytes=XXX-"
            offset = int(handler.headers.getheader('Range')[6:-1])
        except:
            offset = 0

        if needs_tivodecode:
            valid = bool(
                config.get_bin('tivodecode') and config.get_server('tivo_mak'))
        else:
            valid = True

        if valid and offset:
            valid = ((compatible and offset < os.path.getsize(path)) or
                     (not compatible and transcode.is_resumable(path, offset)))

        #faking = (mime in ['video/x-tivo-mpeg-ts', 'video/x-tivo-mpeg'] and
        faking = (mime == 'video/x-tivo-mpeg'
                  and not (is_tivo_file and compatible))
        fname = unicode(path, 'utf-8')
        thead = ''
        if faking:
            thead = self.tivo_header(tsn, path, mime)
        if compatible:
            size = os.path.getsize(fname) + len(thead)
            handler.send_response(200)
            handler.send_header('Content-Length', size - offset)
            handler.send_header(
                'Content-Range',
                'bytes %d-%d/%d' % (offset, size - offset - 1, size))
        else:
            handler.send_response(206)
            handler.send_header('Transfer-Encoding', 'chunked')
        handler.send_header('Content-Type', mime)
        handler.end_headers()

        logger.info('[%s] Start sending "%s" to %s' %
                    (time.strftime('%d/%b/%Y %H:%M:%S'), fname, tivo_name))
        start = time.time()
        count = 0

        if valid:
            if compatible:
                if faking and not offset:
                    handler.wfile.write(thead)
                logger.debug('"%s" is tivo compatible' % fname)
                f = open(fname, 'rb')
                try:
                    if mime == 'video/mp4':
                        count = qtfaststart.process(f, handler.wfile, offset)
                    else:
                        if offset:
                            offset -= len(thead)
                            f.seek(offset)
                        while True:
                            block = f.read(512 * 1024)
                            if not block:
                                break
                            handler.wfile.write(block)
                            count += len(block)
                except Exception, msg:
                    logger.info(msg)
                f.close()
            else:
                logger.debug('"%s" is not tivo compatible' % fname)
                if offset:
                    count = transcode.resume_transfer(path, handler.wfile,
                                                      offset)
                else:
                    count = transcode.transcode(False, path, handler.wfile,
                                                tsn, mime, thead)
Exemplo n.º 14
0
    def metadata_full(self, full_path, tsn="", mime=""):
        data = {}
        vInfo = transcode.video_info(full_path)

        if (int(vInfo["vHeight"]) >= 720 and config.getTivoHeight >= 720) or (
            int(vInfo["vWidth"]) >= 1280 and config.getTivoWidth >= 1280
        ):
            data["showingBits"] = "4096"

        data.update(metadata.basic(full_path))
        if full_path[-5:].lower() == ".tivo":
            data.update(metadata.from_tivo(full_path))
        if full_path[-4:].lower() == ".wtv":
            data.update(metadata.from_mscore(vInfo["rawmeta"]))

        if "episodeNumber" in data:
            try:
                ep = int(data["episodeNumber"])
            except:
                ep = 0
            data["episodeNumber"] = str(ep)

        if config.getDebug() and "vHost" not in data:
            compatible, reason = transcode.tivo_compatible(full_path, tsn, mime)
            if compatible:
                transcode_options = {}
            else:
                transcode_options = transcode.transcode(True, full_path, "", tsn, mime)
            data["vHost"] = (
                ["TRANSCODE=%s, %s" % (["YES", "NO"][compatible], reason)]
                + ["SOURCE INFO: "]
                + ["%s=%s" % (k, v) for k, v in sorted(vInfo.items(), reverse=True)]
                + ["TRANSCODE OPTIONS: "]
                + ["%s" % (v) for k, v in transcode_options.items()]
                + ["SOURCE FILE: ", os.path.basename(full_path)]
            )

        now = datetime.utcnow()
        if "time" in data:
            if data["time"].lower() == "file":
                mtime = os.stat(unicode(full_path, "utf-8")).st_mtime
                if mtime < 0:
                    mtime = 0
                try:
                    now = datetime.utcfromtimestamp(mtime)
                except:
                    logger.warning("Bad file time on " + full_path)
            elif data["time"].lower() == "oad":
                now = isodt(data["originalAirDate"])
            else:
                try:
                    now = isodt(data["time"])
                except:
                    logger.warning("Bad time format: " + data["time"] + " , using current time")

        duration = self.__duration(full_path)
        duration_delta = timedelta(milliseconds=duration)
        min = duration_delta.seconds / 60
        sec = duration_delta.seconds % 60
        hours = min / 60
        min = min % 60

        data.update(
            {
                "time": now.isoformat(),
                "startTime": now.isoformat(),
                "stopTime": (now + duration_delta).isoformat(),
                "size": self.__est_size(full_path, tsn, mime),
                "duration": duration,
                "iso_duration": ("P%sDT%sH%sM%sS" % (duration_delta.days, hours, min, sec)),
            }
        )

        return data
Exemplo n.º 15
0
    def send_file(self, handler, path, query):
        mime = "video/x-tivo-mpeg"
        tsn = handler.headers.getheader("tsn", "")
        tivo_name = config.tivo_names.get(tsn, tsn)

        is_tivo_file = path[-5:].lower() == ".tivo"

        if "Format" in query:
            mime = query["Format"][0]

        needs_tivodecode = is_tivo_file and mime == "video/mpeg"
        compatible = not needs_tivodecode and transcode.tivo_compatible(path, tsn, mime)[0]

        try:  # "bytes=XXX-"
            offset = int(handler.headers.getheader("Range")[6:-1])
        except:
            offset = 0

        if needs_tivodecode:
            valid = bool(config.get_bin("tivodecode") and config.get_server("tivo_mak"))
        else:
            valid = True

        if valid and offset:
            valid = (compatible and offset < os.stat(path).st_size) or (
                not compatible and transcode.is_resumable(path, offset)
            )

        # faking = (mime in ['video/x-tivo-mpeg-ts', 'video/x-tivo-mpeg'] and
        faking = mime == "video/x-tivo-mpeg" and not (is_tivo_file and compatible)
        fname = unicode(path, "utf-8")
        thead = ""
        if faking:
            thead = self.tivo_header(tsn, path, mime)
        if compatible:
            size = os.stat(fname).st_size + len(thead)
            handler.send_response(200)
            handler.send_header("Content-Length", size - offset)
            handler.send_header("Content-Range", "bytes %d-%d/%d" % (offset, size - offset - 1, size))
        else:
            handler.send_response(206)
            handler.send_header("Transfer-Encoding", "chunked")
        handler.send_header("Content-Type", mime)
        handler.send_header("Connection", "close")
        handler.end_headers()

        logger.info('[%s] Start sending "%s" to %s' % (time.strftime("%d/%b/%Y %H:%M:%S"), fname, tivo_name))
        start = time.time()
        count = 0

        if valid:
            if compatible:
                if faking and not offset:
                    handler.wfile.write(thead)
                logger.debug('"%s" is tivo compatible' % fname)
                f = open(fname, "rb")
                try:
                    if mime == "video/mp4":
                        count = qtfaststart.process(f, handler.wfile, offset)
                    else:
                        if offset:
                            offset -= len(thead)
                            f.seek(offset)
                        while True:
                            block = f.read(512 * 1024)
                            if not block:
                                break
                            handler.wfile.write(block)
                            count += len(block)
                except Exception, msg:
                    logger.info(msg)
                f.close()
            else:
                logger.debug('"%s" is not tivo compatible' % fname)
                if offset:
                    count = transcode.resume_transfer(path, handler.wfile, offset)
                else:
                    count = transcode.transcode(False, path, handler.wfile, tsn, mime, thead)