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)
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)
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()
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
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
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
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()
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()
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()