Пример #1
0
    def loadDvdMeta(self, metadir, opts, basefn, deftitle, singleDVDtitle):
        metapath = os.path.join(metadir, basefn)
        meta = metadata.from_text(metapath, opts['metamergefiles'],
                                  opts['metamergelines'])
        if (not 'title' in meta) or (meta['title'] == basefn):
            meta['title'] = deftitle

        titles = []
        kl = meta.keys()
        for k in kl:
            x = regex.search(k)
            if x:
                tn = int(x.group(1))
                if meta[k].lower().startswith("ignore"):
                    del (meta[k])
                else:
                    filename = "__T%02d.mpg" % tn
                    titles.append((meta[k], filename, tn))

                    if (singleDVDtitle):
                        del (meta[k])

        if len(titles) == 0:
            titles.append((meta['title'], "__T00.mpg", 0))

        return (meta, titles)
Пример #2
0
	def loadDvdMeta(self, metadir, opts, basefn, deftitle, singleDVDtitle):
		metapath = os.path.join(metadir, basefn)
		meta = metadata.from_text(metapath, opts['metamergefiles'], opts['metamergelines'])
		if (not 'title' in meta) or (meta['title'] == basefn):
			meta['title'] = deftitle

		titles = []
		kl = meta.keys()
		for k in kl:
			x = regex.search(k)
			if x:
				tn = int(x.group(1))
				if meta[k].lower().startswith("ignore"):
					del(meta[k])
				else:
					filename = "__T%02d.mpg" % tn
					titles.append((meta[k], filename, tn))

					if (singleDVDtitle):
						del(meta[k])

		if len(titles) == 0:
			titles.append((meta['title'], "__T00.mpg", 0))
			
		return (meta, titles)
Пример #3
0
    def __init__(self, opts, name, root, vidlist, harvesters):
        self.name = name
        self.title = name
        self.opts = opts.copy()
        self.count = 0
        self.root = root
        self.videoDir = VideoDir(opts, "", "", root, name)

        tree = myWalk(root)

        sharedirs = {"": self.videoDir}
        shareopts = {"": self.opts}

        for path, dirs, files in tree:
            rpath = path[len(root) :]
            if rpath.startswith(os.path.sep):
                rpath = rpath[1:]
            if rpath not in sharedirs:
                continue
            vl = sharedirs[rpath]
            lopts = shareopts[rpath]
            Config.addLocalOpts(lopts, root, rpath)
            vl.setOpts(lopts)

            for name in dirs:
                if name.startswith("."):
                    continue
                meta = metadata.from_text(
                    os.path.join(path, name, "folder"),
                    lopts["metamergefiles"],
                    lopts["metamergelines"],
                    lopts["metamergeparent"],
                )
                d = VideoDir(lopts, name, rpath, path, self.name)
                d.setMeta(meta)
                vl.addDir(d)
                sharedirs[os.path.join(rpath, name)] = d
                shareopts[os.path.join(rpath, name)] = lopts.copy()

            for name in files:
                if name.startswith("."):
                    continue
                if os.path.splitext(name)[1].lower() in lopts["goodexts"]:
                    fid = fileId(os.path.join(path, name))
                    if fid != None:
                        vf = vidlist.findVideo(fid)
                    else:
                        vf = None

                    if vf == None:
                        vf = VideoFile(lopts, path, name, fid)
                        vidlist.addVideo(vf)

                        meta = metadata.from_text(
                            os.path.join(path, name),
                            lopts["metamergefiles"],
                            lopts["metamergelines"],
                            lopts["metamergeparent"],
                        )
                        if not "title" in meta:
                            meta = metadata.basic(os.path.join(path, name))
                        vf.setMeta(meta)

                        vl.addVideo(vf)
                        self.count += 1

                        for h in harvesters:
                            h.harvest(vf)

                    else:
                        vl.addVideo(vf, path=path, fn=name)
                        self.count += 1

            vl.sort()
Пример #4
0
def video_info(inFile, cache=True):
    vInfo = dict()
    fname = unicode(inFile, 'utf-8')
    mtime = os.stat(fname).st_mtime
    if cache:
        if inFile in info_cache and info_cache[inFile][0] == mtime:
            debug('CACHE HIT! %s' % inFile)
            return info_cache[inFile][1]

    vInfo['Supported'] = True

    ffmpeg_path = config.get_bin('ffmpeg')
    if not ffmpeg_path:
        if os.path.splitext(inFile)[1].lower() not in ['.mpg', '.mpeg',
                                                       '.vob', '.tivo']:
            vInfo['Supported'] = False
        vInfo.update({'millisecs': 0, 'vWidth': 704, 'vHeight': 480,
                      'rawmeta': {}})
        if cache:
            info_cache[inFile] = (mtime, vInfo)
        return vInfo

    if mswindows:
        fname = fname.encode('iso8859-1')
    cmd = [ffmpeg_path, '-i', fname]
    # Windows and other OS buffer 4096 and ffmpeg can output more than that.
    err_tmp = tempfile.TemporaryFile()
    ffmpeg = subprocess.Popen(cmd, stderr=err_tmp, stdout=subprocess.PIPE,
                              stdin=subprocess.PIPE)

    # wait configured # of seconds: if ffmpeg is not back give up
    limit = config.getFFmpegWait()
    if limit:
        for i in xrange(limit * 20):
            time.sleep(.05)
            if not ffmpeg.poll() == None:
                break

        if ffmpeg.poll() == None:
            kill(ffmpeg)
            vInfo['Supported'] = False
            if cache:
                info_cache[inFile] = (mtime, vInfo)
            return vInfo
    else:
        ffmpeg.wait()

    err_tmp.seek(0)
    output = err_tmp.read()
    err_tmp.close()
    debug('ffmpeg output=%s' % output)

    attrs = {'container': r'Input #0, ([^,]+),',
             'vCodec': r'Video: ([^, ]+)',             # video codec
             'aKbps': r'.*Audio: .+, (.+) (?:kb/s).*',     # audio bitrate
             'aCodec': r'.*Audio: ([^, ]+)',             # audio codec
             'aFreq': r'.*Audio: .+, (.+) (?:Hz).*',       # audio frequency
             'mapVideo': r'([0-9]+[.:]+[0-9]+).*: Video:.*'}  # video mapping

    for attr in attrs:
        rezre = re.compile(attrs[attr])
        x = rezre.search(output)
        if x:
            vInfo[attr] = x.group(1)
        else:
            if attr in ['container', 'vCodec']:
                vInfo[attr] = ''
                vInfo['Supported'] = False
            else:
                vInfo[attr] = None
            debug('failed at ' + attr)

    rezre = re.compile(r'.*Audio: .+, (?:(\d+)(?:(?:\.(\d).*)?(?: channels.*)?)|(stereo|mono)),.*')
    x = rezre.search(output)
    if x:
        if x.group(3):
            if x.group(3) == 'stereo':
                vInfo['aCh'] = 2
            elif x.group(3) == 'mono':
                vInfo['aCh'] = 1
        elif x.group(2):
            vInfo['aCh'] = int(x.group(1)) + int(x.group(2))
        elif x.group(1):
            vInfo['aCh'] = int(x.group(1))
        else:
            vInfo['aCh'] = None
            debug('failed at aCh')
    else:
        vInfo['aCh'] = None
        debug('failed at aCh')

    rezre = re.compile(r'.*Video: .+, (\d+)x(\d+)[, ].*')
    x = rezre.search(output)
    if x:
        vInfo['vWidth'] = int(x.group(1))
        vInfo['vHeight'] = int(x.group(2))
    else:
        vInfo['vWidth'] = ''
        vInfo['vHeight'] = ''
        vInfo['Supported'] = False
        debug('failed at vWidth/vHeight')

    rezre = re.compile(r'.*Video: .+, (.+) (?:fps|tb\(r\)|tbr).*')
    x = rezre.search(output)
    if x:
        vInfo['vFps'] = x.group(1)
        if '.' not in vInfo['vFps']:
            vInfo['vFps'] += '.00'

        # Allow override only if it is mpeg2 and frame rate was doubled
        # to 59.94

        if vInfo['vCodec'] == 'mpeg2video' and vInfo['vFps'] != '29.97':
            # First look for the build 7215 version
            rezre = re.compile(r'.*film source: 29.97.*')
            x = rezre.search(output.lower())
            if x:
                debug('film source: 29.97 setting vFps to 29.97')
                vInfo['vFps'] = '29.97'
            else:
                # for build 8047:
                rezre = re.compile(r'.*frame rate differs from container ' +
                                   r'frame rate: 29.97.*')
                debug('Bug in VideoReDo')
                x = rezre.search(output.lower())
                if x:
                    vInfo['vFps'] = '29.97'
    else:
        vInfo['vFps'] = ''
        vInfo['Supported'] = False
        debug('failed at vFps')

    durre = re.compile(r'.*Duration: ([0-9]+):([0-9]+):([0-9]+)\.([0-9]+),')
    d = durre.search(output)

    if d:
        vInfo['millisecs'] = ((int(d.group(1)) * 3600 +
                               int(d.group(2)) * 60 +
                               int(d.group(3))) * 1000 +
                              int(d.group(4)) * (10 ** (3 - len(d.group(4)))))
    else:
        vInfo['millisecs'] = 0

    # get bitrate of source for tivo compatibility test.
    rezre = re.compile(r'.*bitrate: (.+) (?:kb/s).*')
    x = rezre.search(output)
    if x:
        vInfo['kbps'] = x.group(1)
    else:
        # Fallback method of getting video bitrate
        # Sample line:  Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p,
        #               720x480 [PAR 32:27 DAR 16:9], 9800 kb/s, 59.94 tb(r)
        rezre = re.compile(r'.*Stream #0\.0\[.*\]: Video: mpeg2video, ' +
                           r'\S+, \S+ \[.*\], (\d+) (?:kb/s).*')
        x = rezre.search(output)
        if x:
            vInfo['kbps'] = x.group(1)
        else:
            vInfo['kbps'] = None
            debug('failed at kbps')

    # get par.
    rezre = re.compile(r'.*Video: .+PAR ([0-9]+):([0-9]+) DAR [0-9:]+.*')
    x = rezre.search(output)
    if x and x.group(1) != "0" and x.group(2) != "0":
        vInfo['par1'] = x.group(1) + ':' + x.group(2)
        vInfo['par2'] = float(x.group(1)) / float(x.group(2))
    else:
        vInfo['par1'], vInfo['par2'] = None, None

    # get dar.
    rezre = re.compile(r'.*Video: .+DAR ([0-9]+):([0-9]+).*')
    x = rezre.search(output)
    if x and x.group(1) != "0" and x.group(2) != "0":
        vInfo['dar1'] = x.group(1) + ':' + x.group(2)
    else:
        vInfo['dar1'] = None

    # get Audio Stream mapping.
    rezre = re.compile(r'([0-9]+[.:]+[0-9]+)(.*): Audio:(.*)')
    x = rezre.search(output)
    amap = []
    if x:
        for x in rezre.finditer(output):
            amap.append((x.group(1), x.group(2) + x.group(3)))
    else:
        amap.append(('', ''))
        debug('failed at mapAudio')
    vInfo['mapAudio'] = amap

    vInfo['par'] = None

    # get Metadata dump (newer ffmpeg).
    lines = output.split('\n')
    rawmeta = {}
    flag = False

    for line in lines:
        if line.startswith('  Metadata:'):
            flag = True
        else:
            if flag:
                if line.startswith('  Duration:'):
                    flag = False
                else:
                    try:
                        key, value = [x.strip() for x in line.split(':', 1)]
                        try:
                            value = value.decode('utf-8')
                        except:
                            if sys.platform == 'darwin':
                                value = value.decode('macroman')
                            else:
                                value = value.decode('iso8859-1')
                        rawmeta[key] = [value]
                    except:
                        pass

    vInfo['rawmeta'] = rawmeta

    data = metadata.from_text(inFile)
    for key in data:
        if key.startswith('Override_'):
            vInfo['Supported'] = True
            if key.startswith('Override_mapAudio'):
                audiomap = dict(vInfo['mapAudio'])
                newmap = shlex.split(data[key])
                audiomap.update(zip(newmap[::2], newmap[1::2]))
                vInfo['mapAudio'] = sorted(audiomap.items(),
                                           key=lambda (k,v): (k,v))
            elif key.startswith('Override_millisecs'):
                vInfo[key.replace('Override_', '')] = int(data[key])
            else:
                vInfo[key.replace('Override_', '')] = data[key]

    if cache:
        info_cache[inFile] = (mtime, vInfo)
    debug("; ".join(["%s=%s" % (k, v) for k, v in vInfo.items()]))
    return vInfo
Пример #5
0
def video_info(inFile, cache=True):
    vInfo = dict()
    fname = unicode(inFile, "utf-8")
    mtime = os.path.getmtime(fname)
    if cache:
        if inFile in info_cache and info_cache[inFile][0] == mtime:
            debug("CACHE HIT! %s" % inFile)
            return info_cache[inFile][1]

    vInfo["Supported"] = True

    ffmpeg_path = config.get_bin("ffmpeg")
    if not ffmpeg_path:
        if os.path.splitext(inFile)[1].lower() not in [".mpg", ".mpeg", ".vob", ".tivo", ".ts"]:
            vInfo["Supported"] = False
        vInfo.update({"millisecs": 0, "vWidth": 704, "vHeight": 480, "rawmeta": {}})
        if cache:
            info_cache[inFile] = (mtime, vInfo)
        return vInfo

    if mswindows:
        fname = fname.encode("cp1252")
    cmd = [ffmpeg_path, "-i", fname]
    # Windows and other OS buffer 4096 and ffmpeg can output more than that.
    err_tmp = tempfile.TemporaryFile()
    ffmpeg = subprocess.Popen(cmd, stderr=err_tmp, stdout=subprocess.PIPE, stdin=subprocess.PIPE)

    # wait configured # of seconds: if ffmpeg is not back give up
    limit = config.getFFmpegWait()
    if limit:
        for i in xrange(limit * 20):
            time.sleep(0.05)
            if not ffmpeg.poll() == None:
                break

        if ffmpeg.poll() == None:
            kill(ffmpeg)
            vInfo["Supported"] = False
            if cache:
                info_cache[inFile] = (mtime, vInfo)
            return vInfo
    else:
        ffmpeg.wait()

    err_tmp.seek(0)
    output = err_tmp.read()
    err_tmp.close()
    debug("ffmpeg output=%s" % output)

    attrs = {
        "container": r"Input #0, ([^,]+),",
        "vCodec": r"Video: ([^, ]+)",  # video codec
        "aKbps": r".*Audio: .+, (.+) (?:kb/s).*",  # audio bitrate
        "aCodec": r".*Audio: ([^, ]+)",  # audio codec
        "aFreq": r".*Audio: .+, (.+) (?:Hz).*",  # audio frequency
        "mapVideo": r"([0-9]+[.:]+[0-9]+).*: Video:.*",
    }  # video mapping

    for attr in attrs:
        rezre = re.compile(attrs[attr])
        x = rezre.search(output)
        if x:
            vInfo[attr] = x.group(1)
        else:
            if attr in ["container", "vCodec"]:
                vInfo[attr] = ""
                vInfo["Supported"] = False
            else:
                vInfo[attr] = None
            debug("failed at " + attr)

    rezre = re.compile(r".*Audio: .+, (?:(\d+)(?:(?:\.(\d).*)?(?: channels.*)?)|(stereo|mono)),.*")
    x = rezre.search(output)
    if x:
        if x.group(3):
            if x.group(3) == "stereo":
                vInfo["aCh"] = 2
            elif x.group(3) == "mono":
                vInfo["aCh"] = 1
        elif x.group(2):
            vInfo["aCh"] = int(x.group(1)) + int(x.group(2))
        elif x.group(1):
            vInfo["aCh"] = int(x.group(1))
        else:
            vInfo["aCh"] = None
            debug("failed at aCh")
    else:
        vInfo["aCh"] = None
        debug("failed at aCh")

    rezre = re.compile(r".*Video: .+, (\d+)x(\d+)[, ].*")
    x = rezre.search(output)
    if x:
        vInfo["vWidth"] = int(x.group(1))
        vInfo["vHeight"] = int(x.group(2))
    else:
        vInfo["vWidth"] = ""
        vInfo["vHeight"] = ""
        vInfo["Supported"] = False
        debug("failed at vWidth/vHeight")

    rezre = re.compile(r".*Video: .+, (.+) (?:fps|tb\(r\)|tbr).*")
    x = rezre.search(output)
    if x:
        vInfo["vFps"] = x.group(1)
        if "." not in vInfo["vFps"]:
            vInfo["vFps"] += ".00"

        # Allow override only if it is mpeg2 and frame rate was doubled
        # to 59.94

        if vInfo["vCodec"] == "mpeg2video" and vInfo["vFps"] != "29.97":
            # First look for the build 7215 version
            rezre = re.compile(r".*film source: 29.97.*")
            x = rezre.search(output.lower())
            if x:
                debug("film source: 29.97 setting vFps to 29.97")
                vInfo["vFps"] = "29.97"
            else:
                # for build 8047:
                rezre = re.compile(r".*frame rate differs from container " + r"frame rate: 29.97.*")
                debug("Bug in VideoReDo")
                x = rezre.search(output.lower())
                if x:
                    vInfo["vFps"] = "29.97"
    else:
        vInfo["vFps"] = ""
        vInfo["Supported"] = False
        debug("failed at vFps")

    durre = re.compile(r".*Duration: ([0-9]+):([0-9]+):([0-9]+)\.([0-9]+),")
    d = durre.search(output)

    if d:
        vInfo["millisecs"] = (int(d.group(1)) * 3600 + int(d.group(2)) * 60 + int(d.group(3))) * 1000 + int(
            d.group(4)
        ) * (10 ** (3 - len(d.group(4))))
    else:
        vInfo["millisecs"] = 0

    # get bitrate of source for tivo compatibility test.
    rezre = re.compile(r".*bitrate: (.+) (?:kb/s).*")
    x = rezre.search(output)
    if x:
        vInfo["kbps"] = x.group(1)
    else:
        # Fallback method of getting video bitrate
        # Sample line:  Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p,
        #               720x480 [PAR 32:27 DAR 16:9], 9800 kb/s, 59.94 tb(r)
        rezre = re.compile(r".*Stream #0\.0\[.*\]: Video: mpeg2video, " + r"\S+, \S+ \[.*\], (\d+) (?:kb/s).*")
        x = rezre.search(output)
        if x:
            vInfo["kbps"] = x.group(1)
        else:
            vInfo["kbps"] = None
            debug("failed at kbps")

    # get par.
    rezre = re.compile(r".*Video: .+PAR ([0-9]+):([0-9]+) DAR [0-9:]+.*")
    x = rezre.search(output)
    if x and x.group(1) != "0" and x.group(2) != "0":
        vInfo["par1"] = x.group(1) + ":" + x.group(2)
        vInfo["par2"] = float(x.group(1)) / float(x.group(2))
    else:
        vInfo["par1"], vInfo["par2"] = None, None

    # get dar.
    rezre = re.compile(r".*Video: .+DAR ([0-9]+):([0-9]+).*")
    x = rezre.search(output)
    if x and x.group(1) != "0" and x.group(2) != "0":
        vInfo["dar1"] = x.group(1) + ":" + x.group(2)
    else:
        vInfo["dar1"] = None

    # get Audio Stream mapping.
    rezre = re.compile(r"([0-9]+[.:]+[0-9]+)(.*): Audio:(.*)")
    x = rezre.search(output)
    amap = []
    if x:
        for x in rezre.finditer(output):
            amap.append((x.group(1), x.group(2) + x.group(3)))
    else:
        amap.append(("", ""))
        debug("failed at mapAudio")
    vInfo["mapAudio"] = amap

    vInfo["par"] = None

    # get Metadata dump (newer ffmpeg).
    lines = output.split("\n")
    rawmeta = {}
    flag = False

    for line in lines:
        if line.startswith("  Metadata:"):
            flag = True
        else:
            if flag:
                if line.startswith("  Duration:"):
                    flag = False
                else:
                    try:
                        key, value = [x.strip() for x in line.split(":", 1)]
                        try:
                            value = value.decode("utf-8")
                        except:
                            if sys.platform == "darwin":
                                value = value.decode("macroman")
                            else:
                                value = value.decode("cp1252")
                        rawmeta[key] = [value]
                    except:
                        pass

    vInfo["rawmeta"] = rawmeta

    data = metadata.from_text(inFile)
    for key in data:
        if key.startswith("Override_"):
            vInfo["Supported"] = True
            if key.startswith("Override_mapAudio"):
                audiomap = dict(vInfo["mapAudio"])
                newmap = shlex.split(data[key])
                audiomap.update(zip(newmap[::2], newmap[1::2]))
                vInfo["mapAudio"] = sorted(audiomap.items(), key=lambda (k, v): (k, v))
            elif key.startswith("Override_millisecs"):
                vInfo[key.replace("Override_", "")] = int(data[key])
            else:
                vInfo[key.replace("Override_", "")] = data[key]

    if cache:
        info_cache[inFile] = (mtime, vInfo)
    debug("; ".join(["%s=%s" % (k, v) for k, v in vInfo.items()]))
    return vInfo
Пример #6
0
def video_info(inFile, cache=True):
    vInfo = dict()
    fname = unicode(inFile, 'utf-8')
    mtime = os.path.getmtime(fname)
    if cache:
        if inFile in info_cache and info_cache[inFile][0] == mtime:
            debug('CACHE HIT! %s' % inFile)
            return info_cache[inFile][1]

    vInfo['Supported'] = True

    ffmpeg_path = config.get_bin('ffmpeg')
    if not ffmpeg_path:
        if os.path.splitext(inFile)[1].lower() not in [
                '.mpg', '.mpeg', '.vob', '.tivo', '.ts'
        ]:
            vInfo['Supported'] = False
        vInfo.update({
            'millisecs': 0,
            'vWidth': 704,
            'vHeight': 480,
            'rawmeta': {}
        })
        if cache:
            info_cache[inFile] = (mtime, vInfo)
        return vInfo

    if mswindows:
        fname = fname.encode('cp1252')
    cmd = [ffmpeg_path, '-i', fname]
    # Windows and other OS buffer 4096 and ffmpeg can output more than that.
    err_tmp = tempfile.TemporaryFile()
    ffmpeg = subprocess.Popen(cmd,
                              stderr=err_tmp,
                              stdout=subprocess.PIPE,
                              stdin=subprocess.PIPE)

    # wait configured # of seconds: if ffmpeg is not back give up
    limit = config.getFFmpegWait()
    if limit:
        for i in xrange(limit * 20):
            time.sleep(.05)
            if not ffmpeg.poll() == None:
                break

        if ffmpeg.poll() == None:
            kill(ffmpeg)
            vInfo['Supported'] = False
            if cache:
                info_cache[inFile] = (mtime, vInfo)
            return vInfo
    else:
        ffmpeg.wait()

    err_tmp.seek(0)
    output = err_tmp.read()
    err_tmp.close()
    debug('ffmpeg output=%s' % output)

    attrs = {
        'container': r'Input #0, ([^,]+),',
        'vCodec': r'Video: ([^, ]+)',  # video codec
        'aKbps': r'.*Audio: .+, (.+) (?:kb/s).*',  # audio bitrate
        'aCodec': r'.*Audio: ([^, ]+)',  # audio codec
        'aFreq': r'.*Audio: .+, (.+) (?:Hz).*',  # audio frequency
        'mapVideo': r'([0-9]+[.:]+[0-9]+).*: Video:.*'
    }  # video mapping

    for attr in attrs:
        rezre = re.compile(attrs[attr])
        x = rezre.search(output)
        if x:
            vInfo[attr] = x.group(1)
        else:
            if attr in ['container', 'vCodec']:
                vInfo[attr] = ''
                vInfo['Supported'] = False
            else:
                vInfo[attr] = None
            debug('failed at ' + attr)

    rezre = re.compile(
        r'.*Audio: .+, (?:(\d+)(?:(?:\.(\d).*)?(?: channels.*)?)|(stereo|mono)),.*'
    )
    x = rezre.search(output)
    if x:
        if x.group(3):
            if x.group(3) == 'stereo':
                vInfo['aCh'] = 2
            elif x.group(3) == 'mono':
                vInfo['aCh'] = 1
        elif x.group(2):
            vInfo['aCh'] = int(x.group(1)) + int(x.group(2))
        elif x.group(1):
            vInfo['aCh'] = int(x.group(1))
        else:
            vInfo['aCh'] = None
            debug('failed at aCh')
    else:
        vInfo['aCh'] = None
        debug('failed at aCh')

    rezre = re.compile(r'.*Video: .+, (\d+)x(\d+)[, ].*')
    x = rezre.search(output)
    if x:
        vInfo['vWidth'] = int(x.group(1))
        vInfo['vHeight'] = int(x.group(2))
    else:
        vInfo['vWidth'] = ''
        vInfo['vHeight'] = ''
        vInfo['Supported'] = False
        debug('failed at vWidth/vHeight')

    rezre = re.compile(r'.*Video: .+, (.+) (?:fps|tb\(r\)|tbr).*')
    x = rezre.search(output)
    if x:
        vInfo['vFps'] = x.group(1)
        if '.' not in vInfo['vFps']:
            vInfo['vFps'] += '.00'

        # Allow override only if it is mpeg2 and frame rate was doubled
        # to 59.94

        if vInfo['vCodec'] == 'mpeg2video' and vInfo['vFps'] != '29.97':
            # First look for the build 7215 version
            rezre = re.compile(r'.*film source: 29.97.*')
            x = rezre.search(output.lower())
            if x:
                debug('film source: 29.97 setting vFps to 29.97')
                vInfo['vFps'] = '29.97'
            else:
                # for build 8047:
                rezre = re.compile(r'.*frame rate differs from container ' +
                                   r'frame rate: 29.97.*')
                debug('Bug in VideoReDo')
                x = rezre.search(output.lower())
                if x:
                    vInfo['vFps'] = '29.97'
    else:
        vInfo['vFps'] = ''
        vInfo['Supported'] = False
        debug('failed at vFps')

    durre = re.compile(r'.*Duration: ([0-9]+):([0-9]+):([0-9]+)\.([0-9]+),')
    d = durre.search(output)

    if d:
        vInfo['millisecs'] = (
            (int(d.group(1)) * 3600 + int(d.group(2)) * 60 + int(d.group(3))) *
            1000 + int(d.group(4)) * (10**(3 - len(d.group(4)))))
    else:
        vInfo['millisecs'] = 0

    # get bitrate of source for tivo compatibility test.
    rezre = re.compile(r'.*bitrate: (.+) (?:kb/s).*')
    x = rezre.search(output)
    if x:
        vInfo['kbps'] = x.group(1)
    else:
        # Fallback method of getting video bitrate
        # Sample line:  Stream #0.0[0x1e0]: Video: mpeg2video, yuv420p,
        #               720x480 [PAR 32:27 DAR 16:9], 9800 kb/s, 59.94 tb(r)
        rezre = re.compile(r'.*Stream #0\.0\[.*\]: Video: mpeg2video, ' +
                           r'\S+, \S+ \[.*\], (\d+) (?:kb/s).*')
        x = rezre.search(output)
        if x:
            vInfo['kbps'] = x.group(1)
        else:
            vInfo['kbps'] = None
            debug('failed at kbps')

    # get par.
    rezre = re.compile(r'.*Video: .+PAR ([0-9]+):([0-9]+) DAR [0-9:]+.*')
    x = rezre.search(output)
    if x and x.group(1) != "0" and x.group(2) != "0":
        vInfo['par1'] = x.group(1) + ':' + x.group(2)
        vInfo['par2'] = float(x.group(1)) / float(x.group(2))
    else:
        vInfo['par1'], vInfo['par2'] = None, None

    # get dar.
    rezre = re.compile(r'.*Video: .+DAR ([0-9]+):([0-9]+).*')
    x = rezre.search(output)
    if x and x.group(1) != "0" and x.group(2) != "0":
        vInfo['dar1'] = x.group(1) + ':' + x.group(2)
    else:
        vInfo['dar1'] = None

    # get Audio Stream mapping.
    rezre = re.compile(r'([0-9]+[.:]+[0-9]+)(.*): Audio:(.*)')
    x = rezre.search(output)
    amap = []
    if x:
        for x in rezre.finditer(output):
            amap.append((x.group(1), x.group(2) + x.group(3)))
    else:
        amap.append(('', ''))
        debug('failed at mapAudio')
    vInfo['mapAudio'] = amap

    vInfo['par'] = None

    # get Metadata dump (newer ffmpeg).
    lines = output.split('\n')
    rawmeta = {}
    flag = False

    for line in lines:
        if line.startswith('  Metadata:'):
            flag = True
        else:
            if flag:
                if line.startswith('  Duration:'):
                    flag = False
                else:
                    try:
                        key, value = [x.strip() for x in line.split(':', 1)]
                        try:
                            value = value.decode('utf-8')
                        except:
                            if sys.platform == 'darwin':
                                value = value.decode('macroman')
                            else:
                                value = value.decode('cp1252')
                        rawmeta[key] = [value]
                    except:
                        pass

    vInfo['rawmeta'] = rawmeta

    data = metadata.from_text(inFile)
    for key in data:
        if key.startswith('Override_'):
            vInfo['Supported'] = True
            if key.startswith('Override_mapAudio'):
                audiomap = dict(vInfo['mapAudio'])
                newmap = shlex.split(data[key])
                audiomap.update(zip(newmap[::2], newmap[1::2]))
                vInfo['mapAudio'] = sorted(audiomap.items(),
                                           key=lambda (k, v): (k, v))
            elif key.startswith('Override_millisecs'):
                vInfo[key.replace('Override_', '')] = int(data[key])
            else:
                vInfo[key.replace('Override_', '')] = data[key]

    if cache:
        info_cache[inFile] = (mtime, vInfo)
    debug("; ".join(["%s=%s" % (k, v) for k, v in vInfo.items()]))
    return vInfo
Пример #7
0
    def __init__(self, opts, name, root, vidlist, harvesters):
        self.name = name
        self.title = name
        self.opts = opts.copy()
        self.count = 0
        self.root = root

        self.videoDir = VideoDir(self.opts, "", "", root, name)

        shareopts = {"": self.opts}
        sharedirs = {"": self.videoDir}

        tree = os.walk(root)

        for path, dirs, files in tree:
            rpath = path[len(root):]
            if rpath.startswith(os.path.sep): rpath = rpath[1:]

            if rpath not in sharedirs: continue
            vdir = sharedirs[rpath]
            lopts = shareopts[rpath]
            Config.addLocalOpts(lopts, root, rpath)
            vdir.setOpts(lopts)

            if self.isDvdDir(path):
                p, deftitle = os.path.split(path)
                meta, titles = self.loadDvdMeta(path, lopts, "default",
                                                deftitle, False)
                fid = fileId(os.path.join(path, "default.txt"))
                for (title, fn, tn) in titles:
                    if fid != None:
                        vf = vidlist.findVideo((fid, tn))
                    else:
                        vf = None

                    if vf == None:
                        vf = VideoFile(lopts, path, fn, (fid, tn))
                        vidlist.addVideo(vf)

                        meta, t = self.loadDvdMeta(path, lopts, fn, title,
                                                   True)
                        meta['title'] = title
                        meta['titleNumber'] = tn
                        vf.setMeta(meta)

                        vdir.addVideo(vf)
                        self.count += 1

                        for h in harvesters:
                            h.harvest(vf)

                    else:
                        vdir.addVideo(vf, path=path, fn=fn)
                        self.count += 1
            else:
                for dn in dirs:
                    if dn.startswith("."): continue

                    cdir = os.path.join(path, dn)
                    if self.isDvdDir(cdir):
                        meta, tnames = self.loadDvdMeta(
                            cdir, lopts, "default", dn, False)

                        d = DVDDir(lopts, dn, rpath, path, self.name)
                    else:
                        meta = metadata.from_text(
                            os.path.join(path, dn, "folder"),
                            lopts['metamergefiles'], lopts['metamergelines'])

                        d = VideoDir(lopts, dn, rpath, path, self.name)

                    d.setMeta(meta)
                    vdir.addDir(d)
                    sharedirs[os.path.join(rpath, dn)] = d
                    shareopts[os.path.join(rpath, dn)] = lopts.copy()
            vdir.sort()
Пример #8
0
    def __init__(self, opts, name, root, vidlist, harvesters):
        self.name = name
        self.title = name
        self.opts = opts.copy()
        self.count = 0
        self.root = root
        self.videoDir = VideoDir(opts, "", "", root, name)

        tree = myWalk(root)

        sharedirs = {"": self.videoDir}
        shareopts = {"": self.opts}

        for path, dirs, files in tree:
            rpath = path[len(root):]
            if rpath.startswith(os.path.sep): rpath = rpath[1:]
            if rpath not in sharedirs: continue
            vl = sharedirs[rpath]
            lopts = shareopts[rpath]
            Config.addLocalOpts(lopts, root, rpath)
            vl.setOpts(lopts)

            for name in dirs:
                if name.startswith("."): continue
                meta = metadata.from_text(os.path.join(path, name, "folder"),
                                          lopts['metamergefiles'],
                                          lopts['metamergelines'])
                d = VideoDir(lopts, name, rpath, path, self.name)
                d.setMeta(meta)
                vl.addDir(d)
                sharedirs[os.path.join(rpath, name)] = d
                shareopts[os.path.join(rpath, name)] = lopts.copy()

            for name in files:
                if name.startswith("."): continue
                if os.path.splitext(name)[1].lower() in lopts['goodexts']:
                    fid = fileId(os.path.join(path, name))
                    if fid != None:
                        vf = vidlist.findVideo(fid)
                    else:
                        vf = None

                    if vf == None:
                        vf = VideoFile(lopts, path, name, fid)
                        vidlist.addVideo(vf)

                        meta = metadata.from_text(os.path.join(path, name),
                                                  lopts['metamergefiles'],
                                                  lopts['metamergelines'])
                        if not 'title' in meta:
                            meta = metadata.basic(os.path.join(path, name))
                        vf.setMeta(meta)

                        vl.addVideo(vf)
                        self.count += 1

                        for h in harvesters:
                            h.harvest(vf)

                    else:
                        vl.addVideo(vf, path=path, fn=name)
                        self.count += 1

            vl.sort()
Пример #9
0
	def __init__(self, opts, name, root, vidlist, harvesters):
		self.name = name
		self.title = name
		self.opts = opts.copy()
		self.count = 0
		self.root = root

		self.videoDir = VideoDir(self.opts, "", "", root, name)
		
		shareopts = {"": self.opts}
		sharedirs = {"": self.videoDir}

		tree = os.walk(root)

		for path, dirs, files in tree:
			rpath = path[len(root):]
			if rpath.startswith(os.path.sep): rpath = rpath[1:]

			if rpath not in sharedirs: continue
			vdir = sharedirs[rpath]
			lopts = shareopts[rpath]
			Config.addLocalOpts(lopts, root, rpath)
			vdir.setOpts(lopts)

			if self.isDvdDir(path):
				p, deftitle = os.path.split(path)
				meta, titles = self.loadDvdMeta(path, lopts, "default", deftitle, False)
				fid = fileId(os.path.join(path, "default.txt"))
				for (title, fn, tn) in titles:
					if fid != None:		
						vf = vidlist.findVideo((fid, tn))
					else:
						vf = None
						
					if vf == None:
						vf = VideoFile(lopts, path, fn, (fid, tn))
						vidlist.addVideo(vf)

						meta, t = self.loadDvdMeta(path, lopts, fn, title, True)
						meta['title'] = title
						meta['titleNumber'] = tn
						vf.setMeta(meta)
						
						vdir.addVideo(vf)
						self.count += 1

						for h in harvesters:
							h.harvest(vf)

					else:
						vdir.addVideo(vf, path=path, fn=fn)
						self.count += 1
			else:
				for dn in dirs:
					if dn.startswith("."): continue

					cdir = os.path.join(path, dn)
					if self.isDvdDir(cdir):
						meta, tnames = self.loadDvdMeta(cdir,
							lopts,
							"default",
							dn,
							False)
					
						d = DVDDir(lopts, dn, rpath, path, self.name)
					else:
						meta = metadata.from_text(
							os.path.join(path, dn, "folder"),
							lopts['metamergefiles'],
							lopts['metamergelines'])

						d = VideoDir(lopts, dn, rpath, path, self.name)
						
					d.setMeta(meta)
					vdir.addDir(d)
					sharedirs[os.path.join(rpath, dn)] = d
					shareopts[os.path.join(rpath, dn)] = lopts.copy()
			vdir.sort()