def _AnalyzeSource(self): """Find out some basic information about the source ATM we will blindly assume it's a dvdrom device or a disk dvd image, if a title (chapter) number is given. """ _debug_('_AnalyzeSource(self)', 2) if self.chapter: self.sourcetype = "dvd" #check some things, like length _debug_('source=\"%s\" chapter=%s' % (self.source, self.chapter)) dvddata = mmpython.parse(self.source) dvdtitle = dvddata.tracks[self.chapter - 1] self.length = dvdtitle['length'] _debug_("Video length: %s" % self.length) #NI : maybe implement procedure to get resolution, handy for scaling/manual cropping self._CropDetect() else: data = mmpython.parse(self.source) _debug_('source=\"%s\"' % (self.source)) self.sourcetype = data['type'].encode('latin1') if config.DEBUG >= 2: for f in dir(data): _debug_('%s: %s' % (f, eval('data["%s"]' % f)), 2) try: self.length = data.get_length() except: self.length = 600 _debug_("Video length: %s" % self.length) self._CropDetect()
def parse(filepath): """ Parse video at filepath :param filepath: path of video to parse as string :return: Metadata Instance of the video """ metadata = Metadata() metadata.parse(filepath) return metadata
def disc_info(media, force=False): """ return kaa metadata disc information for the media """ discinfo = mmpython.parse(media.devicename) if not discinfo or not discinfo.id: # bad disc, e.g. blank disc return {} cachedir = os.path.join(config.OVERLAY_DIR, 'disc/metadata') cachefile = os.path.join(cachedir, discinfo.id + '.freevo') if os.path.isfile(cachefile): metainfo = util.read_pickle(cachefile) else: metainfo = {} if force or discinfo.mime == 'unknown/unknown' and not metainfo.has_key('disc_num_video'): media.mount() for type in ('video', 'audio', 'image'): items = getattr(config, '%s_SUFFIX' % type.upper()) files = util.match_files_recursively(media.mountdir, items) metainfo['disc_num_%s' % type] = len(files) media.umount() util.save_pickle(metainfo, cachefile) info = Info(cachefile, discinfo, metainfo) info.disc = True return info
def videoInfo(self): """Videolar için ayrıntıların ayarlanması""" info = {"title":"","length":0,"width":0,"height":0} if self.address: realinfo = Meta.parse(self.address) elif self.realinfo: realinfo = self.realinfo for i in info.keys(): if realinfo.has_key(i) and realinfo[i] != None: info[i] = realinfo[i] return info
def imageInfo(self): """Resimler için ayrıntıların ayarlanması""" info = {"width":0,"height":0} if self.address: realinfo = Meta.parse(self.address) elif self.realinfo: realinfo = self.realinfo for i in info.keys(): if realinfo.has_key(i) and realinfo[i] != None: info[i] = realinfo[i] return info
def getNewName(file): ext = file.split(".")[-1].lower() info = Meta.parse(file) if info and info.timestamp: createDate = datetime.datetime.fromtimestamp(info.timestamp) else: stat = os.stat(file) createDate = datetime.datetime.fromtimestamp(stat.st_mtime) newName = createDate.strftime("%Y-%m-%d %H.%M.%S") newName = newName + "." + ext return newName
def resume(self, arg=None, menuw=None): """ resume playback """ t = max(0, self.item['autobookmark_resume'] - 10) info = mmpython.parse(self.item.filename) if hasattr(info, 'seek') and t: arg = '-sb %s' % info.seek(t) else: arg = '-ss %s' % t if menuw: menuw.back_one_menu() self.item.play(menuw=menuw, arg=arg)
def get_formatted_cd_info(self, device): cd_info = mmpython.parse(device) if cd_info is None: logger.error(_('No CD medadata available')) popup_string = _('CD info not found!') AlertBox(text=popup_string).show() return [ 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown' ] current_time = time.strftime('%d-%b-%y-%I:%M%P') artist = _('Unknown Artist') + ' ' + current_time + ' - ' + _('RENAME') album = _('Unknown CD Album') + ' ' + current_time + ' - ' + _( 'RENAME') genre = _('Other') year = time.strftime('%Y') # Check if getting CDDB data failed -is there a better way to do this? # Give some defaults with a timestamp to uniqueify artist and album names. # So that subsequent CDs with no CDDB data found don't overwrite each other. if cd_info.title is None and cd_info.artist is None: logger.warning(_('No CDDB data available to mmpython')) popup_string = _( 'CD info not found!\nMust manually rename files\nwhen finished ripping' ) AlertBox(text=popup_string).show() else: # If valid data was returned from mmpython/CDDB album = self.fix_case(self.replace_special_char( cd_info.title, '-')) artist = self.fix_case( self.replace_special_char(cd_info.artist, '-')) genre = self.replace_special_char(cd_info.tracks[0].genre, '-') year = cd_info.year song_names = [] for track in cd_info.tracks: song_names.append( self.fix_case(self.replace_special_char(track.title, '-'))) if hasattr(cd_info, 'mixed') and cd_info.mixed: # remove last tracks if it's a mixed cd song_names = song_names[:-1] return [cd_info.id, artist, album, genre, year, song_names]
def disc_info(media, force=False): """ return kaa metadata disc information for the media """ type, id = mmpython.cdrom.status(media.devicename) if not id: # bad disc, e.g. blank disc return {} cachedir = os.path.join(config.OVERLAY_DIR, 'disc/metadata') cachefile = os.path.join(cachedir, id + '.mmpython') if os.path.isfile(cachefile) and not force: mmdata = util.read_pickle(cachefile) else: mmdata = mmpython.parse(media.devicename) if not mmdata: print '*****************************************' print 'Error detecting the disc in %r' % (media.devicename) print 'Please contact the developers' print '*****************************************' return {} else: util.save_pickle(mmdata, cachefile) cachefile = os.path.join(cachedir, id + '.freevo') if os.path.isfile(cachefile): metainfo = util.read_pickle(cachefile) else: metainfo = {} if mmdata.mime == 'unknown/unknown' and not metainfo.has_key( 'disc_num_video'): media.mount() for type in ('video', 'audio', 'image'): items = getattr(config, '%s_SUFFIX' % type.upper()) files = util.match_files_recursively(media.mountdir, items) metainfo['disc_num_%s' % type] = len(files) media.umount() util.save_pickle(metainfo, cachefile) info = Info(cachefile, mmdata, metainfo) info.disc = True return info
def get_formatted_cd_info(self, device): cd_info = mmpython.parse(device) # Check if getting CDDB data failed -is there a better way to do this? # Give some defaults with a timestamp to uniqueify artist and album names. # So that subsequent CDs with no CDDB data found don't overwrite each other. if ((cd_info.title == None) and (cd_info.artist == None)): _debug_( _('WARNING') + ': ' + _('No CDDB data available to mmpython'), 2) current_time = time.strftime('%d-%b-%y-%I:%M%P') artist = _('Unknown Artist') + ' ' + current_time + ' - ' + _( 'RENAME') album = _('Unknown CD Album') + ' ' + current_time + ' - ' + _( 'RENAME') genre = _('Other') # Flash a popup window indicating copying is done popup_string = _( "CD info not found!\nMust manually rename files\nwhen finished ripping" ) pop = AlertBox(text=popup_string) time.sleep(7) # If valid data was returned from mmpython/CDDB else: album = self.fix_case(self.replace_special_char( cd_info.title, '-')) artist = self.fix_case( self.replace_special_char(cd_info.artist, '-')) genre = self.replace_special_char(cd_info.tracks[0].genre, '-') song_names = [] for track in cd_info.tracks: song_names.append( self.fix_case(self.replace_special_char(track.title, '-'))) if hasattr(cd_info, 'mixed') and cd_info.mixed: # remove last tracks if it's a mixed cd song_names = song_names[:-1] return [cd_info.id, artist, album, genre, song_names]
def resume(self, arg=None, menuw=None): """ resume playback """ t = max(0, self.item['autobookmark_resume'] - 10) info = mmpython.parse(self.item.filename) if (self.item.player.name == 'xine'): self.write_playlist(t) arg = ("--playlist %s/playlist_xine_%s.tox" % (config.FREEVO_CACHEDIR, t)) else: if hasattr(info, 'seek') and t: arg = '-sb %s' % info.seek(t) else: arg = '-ss %s' % t if menuw: menuw.back_one_menu() self.item.play(menuw=menuw, arg=arg)
def create(self, filename): """ create mmpython information about the given file """ data = os.path.split(filename) if len(data) == 2: if data[1] == '.directory': filename = data[0] info = mmpython.parse(filename) if info: thumbnail = None if info.has_key('thumbnail'): thumbnail = info.thumbnail info = self.simplify(info) name = util.getname(filename) if name == name.upper() and info.has_key('type') and \ info['type'] in ('DVD', 'VCD'): name = util.getname(filename.lower()) info['title:filename'] = name if info.has_key('video'): for video in info['video']: for variable in ('width', 'height', 'length', 'aspect', 'fps'): if video.has_key(variable) and not \ (info.has_key(variable) and info[variable]): info[variable] = video[variable] if thumbnail and config.IMAGE_USE_EXIF_THUMBNAIL and config.CACHE_IMAGES: util.cache_image(filename, thumbnail) elif config.CACHE_IMAGES and info.has_key('mime') and info['mime'] and \ info['mime'].startswith('image'): util.cache_image(filename) if info.has_key('media') and info['media'] == 'MEDIA_DIRECTORY': pass info = self.normalize(info) return info return {}
def extract_name(filename): """Getting and returning anime name""" # Remove path from filename meta = metadata.parse(filename) #TODO: full usage of metadata. if meta.title: name = meta.title else: name = os.path.basename(filename) # Remove excess info name = clean_name(name) # Remove episode number name = re.sub("(ep\.?)?\s?\d+", "", name, re.I) # Remove all digits name = re.sub("[\d\._]{1,}", "", name) # Get rid of scores name = name.replace("-", "") return name.strip()
def extract_name(filename): """Getting and returning anime name""" # Remove path from filename meta = metadata.parse(filename) #TODO: full usage of metadata. if meta.title: name = meta.title else: name = os.path.basename(filename) # Remove excess info name = clean_name(name) # Remove episode number name = re.sub("(ep\.?)?\s?\d+", "", name, re.I) # Remove all digits name = re.sub("[\d\._]{1,}", "", name) # Get rid of scores name = name.replace("-","") return name.strip()
def get_video_info(root, file, label, device, path): """Obtener información del archivo de vídeo. """ orig_level = logging.getLogger().level # Recuperar el level original # Se sobrescribe el level para que no aparezca basura de ffmpeg logging.getLogger().level = logging.CRITICAL path_file = os.path.join(root, file) try: info = metadata.parse(path_file) except: info = {} project_dir = root.replace(os.path.join(device, path), '', 1) project_dir = os.path.join('html', 'devices', parse.quote_plus(os.path.join(label, path)), project_dir) if not os.path.exists(project_dir): os.makedirs(project_dir) project_file = os.path.join(project_dir, file) system_file = os.path.join(root, file) if info and not os.path.exists(project_file + '.jpg') and info['video']: orig_width = info['video'][0]['width'] orig_height = info['video'][0]['height'] if orig_height and orig_width: escale = orig_width / THUMB_WIDTH size = (THUMB_WIDTH, orig_height / escale) while len(threading.enumerate()) > 8: time.sleep(0.001) l = threading.Thread(target=GetThumb, args=(system_file, project_file + '.jpg', size)) l.start() info['thumb'] = project_file + '.jpg' if not info: info = {'type': 'file'} info['size'] = os.path.getsize(path_file) info['str_size'] = str_size(info['size']) # Se devuelve al level original. logging.getLogger().level = orig_level return info
def musicInfo(self): """Müzikler için ayrıntıların ayarlanması""" turnKeys = {"date":"userdate","tracknumber":"trackno"} info = {"title":"","artist":"","album":"","date":0,"tracknumber":0, "genre":"","bitrate":0,"samplerate":0,"length":0} if self.address: realinfo = Meta.parse(self.address) for i in info.keys(): if i in turnKeys.keys() and realinfo[turnKeys[i]] != None: info[i] = int(realinfo[turnKeys[i]]) elif realinfo[i] != None: if i == "bitrate": info[i] = realinfo[i]*1000 elif i == "length": info[i] = int(realinfo[i]) else: info[i] = realinfo[i] elif self.realinfo: realinfo = self.realinfo for i in info.keys(): if realinfo.has_key(i): info[i] = realinfo[i] return info
def get_formatted_cd_info(self, device): cd_info = mmpython.parse(device) if cd_info is None: logger.error(_('No CD medadata available')) popup_string=_('CD info not found!') AlertBox(text=popup_string).show() return [ 'unknown', 'unknown', 'unknown', 'unknown', 'unknown', 'unknown' ] current_time = time.strftime('%d-%b-%y-%I:%M%P') artist = _('Unknown Artist') + ' ' + current_time + ' - ' + _('RENAME') album = _('Unknown CD Album') + ' ' + current_time + ' - ' + _('RENAME') genre = _('Other') year = time.strftime('%Y') # Check if getting CDDB data failed -is there a better way to do this? # Give some defaults with a timestamp to uniqueify artist and album names. # So that subsequent CDs with no CDDB data found don't overwrite each other. if cd_info.title is None and cd_info.artist is None: logger.warning(_('No CDDB data available to mmpython')) popup_string=_('CD info not found!\nMust manually rename files\nwhen finished ripping') AlertBox(text=popup_string).show() else: # If valid data was returned from mmpython/CDDB album = self.fix_case(self.replace_special_char(cd_info.title, '-')) artist = self.fix_case(self.replace_special_char(cd_info.artist, '-')) genre = self.replace_special_char(cd_info.tracks[0].genre, '-') year = cd_info.year song_names = [] for track in cd_info.tracks: song_names.append(self.fix_case(self.replace_special_char(track.title, '-'))) if hasattr(cd_info, 'mixed') and cd_info.mixed: # remove last tracks if it's a mixed cd song_names = song_names[:-1] return [cd_info.id, artist, album, genre, year, song_names]
def checkForUpdates(): try: file = open(config.RSS_FEEDS, 'r') except IOError: _debug_('Could not open configuration file %s' % (config.RSS_FEEDS), DERROR) return for line in file: if line == '\n': continue if re.search('^#', line): continue try: (url, numberOfDays) = re.split(';', line) except ValueError: continue _debug_('Check %s for updates' % url) try: sock = urllib.urlopen(url) feedSource = sock.read() sock.close() for item in rssfeed.Feed(feedSource).items: diff = datetime.date.today() - convertDate(item.date) goodUntil = datetime.date.today() + datetime.timedelta( days=int(numberOfDays)) if int(diff.days) <= int(numberOfDays) and not re.search( 'None', item.url): os.chdir(config.RSS_DOWNLOAD) filename = os.path.basename(item.url) _debug_('%r -> %s' % (item.title, filename), 2) if len(glob.glob(filename)) == 0 and not checkForDup( item.url): if re.search('torrent', item.url): _debug_('Running bittorrent download from %s' % item.url) cmdlog = open( os.path.join(config.FREEVO_LOGDIR, 'rss-bittorrent.out'), 'a') p = Popen('bittorrent-console %s' % (item.url), shell=True, stderr=cmdlog, stdout=cmdlog) exitStatus = p.wait() filename = re.sub('\.torrent', '', filename) else: _debug_('Running wget download from %s' % (item.url)) cmdlog = open( os.path.join(config.FREEVO_LOGDIR, 'rss-wget.out'), 'a') p = Popen('wget -O %s %s' % (filename, item.url), shell=True, stderr=cmdlog, stdout=cmdlog) exitStatus = p.wait() if exitStatus: _debug_('Download failed - exit status %s.' % exitStatus) os.remove(filename) else: _debug_('Download completed (%s bytes)' % os.path.getsize(filename)) meta = metadata.parse(filename) if meta and meta.has_key('media'): if meta.media == 'MEDIA_AUDIO' or isAudioItem( filename): try: fxdpath = createFxd(item, filename) shutil.move(filename, config.RSS_AUDIO) shutil.move(fxdpath, config.RSS_AUDIO) except: _debug_('failed to move %s to %s' % (filename, newpath)) elif meta.media == 'MEDIA_VIDEO' or isVideoItem( filename): try: fxdpath = createFxd(item, filename) shutil.move(filename, config.RSS_VIDEO) shutil.move(fxdpath, config.RSS_VIDEO) except: _debug_('failed to move %s to %s' % (filename, newpath)) else: _debug_( 'Cannot move %s as it media type is %s', (filename, meta.media)) fxdpath = createFxd(item, filename) else: _debug_( 'Cannot move %s as cannot determine its media type', (filename)) addFileToCache(item.url) addFileToExpiration(filename, goodUntil) except IOError: _debug_('Unable to download %s. Connection may be down.' % (url), DERROR)
def __init__(self, path): self.info = {} try: info = metadata.parse(os.path.normpath(path)) except: sys.stderr.write("METADATA, problem with %s" % path) return if not info: self.info = {} return if not hasattr(info, 'mime'): self.info = {} return if not info.mime: self.info = {} return self.mime = info.mime if info.mime not in mimes: mimes.append(info.mime) if info.mime == 'audio/wav': self.info = {'samplerate': info.samplerate} self.icon = 'icon-snd' elif info.mime.startswith('audio') or info.mime.endswith('ogg'): self.icon = 'icon-snd' try: pattern="" if info.has_key('title'): if info.title: title = info.title.encode("latin_1") pattern+=title if info.has_key('artist'): if info.artist: artist = info.artist.encode("latin_1") pattern+=" "+artist if info.has_key('album'): if info.album: album = info.album.encode("latin_1") pattern+=" "+album if info.has_key('comment'): if len(info.comment) > 0: comment = info.comment.encode("latin_1") pattern+=" "+comment if pattern: enc = chardet.detect(pattern)['encoding'] if enc == 'EUC-TW' or enc == 'windows-1255' or enc == 'MacCyrillic' or enc == 'TIS-620' or enc == 'KOI8-R' or enc == 'IBM866': enc = 'CP1251' elif not enc or enc.startswith('ISO-8859'): enc = "latin1" else: enc = None except: if info.has_key('title'): if info.title: title = slughifi(info.title) if info.has_key('artist'): if len(info.artist) > 0: artist = slughifi(info.artist) if info.has_key('album'): if info.album: album = slughifi(info.album) if info.has_key('comment'): if info.comment: comment = slughifi(info.comment) enc = None for key in ['samplerate', 'date', 'bitrate', 'trackno']: if hasattr(info, i): self.info[key] = getattr(info, key) if hasattr(info, 'length'): self.info['length'] = info.length # getPlayTimeString(value) if hasattr(info, 'comment'): try: tmp=value.encode("latin_1") try: tmp = unicode(tmp, chardet.detect(tmp)['encoding']) except: tmp=re.sub('[^a-zA-Z0-9\\s\\-]{1}', replace_char, value).lower() except: tmp=re.sub('[^a-zA-Z0-9\\s\\-]{1}', replace_char, value).lower() if re.sub('\s+','',tmp): self.info['comment'] = tmp if hasattr(info, 'album') and enc: try: self.info['album'] = unicode(album, enc) except UnicodeEncodeError: self.info['album'] = slughifi(album) if hasattr(info, 'artist') and enc: try: self.info['artist'] = unicode(artist, enc) except UnicodeEncodeError: self.info['artist'] = slughifi(artist) if hasattr(info, 'title') and enc: try: self.info['title'] = unicode(title, enc) except UnicodeEncodeError: self.info['title'] = slughifi(title) elif info.mime.startswith('video') or \ info.mime == 'application/ogm' or \ info.mime == 'application/mkv': if info.mime.endswith('x-msvideo'): self.icon = 'icon-avi' else: self.icon = 'icon-vid' for key in ['comment', 'producer', 'genre', 'country']: if hasattr(info, key): self.info[key] = getattr(info, key) if hasattr(info, 'length'): self.info['length'] = info.length #getPlayTimeString(value) if hasattr(info, 'all_header'): if len(info.all_header) > 0: for k in info.all_header[0]: self.info[k] = info.all_header[0][k] try: if info.video[0].codec: self.info['codec'] = info.video[0].codec if info.video[0].fps: self.info['fps'] = "%.0d" % info.video[0].fps if info.video[0].width: self.info['width'] = info.video[0].width if info.video[0].height: self.info['height'] = info.video[0].height if info.header['INFO']['ISRC']: self.info['source'] = info.header['INFO']['ISRC'] except: pass
def parse(filepath): return metadata.parse(filepath)
logger.debug('Running bittorrent download from %s', item.url) cmdlog = open(os.path.join(config.FREEVO_LOGDIR, 'rss-bittorrent.out'), 'a') p = Popen('bittorrent-console %s' % (item.url), shell=True, stderr=cmdlog, stdout=cmdlog) exitStatus = p.wait() filename = re.sub('\.torrent', '', filename) else: logger.debug('Running wget download from %s', item.url) cmdlog = open(os.path.join(config.FREEVO_LOGDIR, 'rss-wget.out'), 'a') p = Popen('wget -O %s %s' % (filename, item.url), shell=True, stderr=cmdlog, stdout=cmdlog) exitStatus = p.wait() if exitStatus: logger.debug('Download failed - exit status %s.', exitStatus) os.remove(filename) else: logger.debug('Download completed (%s bytes)', os.path.getsize(filename)) meta = metadata.parse(filename) if meta and meta.has_key('media'): if meta.media == 'MEDIA_AUDIO' or isAudioItem(filename): try: fxdpath = createFxd(item, filename) shutil.move(filename, config.RSS_AUDIO) shutil.move(fxdpath, config.RSS_AUDIO) except: logger.debug('failed to move %s to %s', filename, newpath) elif meta.media == 'MEDIA_VIDEO' or isVideoItem(filename): try: fxdpath = createFxd(item, filename) shutil.move(filename, config.RSS_VIDEO) shutil.move(fxdpath, config.RSS_VIDEO) except: logger.debug('failed to move %s to %s', filename, newpath)
def play(self, options, item): """ play a videoitem with mplayer """ self.options = options self.item = item mode = item.mode url = item.url self.item_info = None self.item_length = -1 self.item.elapsed = 0 VODEV = config.MPLAYER_VO_DEV VODEVOPTS = config.MPLAYER_VO_DEV_OPTS if mode == 'file': url = item.url[6:] self.item_info = mmpython.parse(url) if hasattr(self.item_info, 'get_length'): self.item_length = self.item_info.get_endpos() self.dynamic_seek_control = True if url.startswith('dvd://') and url[-1] == '/': url += '1' if url == 'vcd://': c_len = 0 for i in range(len(item.info.tracks)): if item.info.tracks[i].length > c_len: c_len = item.info.tracks[i].length url = item.url + str(i + 1) try: _debug_('MPlayer.play(): mode=%s, url=%s' % (mode, url)) except UnicodeError: _debug_('MPlayer.play(): [non-ASCII data]') if mode == 'file' and not os.path.isfile(url): # This event allows the videoitem which contains subitems to # try to play the next subitem return '%s\nnot found' % os.path.basename(url) # Build the MPlayer command command = [ '--prio=%s' % config.MPLAYER_NICE, config.MPLAYER_CMD ] + \ config.MPLAYER_ARGS_DEF.split(' ') + \ [ '-slave', '-ao'] + config.MPLAYER_AO_DEV.split(' ') additional_args = [] if mode == 'dvd': if config.DVD_LANG_PREF: # There are some bad mastered DVDs out there. E.g. the specials on # the German Babylon 5 Season 2 disc claim they have more than one # audio track, even more then on en. But only the second en works, # mplayer needs to be started without -alang to find the track if hasattr( item, 'mplayer_audio_broken') and item.mplayer_audio_broken: print '*** dvd audio broken, try without alang ***' else: additional_args += ['-alang', config.DVD_LANG_PREF] if config.DVD_SUBTITLE_PREF: # Only use if defined since it will always turn on subtitles # if defined additional_args += ['-slang', config.DVD_SUBTITLE_PREF] if hasattr(item.media, 'devicename') and mode != 'file': additional_args += ['-dvd-device', item.media.devicename] elif mode == 'dvd': # dvd on harddisc additional_args += ['-dvd-device', item.filename] url = url[:6] + url[url.rfind('/') + 1:] if item.media and hasattr(item.media, 'devicename'): additional_args += ['-cdrom-device', item.media.devicename] if item.selected_subtitle == -1: additional_args += ['-noautosub'] elif item.selected_subtitle and mode == 'file': if os.path.isfile(os.path.splitext(item.filename)[0] + '.idx'): additional_args += ['-vobsubid', str(item.selected_subtitle)] else: additional_args += ['-sid', str(item.selected_subtitle)] elif item.selected_subtitle: additional_args += ['-sid', str(item.selected_subtitle)] if item.selected_audio: if item.mimetype == 'mkv': additional_args += ['-aid', str(item.selected_audio - 1)] else: additional_args += ['-aid', str(item.selected_audio)] # This comes from the bilingual language selection menu if hasattr(item, 'selected_language') and item.selected_language: if item.selected_language == 'left': additional_args += ['-af', 'pan=2:1:1:0:0'] elif item.selected_language == 'right': additional_args += ['-af', 'pan=2:0:0:1:1'] if item['deinterlace'] and config.MPLAYER_VF_INTERLACED: additional_args += ['-vf', config.MPLAYER_VF_INTERLACED] elif config.MPLAYER_VF_PROGRESSIVE: additional_args += ['-vf', config.MPLAYER_VF_PROGRESSIVE] if os.path.isfile(os.path.splitext(item.filename)[0] + '.edl'): additional_args += [ '-edl', str(os.path.splitext(item.filename)[0] + '.edl') ] mode = item.mimetype if not config.MPLAYER_ARGS.has_key(mode): mode = 'default' # Mplayer command and standard arguments command += ['-v', '-vo', VODEV] command += VODEVOPTS.split(' ') # mode specific args command += config.MPLAYER_ARGS[mode].split(' ') # make the options a list command += additional_args if hasattr(item, 'is_playlist') and item.is_playlist: command.append('-playlist') # add the file to play command.append(url) if options: command += options # use software scaler? if '-nosws' in command: command.remove('-nosws') elif not '-framedrop' in command: command += config.MPLAYER_SOFTWARE_SCALER.split(' ') # correct avi delay based on kaa.metadata settings if config.MPLAYER_SET_AUDIO_DELAY and item.info.has_key('delay') and \ item.info['delay'] > 0: command += [ '-mc', str(int(item.info['delay']) + 1), '-delay', '-' + str(item.info['delay']) ] while '' in command: command.remove('') # autocrop if config.MPLAYER_AUTOCROP and not item.network_play and str(' ').join( command).find('crop=') == -1: _debug_('starting autocrop') (x1, y1, x2, y2) = (1000, 1000, 0, 0) crop_cmd = [ config.MPLAYER_CMD, '-ao', 'null', '-vo', 'null', '-slave', '-nolirc', '-ss', '%s' % config.MPLAYER_AUTOCROP_START, '-frames', '20', '-vf', 'cropdetect' ] crop_cmd.append(url) child = popen2.Popen3(self.sort_filter(crop_cmd), 1, 100) exp = re.compile( '^.*-vf crop=([0-9]*):([0-9]*):([0-9]*):([0-9]*).*') while (1): data = child.fromchild.readline() if not data: break m = exp.match(data) if m: x1 = min(x1, int(m.group(3))) y1 = min(y1, int(m.group(4))) x2 = max(x2, int(m.group(1)) + int(m.group(3))) y2 = max(y2, int(m.group(2)) + int(m.group(4))) _debug_('x1=%s x2=%s y1=%s y2=%s' % (x1, x2, y1, y2)) if x1 < 1000 and x2 < 1000: command = command + [ '-vf', 'crop=%s:%s:%s:%s' % (x2 - x1, y2 - y1, x1, y1) ] _debug_('crop=%s:%s:%s:%s' % (x2 - x1, y2 - y1, x1, y1)) child.wait() if item.subtitle_file: d, f = util.resolve_media_mountdir(item.subtitle_file) util.mount(d) command += ['-sub', f] if item.audio_file: d, f = util.resolve_media_mountdir(item.audio_file) util.mount(d) command += ['-audiofile', f] self.plugins = plugin.get('mplayer_video') for p in self.plugins: command = p.play(command, self) command = self.sort_filter(command) if plugin.getbyname('MIXER'): plugin.getbyname('MIXER').reset() rc.app(self) self.app = MPlayerApp(command, self) return None
cmdlog = open( os.path.join(config.FREEVO_LOGDIR, 'rss-wget.out'), 'a') p = Popen('wget -O %s %s' % (filename, item.url), shell=True, stderr=cmdlog, stdout=cmdlog) exitStatus = p.wait() if exitStatus: logger.debug('Download failed - exit status %s.', exitStatus) os.remove(filename) else: logger.debug('Download completed (%s bytes)', os.path.getsize(filename)) meta = metadata.parse(filename) if meta and meta.has_key('media'): if meta.media == 'MEDIA_AUDIO' or isAudioItem( filename): try: fxdpath = createFxd(item, filename) shutil.move(filename, config.RSS_AUDIO) shutil.move(fxdpath, config.RSS_AUDIO) except: logger.debug('failed to move %s to %s', filename, newpath) elif meta.media == 'MEDIA_VIDEO' or isVideoItem( filename): try: fxdpath = createFxd(item, filename) shutil.move(filename, config.RSS_VIDEO)
def construct_node(location, parent_path, node_cache, channel): """Return list of dictionaries of subdirectories and/or files in the location""" # Recursively add all subdirectories children = [] location = location if not location or location[ -1] != "/" else location[:-1] base_name = os.path.basename(location) if base_name.endswith(".json"): return None if not parent_path: base_name = channel["name"] slug = slugify(unicode(".".join(base_name.split(".")[:-1]))) if not slug or slug in node_cache["Slugs"]: slug = slugify(unicode(base_name)) # Note: It is assumed that any file with *exactly* the same file name is the same file. node_cache["Slugs"].add(slug) current_path = os.path.join(parent_path, slug) try: with open(location + ".json", "r") as f: meta_data = json.load(f) except IOError: meta_data = {} logging.warning( "No metadata for file {base_name}".format(base_name=base_name)) node = { "path": current_path, "parent_id": os.path.basename(parent_path), "ancestor_ids": filter(None, parent_path.split("/")), "slug": slug, } if os.path.isdir(location): node.update({ "kind": "Topic", "id": slug, "children": sorted([ construct_node(os.path.join(location, s), current_path, node_cache, channel) for s in os.listdir(location) ], key=lambda x: (not x.get("topic_spotlight", False) if x else True, x.get("title", "") if x else "")), }) node["children"] = [child for child in node["children"] if child] node.update(meta_data) # Finally, can add contains contains = set([]) for ch in node["children"]: contains = contains.union(ch.get("contains", set([]))) contains = contains.union(set([ch["kind"]])) node["contains"] = list(contains) else: extension = base_name.split(".")[-1] kind = file_kind_map.get(extension, None) if not kind: return None elif kind in ["Video", "Audio", "Image"]: from kaa import metadata as kaa_metadata info = kaa_metadata.parse(location) data_meta = {} for meta_key, data_fn in file_meta_data_map.items(): if data_fn(info): data_meta[meta_key] = data_fn(info) if data_meta.get("codec", None): data_meta["{kind}_codec".format( kind=kind.lower())] = data_meta["codec"] del data_meta["codec"] data_meta.update(meta_data) meta_data = data_meta id = file_md5(channel["id"], location) node.update({ "id": id, "kind": kind, "format": extension, }) node.update(meta_data) # Copy over content shutil.copy(location, os.path.join(settings.CONTENT_ROOT, id + "." + extension)) logging.debug("%s file %s to local content directory." % ("Copied", slug)) # Verify some required fields: if "title" not in node: logging.warning( "Title missing from file {base_name}, using file name instead". format(base_name=base_name)) if os.path.isdir(location): node["title"] = base_name else: node["title"] = os.path.splitext(base_name)[0] # Clean up some fields: # allow tags and keywords to be a single item as a string, convert to list for key in ["tags", "keywords"]: if isinstance(node.get(key, []), basestring): node[key] = [node[key]] if not os.path.isdir(location): nodecopy = copy.deepcopy(node) if kind == "Exercise": node_cache["Exercise"].append(nodecopy) else: node_cache["Content"].append(nodecopy) return node
def construct_node(location, parent_path, node_cache, channel): """Return list of dictionaries of subdirectories and/or files in the location""" # Recursively add all subdirectories children = [] location = location if not location or location[-1] != "/" else location[:-1] base_name = os.path.basename(location) if base_name.endswith(".json"): return None if not parent_path: base_name = channel["name"] slug = slugify(unicode(".".join(base_name.split(".")[:-1]))) if not slug or slug in node_cache["Slugs"]: slug = slugify(unicode(base_name)) # Note: It is assumed that any file with *exactly* the same file name is the same file. node_cache["Slugs"].add(slug) current_path = os.path.join(parent_path, slug) try: with open(location + ".json", "r") as f: meta_data = json.load(f) except IOError: meta_data = {} logging.warning("No metadata for file {base_name}".format(base_name=base_name)) node = { "path": current_path, "slug": slug, } if os.path.isdir(location): node.update({ "kind": "Topic", "id": slug, "children": sorted([construct_node(os.path.join(location, s), current_path, node_cache, channel) for s in os.listdir(location)], key=lambda x: (not x.get("topic_spotlight", False) if x else True, x.get("title", "") if x else "")), }) node["children"] = [child for child in node["children"] if child] node.update(meta_data) # Finally, can add contains contains = set([]) for ch in node["children"]: contains = contains.union(ch.get("contains", set([]))) contains = contains.union(set([ch["kind"]])) node["contains"] = list(contains) else: extension = base_name.split(".")[-1] kind = file_kind_map.get(extension, None) if not kind: return None elif kind in ["Video", "Audio", "Image"]: from kaa import metadata as kaa_metadata info = kaa_metadata.parse(location) data_meta = {} for meta_key, data_fn in file_meta_data_map.items(): if data_fn(info): data_meta[meta_key] = data_fn(info) if data_meta.get("codec", None): data_meta["{kind}_codec".format(kind=kind.lower())] = data_meta["codec"] del data_meta["codec"] data_meta.update(meta_data) meta_data = data_meta id = file_md5(channel["id"], location) node.update({ "id": id, "kind": kind, "format": extension, }) node.update(meta_data) # Copy over content shutil.copy(location, os.path.join(settings.CONTENT_ROOT, id + "." + extension)) logging.debug("%s file %s to local content directory." % ("Copied", slug)) # Verify some required fields: if "title" not in node: logging.warning("Title missing from file {base_name}, using file name instead".format(base_name=base_name)) if os.path.isdir(location): node["title"] = base_name else: node["title"] = os.path.splitext(base_name)[0] # Clean up some fields: # allow tags and keywords to be a single item as a string, convert to list for key in ["tags", "keywords"]: if isinstance(node.get(key, []), basestring): node[key] = [node[key]] if not os.path.isdir(location): nodecopy = copy.deepcopy(node) if kind == "Exercise": node_cache["Exercise"].append(nodecopy) else: node_cache["Content"].append(nodecopy) return node
def __init__(self, directory, parent, name='', display_type=None, add_args=None, create_metainfo=True): self.autovars = [('num_dir_items', 0), ('show_all_items', False)] Playlist.__init__(self, parent=parent, display_type=display_type) self.type = 'dir' self.menu = None # store FileInformation for moving/copying self.files = FileInformation() if self.media: self.files.read_only = True self.files.append(directory) self.dir = os.path.abspath(directory) self.info = mediainfo.get_dir(directory) #FIXME This should be done in the cache create if not self.image: mminfo = mmpython.parse(directory) if mminfo: if mminfo['image']: self.image = mminfo['image'] if mminfo['title']: self.title = mminfo['title'] if mminfo['comment']: self.comment = mminfo['comment'] if name: self.name = Unicode(name) elif self.info['title:filename']: self.name = self.info['title:filename'] elif self.info['title']: self.name = self.info['title'] else: self.name = util.getname(directory, skip_ext=False) if add_args == None and hasattr(parent, 'add_args'): add_args = parent.add_args self.add_args = add_args if self.parent and hasattr(parent, 'skin_display_type'): self.skin_display_type = parent.skin_display_type elif parent: self.skin_display_type = parent.display_type else: self.skin_display_type = display_type if self['show_all_items']: self.display_type = None # set tv to video now if self.display_type == 'tv': display_type = 'video' # set directory variables to default global all_variables self.all_variables = copy.copy(all_variables) # Check mimetype plugins if they want to add something for p in plugin.mimetype(display_type): self.all_variables += p.dirconfig(self) # set the variables to the default values for var in self.all_variables: if hasattr(parent, var[0]): setattr(self, var[0], getattr(parent, var[0])) elif hasattr(config, var[0]): setattr(self, var[0], getattr(config, var[0])) else: setattr(self, var[0], False) self.modified_vars = [] # Check for a cover in current dir if self.info['image']: image = self.info['image'] else: image = util.getimage(os.path.join(directory, 'cover')) # if we have an image then use it if image: self.image = image self.files.image = image # Check for a folder.fxd in current dir self.folder_fxd = directory + '/folder.fxd' if vfs.isfile(self.folder_fxd): self.set_fxd_file(self.folder_fxd) # Check mimetype plugins if they want to add something for p in plugin.mimetype(display_type): p.dirinfo(self) if self.DIRECTORY_SORT_BY_DATE == 2 and self.display_type != 'tv': self.DIRECTORY_SORT_BY_DATE = 0 # create some extra info if create_metainfo: self.create_metainfo()
def play(self, options, item): """ play a videoitem with mplayer """ logger.log(9, 'options=%r', options) for k, v in item.__dict__.items(): logger.log(9, 'item[%s]=%r', k, v) mode = item.mode url = item.url self.options = options self.item = item self.item_info = None self.item_length = -1 self.item.elapsed = 0 if mode == 'file': url = item.url[6:] self.item_info = mmpython.parse(url) if hasattr(self.item_info, 'get_length'): self.item_length = self.item_info.get_endpos() self.dynamic_seek_control = True if url.startswith('dvd://') and url[-1] == '/': url += '1' if url == 'vcd://': c_len = 0 for i in range(len(item.info.tracks)): if item.info.tracks[i].length > c_len: c_len = item.info.tracks[i].length url = item.url + str(i + 1) url = Unicode(url) try: logger.debug('MPlayer.play(): mode=%s, url=%s', mode, url) except UnicodeError: logger.debug('MPlayer.play(): [non-ASCII data]') if mode == 'file' and not os.path.isfile(url): # This event allows the videoitem which contains subitems to # try to play the next subitem return '%s\nnot found' % os.path.basename(url) set_vcodec = False if item['xvmc'] and item['type'][:6] in ['MPEG-1', 'MPEG-2', 'MPEG-T']: set_vcodec = True mode = item.mimetype if not config.MPLAYER_ARGS.has_key(mode): logger.info('MPLAYER_ARGS not defined for %r, using default', mode) mode = 'default' logger.debug('mode=%s args=%s', mode, config.MPLAYER_ARGS[mode]) # Build the MPlayer command args = { 'nice': config.MPLAYER_NICE, 'cmd': config.MPLAYER_CMD, 'vo': '-vo %s' % config.MPLAYER_VO_DEV, 'vo_opts': config.MPLAYER_VO_DEV_OPTS, 'vc': '', 'ao': '-ao %s' % config.MPLAYER_AO_DEV, 'ao_opts': config.MPLAYER_AO_DEV_OPTS, 'default_args': config.MPLAYER_ARGS_DEF, 'mode_args': config.MPLAYER_ARGS[mode], 'fxd_args': ' '.join(options), 'geometry': '', 'verbose': '', 'dvd-device': '', 'cdrom-device': '', 'alang': '', 'aid': '', 'slang': '', 'sid': '', 'playlist': '', 'field-dominance': '', 'edl': '', 'mc': '', 'delay': '', 'sub': '', 'audiofile': '', 'af': [], 'vf': [], 'url': url, 'disable_osd': False, 'start_position': [], } if item['resume']: t = int(item['resume']) info = mmpython.parse(item.filename) if hasattr(info, 'seek') and t: args['start_position'] = ['-sb', str(info.seek(t))] else: args['start_position'] = ['-ss', str(t)] if config.CONF.x or config.CONF.y: args['geometry'] = '-geometry %d:%d' % (config.CONF.x, config.CONF.y) if config.DEBUG_CHILDAPP: args['verbose'] = '-v' if mode == 'dvd': if config.DVD_LANG_PREF: # There are some bad mastered DVDs out there. E.g. the specials on # the German Babylon 5 Season 2 disc claim they have more than one # audio track, even more then on en. But only the second en works, # mplayer needs to be started without -alang to find the track if hasattr( item, 'mplayer_audio_broken') and item.mplayer_audio_broken: print '*** dvd audio broken, try without alang ***' else: args['alang'] = '-alang %s' % config.DVD_LANG_PREF if config.DVD_SUBTITLE_PREF: # Only use if defined since it will always turn on subtitles when defined args['slang'] = '-slang %s' % config.DVD_SUBTITLE_PREF if mode == 'dvd': # dvd on harddisc args['dvd-device'] = '%s' % item.filename args['url'] = url[:6] + url[url.rfind('/') + 1:] elif mode != 'file' and hasattr(item.media, 'devicename'): args['dvd-device'] = '%s' % item.media.devicename if item.media and hasattr(item.media, 'devicename'): args['cdrom-device'] = '%s' % item.media.devicename if item.selected_subtitle == -1: args['sid'] = '-noautosub' elif item.selected_subtitle is not None: if mode == 'file': if os.path.isfile(os.path.splitext(item.filename)[0] + '.idx'): args['sid'] = '-vobsubid %s' % str(item.selected_subtitle) else: args['sid'] = '-sid %s' % str(item.selected_subtitle) else: args['sid'] = '-sid %s' % str(item.selected_subtitle) if item.selected_audio is not None: args['aid'] = '-aid %s' % str(item.selected_audio) # This comes from the bilingual language selection menu if hasattr(item, 'selected_language') and item.selected_language: if item.selected_language == 'left': args['af'].append('pan=2:1:1:0:0') elif item.selected_language == 'right': args['af'].append('pan=2:0:0:1:1') if not set_vcodec: if item['deinterlace'] and config.MPLAYER_VF_INTERLACED: args['vf'].append(config.MPLAYER_VF_INTERLACED) elif config.MPLAYER_VF_PROGRESSIVE: args['vf'].append(config.MPLAYER_VF_PROGRESSIVE) if config.VIDEO_FIELD_DOMINANCE is not None: args['field-dominance'] = '-field-dominance %d' % int( item['field-dominance']) if os.path.isfile(os.path.splitext(item.filename)[0] + '.edl'): args['edl'] = '-edl %s' % str( os.path.splitext(item.filename)[0] + '.edl') if dialog.overlay_display_supports_dialogs: # Disable the mplayer OSD if we have a better option. args['disable_osd'] = True # Mplayer command and standard arguments if set_vcodec: if item['deinterlace']: bobdeint = 'bobdeint' else: bobdeint = 'nobobdeint' args['vo'] = '-vo xvmc:%s' % bobdeint args['vc'] = '-vc ffmpeg12mc' if hasattr(item, 'is_playlist') and item.is_playlist: args['playlist'] = '-playlist' if args['fxd_args'].find('-playlist') > 0: args['fxd_args'] = args['fxd_args'].replace('-playlist', '') args['playlist'] = '-playlist' # correct avi delay based on kaa.metadata settings if config.MPLAYER_SET_AUDIO_DELAY and item.info.has_key( 'delay') and item.info['delay'] > 0: args['mc'] = '-mc %s' % str(int(item.info['delay']) + 1) args['delay'] = '-delay -%s' % str(item.info['delay']) # mplayer A/V is screwed up when setrting screen refresh rate to the same value as the movies FPS # this does happen almost exclusively at 23.976 FPS. Let's try to fix it. if config.MPLAYER_RATE_SET_FROM_VIDEO and item.getattr('fps') in [ '23.976', '24.000' ]: args['mc'] = '-mc %s' % str(int(config.MPLAYER_AUDIO_DELAY) + 1) args['delay'] = '-delay %s' % str(config.MPLAYER_AUDIO_DELAY) # autocrop if config.MPLAYER_AUTOCROP and not item.network_play and args[ 'fxd_args'].find('crop=') == -1: logger.debug('starting autocrop') (x1, y1, x2, y2) = (1000, 1000, 0, 0) crop_points = config.MPLAYER_AUTOCROP_START if not isinstance(crop_points, list): crop_points = [crop_points] for crop_point in crop_points: (x1, y1, x2, y2) = self.get_crop(crop_point, x1, y1, x2, y2) if x1 < 1000 and x2 < 1000: args['vf'].append('crop=%s:%s:%s:%s' % (x2 - x1, y2 - y1, x1, y1)) logger.debug('crop=%s:%s:%s:%s', x2 - x1, y2 - y1, x1, y1) if item.subtitle_file: d, f = util.resolve_media_mountdir(item.subtitle_file) util.mount(d) args['sub'] = '-sub %s' % f if item.audio_file: d, f = util.resolve_media_mountdir(item.audio_file) util.mount(d) args['audiofile'] = '-audiofile %s' % f self.plugins = plugin.get('mplayer_video') for p in self.plugins: command = p.play(command, self) vo = ['%(vo)s' % args, '%(vo_opts)s' % args] vo = filter(len, vo) vo = ':'.join(vo) ao = ['%(ao)s' % args, '%(ao_opts)s' % args] ao = filter(len, ao) ao = ':'.join(ao) # process the mplayer options extracting video and audio filters args['default_args'], args = self.find_filters(args['default_args'], args) args['mode_args'], args = self.find_filters(args['mode_args'], args) args['fxd_args'], args = self.find_filters(args['fxd_args'], args) command = ['--prio=%(nice)s' % args] command += ['%(cmd)s' % args] command += ['-slave'] command += str('%(verbose)s' % args).split() command += str('%(geometry)s' % args).split() command += vo.split() command += str('%(vc)s' % args).split() command += ao.split() command += args['dvd-device'] and [ '-dvd-device', '%(dvd-device)s' % args ] or [] command += args['cdrom-device'] and [ '-cdrom-device', '%(cdrom-device)s' % args ] or [] command += str('%(alang)s' % args).split() command += str('%(aid)s' % args).split() command += str('%(audiofile)s' % args).split() command += str('%(slang)s' % args).split() command += str('%(sid)s' % args).split() command += str('%(sub)s' % args).split() command += str('%(field-dominance)s' % args).split() command += str('%(edl)s' % args).split() command += str('%(mc)s' % args).split() command += str('%(delay)s' % args).split() command += args['default_args'].split() command += args['mode_args'].split() command += args['fxd_args'].split() command += args['af'] and ['-af', '%s' % ','.join(args['af'])] or [] command += args['vf'] and ['-vf', '%s' % ','.join(args['vf'])] or [] command += args['disable_osd'] and ['-osdlevel', '0'] or [] command += args['start_position'] if config.OSD_SINGLE_WINDOW: command += ['-wid', str(osd.video_window.id)] # This ensures constant subtitle size, disable if you do not like this # and want to have the size as designed by the sutitle creator. # Unfortunately, subtitle size is heavilly dependant on the size of # the video, i.e. width/height so the size varies so much that is unusable if config.MPLAYER_ASS_FONT_SCALE and mode not in ['dvd', 'default']: try: v_height = float(item.getattr('height')) v_width = float(item.getattr('width')) f_scale = (v_width / v_height) * config.MPLAYER_ASS_FONT_SCALE command += ['-ass-font-scale', str(f_scale)] except: pass # use software scaler? #XXX these need to be in the arg list as the scaler will add vf args if '-nosws' in command: command.remove('-nosws') elif '-framedrop' not in command: command += config.MPLAYER_SOFTWARE_SCALER.split() command = filter(len, command) command += str('%(playlist)s' % args).split() command += ['%(url)s' % args] logger.debug(' '.join(command[1:])) #if plugin.getbyname('MIXER'): #plugin.getbyname('MIXER').reset() self.paused = False rc.add_app(self) self.app = MPlayerApp(command, self) dialog.enable_overlay_display(AppTextDisplay(self.show_message)) self.play_state_dialog = None return None
def __init__(self, path): self.info = {} try: info = metadata.parse(os.path.normpath(path)) except: sys.stderr.write("METADATA, problem with %s" % path) return if not info: self.info = {} return if not hasattr(info, 'mime'): self.info = {} return if not info.mime: self.info = {} return self.mime = info.mime if info.mime not in mimes: mimes.append(info.mime) if info.mime == 'audio/wav': self.info = {'samplerate': info.samplerate} self.icon = 'icon-snd' elif info.mime.startswith('audio') or info.mime.endswith('ogg'): self.icon = 'icon-snd' try: pattern = "" if info.has_key('title'): if info.title: title = info.title.encode("latin_1") pattern += title if info.has_key('artist'): if info.artist: artist = info.artist.encode("latin_1") pattern += " " + artist if info.has_key('album'): if info.album: album = info.album.encode("latin_1") pattern += " " + album if info.has_key('comment'): if len(info.comment) > 0: comment = info.comment.encode("latin_1") pattern += " " + comment if pattern: enc = chardet.detect(pattern)['encoding'] if enc == 'EUC-TW' or enc == 'windows-1255' or enc == 'MacCyrillic' or enc == 'TIS-620' or enc == 'KOI8-R' or enc == 'IBM866': enc = 'CP1251' elif not enc or enc.startswith('ISO-8859'): enc = "latin1" else: enc = None except: if info.has_key('title'): if info.title: title = slughifi(info.title) if info.has_key('artist'): if len(info.artist) > 0: artist = slughifi(info.artist) if info.has_key('album'): if info.album: album = slughifi(info.album) if info.has_key('comment'): if info.comment: comment = slughifi(info.comment) enc = None for key in ['samplerate', 'date', 'bitrate', 'trackno']: if hasattr(info, i): self.info[key] = getattr(info, key) if hasattr(info, 'length'): self.info['length'] = info.length # getPlayTimeString(value) if hasattr(info, 'comment'): try: tmp = value.encode("latin_1") try: tmp = unicode(tmp, chardet.detect(tmp)['encoding']) except: tmp = re.sub('[^a-zA-Z0-9\\s\\-]{1}', replace_char, value).lower() except: tmp = re.sub('[^a-zA-Z0-9\\s\\-]{1}', replace_char, value).lower() if re.sub('\s+', '', tmp): self.info['comment'] = tmp if hasattr(info, 'album') and enc: try: self.info['album'] = unicode(album, enc) except UnicodeEncodeError: self.info['album'] = slughifi(album) if hasattr(info, 'artist') and enc: try: self.info['artist'] = unicode(artist, enc) except UnicodeEncodeError: self.info['artist'] = slughifi(artist) if hasattr(info, 'title') and enc: try: self.info['title'] = unicode(title, enc) except UnicodeEncodeError: self.info['title'] = slughifi(title) elif info.mime.startswith('video') or \ info.mime == 'application/ogm' or \ info.mime == 'application/mkv': if info.mime.endswith('x-msvideo'): self.icon = 'icon-avi' else: self.icon = 'icon-vid' for key in ['comment', 'producer', 'genre', 'country']: if hasattr(info, key): self.info[key] = getattr(info, key) if hasattr(info, 'length'): self.info['length'] = info.length #getPlayTimeString(value) if hasattr(info, 'all_header'): if len(info.all_header) > 0: for k in info.all_header[0]: self.info[k] = info.all_header[0][k] try: if info.video[0].codec: self.info['codec'] = info.video[0].codec if info.video[0].fps: self.info['fps'] = "%.0d" % info.video[0].fps if info.video[0].width: self.info['width'] = info.video[0].width if info.video[0].height: self.info['height'] = info.video[0].height if info.header['INFO']['ISRC']: self.info['source'] = info.header['INFO']['ISRC'] except: pass
def play(self, options, item): """ play a videoitem with mplayer """ logger.log( 9, 'options=%r', options) for k, v in item.__dict__.items(): logger.log( 9, 'item[%s]=%r', k, v) mode = item.mode url = item.url self.options = options self.item = item self.item_info = None self.item_length = -1 self.item.elapsed = 0 if mode == 'file': url = item.url[6:] self.item_info = mmpython.parse(url) if hasattr(self.item_info, 'get_length'): self.item_length = self.item_info.get_endpos() self.dynamic_seek_control = True if url.startswith('dvd://') and url[-1] == '/': url += '1' if url == 'vcd://': c_len = 0 for i in range(len(item.info.tracks)): if item.info.tracks[i].length > c_len: c_len = item.info.tracks[i].length url = item.url + str(i+1) url=Unicode(url) try: logger.debug('MPlayer.play(): mode=%s, url=%s', mode, url) except UnicodeError: logger.debug('MPlayer.play(): [non-ASCII data]') if mode == 'file' and not os.path.isfile(url): # This event allows the videoitem which contains subitems to # try to play the next subitem return '%s\nnot found' % os.path.basename(url) set_vcodec = False if item['xvmc'] and item['type'][:6] in ['MPEG-1', 'MPEG-2', 'MPEG-T']: set_vcodec = True mode = item.mimetype if not config.MPLAYER_ARGS.has_key(mode): logger.info('MPLAYER_ARGS not defined for %r, using default', mode) mode = 'default' logger.debug('mode=%s args=%s', mode, config.MPLAYER_ARGS[mode]) # Build the MPlayer command args = { 'nice': config.MPLAYER_NICE, 'cmd': config.MPLAYER_CMD, 'vo': '-vo %s' % config.MPLAYER_VO_DEV, 'vo_opts': config.MPLAYER_VO_DEV_OPTS, 'vc': '', 'ao': '-ao %s' % config.MPLAYER_AO_DEV, 'ao_opts': config.MPLAYER_AO_DEV_OPTS, 'default_args': config.MPLAYER_ARGS_DEF, 'mode_args': config.MPLAYER_ARGS[mode], 'fxd_args': ' '.join(options), 'geometry': '', 'verbose': '', 'dvd-device': '', 'cdrom-device': '', 'alang': '', 'aid': '', 'slang': '', 'sid': '', 'playlist': '', 'field-dominance': '', 'edl': '', 'mc': '', 'delay': '', 'sub': '', 'audiofile': '', 'af': [], 'vf': [], 'url': url, 'disable_osd': False, 'start_position': [], } if item['resume']: t = int(item['resume']) info = mmpython.parse(item.filename) if hasattr(info, 'seek') and t: args['start_position']=['-sb' , str(info.seek(t))] else: args['start_position']=['-ss', str(t)] if config.CONF.x or config.CONF.y: args['geometry'] = '-geometry %d:%d' % (config.CONF.x, config.CONF.y) if config.DEBUG_CHILDAPP: args['verbose'] = '-v' if mode == 'dvd': if config.DVD_LANG_PREF: # There are some bad mastered DVDs out there. E.g. the specials on # the German Babylon 5 Season 2 disc claim they have more than one # audio track, even more then on en. But only the second en works, # mplayer needs to be started without -alang to find the track if hasattr(item, 'mplayer_audio_broken') and item.mplayer_audio_broken: print '*** dvd audio broken, try without alang ***' else: args['alang'] = '-alang %s' % config.DVD_LANG_PREF if config.DVD_SUBTITLE_PREF: # Only use if defined since it will always turn on subtitles when defined args['slang'] = '-slang %s' % config.DVD_SUBTITLE_PREF if mode == 'dvd': # dvd on harddisc args['dvd-device'] = '%s' % item.filename args['url'] = url[:6] + url[url.rfind('/')+1:] elif mode != 'file' and hasattr(item.media, 'devicename'): args['dvd-device'] = '%s' % item.media.devicename if item.media and hasattr(item.media, 'devicename'): args['cdrom-device'] = '%s' % item.media.devicename if item.selected_subtitle == -1: args['sid'] = '-noautosub' elif item.selected_subtitle is not None: if mode == 'file': if os.path.isfile(os.path.splitext(item.filename)[0]+'.idx'): args['sid'] = '-vobsubid %s' % str(item.selected_subtitle) else: args['sid'] = '-sid %s' % str(item.selected_subtitle) else: args['sid'] = '-sid %s' % str(item.selected_subtitle) if item.selected_audio is not None: args['aid'] = '-aid %s' % str(item.selected_audio) # This comes from the bilingual language selection menu if hasattr(item, 'selected_language') and item.selected_language: if item.selected_language == 'left': args['af'].append('pan=2:1:1:0:0') elif item.selected_language == 'right': args['af'].append('pan=2:0:0:1:1') if not set_vcodec: if item['deinterlace'] and config.MPLAYER_VF_INTERLACED: args['vf'].append(config.MPLAYER_VF_INTERLACED) elif config.MPLAYER_VF_PROGRESSIVE: args['vf'].append(config.MPLAYER_VF_PROGRESSIVE) if config.VIDEO_FIELD_DOMINANCE is not None: args['field-dominance'] = '-field-dominance %d' % int(item['field-dominance']) if os.path.isfile(os.path.splitext(item.filename)[0]+'.edl'): args['edl'] = '-edl %s' % str(os.path.splitext(item.filename)[0]+'.edl') if dialog.overlay_display_supports_dialogs: # Disable the mplayer OSD if we have a better option. args['disable_osd'] = True # Mplayer command and standard arguments if set_vcodec: if item['deinterlace']: bobdeint='bobdeint' else: bobdeint='nobobdeint' args['vo'] = '-vo xvmc:%s' % bobdeint args['vc'] = '-vc ffmpeg12mc' if hasattr(item, 'is_playlist') and item.is_playlist: args['playlist'] = '-playlist' if args['fxd_args'].find('-playlist') > 0: args['fxd_args'] = args['fxd_args'].replace('-playlist', '') args['playlist'] = '-playlist' # correct avi delay based on kaa.metadata settings if config.MPLAYER_SET_AUDIO_DELAY and item.info.has_key('delay') and item.info['delay'] > 0: args['mc'] = '-mc %s' % str(int(item.info['delay'])+1) args['delay'] = '-delay -%s' % str(item.info['delay']) # mplayer A/V is screwed up when setrting screen refresh rate to the same value as the movies FPS # this does happen almost exclusively at 23.976 FPS. Let's try to fix it. if config.MPLAYER_RATE_SET_FROM_VIDEO and item.getattr('fps') in ['23.976', '24.000' ]: args['mc'] = '-mc %s' % str(int(config.MPLAYER_AUDIO_DELAY)+1) args['delay'] = '-delay %s' % str(config.MPLAYER_AUDIO_DELAY) # autocrop if config.MPLAYER_AUTOCROP and not item.network_play and args['fxd_args'].find('crop=') == -1: logger.debug('starting autocrop') (x1, y1, x2, y2) = (1000, 1000, 0, 0) crop_points = config.MPLAYER_AUTOCROP_START if not isinstance(crop_points, list): crop_points = [crop_points] for crop_point in crop_points: (x1, y1, x2, y2) = self.get_crop(crop_point, x1, y1, x2, y2) if x1 < 1000 and x2 < 1000: args['vf'].append('crop=%s:%s:%s:%s' % (x2-x1, y2-y1, x1, y1)) logger.debug('crop=%s:%s:%s:%s', x2 - x1, y2 - y1, x1, y1) if item.subtitle_file: d, f = util.resolve_media_mountdir(item.subtitle_file) util.mount(d) args['sub'] = '-sub %s' % f if item.audio_file: d, f = util.resolve_media_mountdir(item.audio_file) util.mount(d) args['audiofile'] = '-audiofile %s' % f self.plugins = plugin.get('mplayer_video') for p in self.plugins: command = p.play(command, self) vo = ['%(vo)s' % args, '%(vo_opts)s' % args] vo = filter(len, vo) vo = ':'.join(vo) ao = ['%(ao)s' % args, '%(ao_opts)s' % args] ao = filter(len, ao) ao = ':'.join(ao) # process the mplayer options extracting video and audio filters args['default_args'], args = self.find_filters(args['default_args'], args) args['mode_args'], args = self.find_filters(args['mode_args'], args) args['fxd_args'], args = self.find_filters(args['fxd_args'], args) command = ['--prio=%(nice)s' % args] command += ['%(cmd)s' % args] command += ['-slave'] command += str('%(verbose)s' % args).split() command += str('%(geometry)s' % args).split() command += vo.split() command += str('%(vc)s' % args).split() command += ao.split() command += args['dvd-device'] and ['-dvd-device', '%(dvd-device)s' % args] or [] command += args['cdrom-device'] and ['-cdrom-device', '%(cdrom-device)s' % args] or [] command += str('%(alang)s' % args).split() command += str('%(aid)s' % args).split() command += str('%(audiofile)s' % args).split() command += str('%(slang)s' % args).split() command += str('%(sid)s' % args).split() command += str('%(sub)s' % args).split() command += str('%(field-dominance)s' % args).split() command += str('%(edl)s' % args).split() command += str('%(mc)s' % args).split() command += str('%(delay)s' % args).split() command += args['default_args'].split() command += args['mode_args'].split() command += args['fxd_args'].split() command += args['af'] and ['-af', '%s' % ','.join(args['af'])] or [] command += args['vf'] and ['-vf', '%s' % ','.join(args['vf'])] or [] command += args['disable_osd'] and ['-osdlevel', '0'] or [] command += args['start_position'] if config.OSD_SINGLE_WINDOW: command += ['-wid', str(osd.video_window.id)] # This ensures constant subtitle size, disable if you do not like this # and want to have the size as designed by the sutitle creator. # Unfortunately, subtitle size is heavilly dependant on the size of # the video, i.e. width/height so the size varies so much that is unusable if config.MPLAYER_ASS_FONT_SCALE and mode not in ['dvd', 'default']: v_height = float(item.getattr('height')) v_width = float(item.getattr('width')) f_scale = (v_width / v_height) * config.MPLAYER_ASS_FONT_SCALE command += ['-ass-font-scale', str(f_scale)] # use software scaler? #XXX these need to be in the arg list as the scaler will add vf args if '-nosws' in command: command.remove('-nosws') elif '-framedrop' not in command: command += config.MPLAYER_SOFTWARE_SCALER.split() command = filter(len, command) command += str('%(playlist)s' % args).split() command += ['%(url)s' % args] logger.debug(' '.join(command[1:])) #if plugin.getbyname('MIXER'): #plugin.getbyname('MIXER').reset() self.paused = False rc.add_app(self) self.app = MPlayerApp(command, self) dialog.enable_overlay_display(AppTextDisplay(self.show_message)) self.play_state_dialog = None return None
# main function, will be called when this file is executed, not imported # args: mplayer, videofile, imagefile, [ pos ] # if __name__ == "__main__": import popen2 mplayer = os.path.abspath(sys.argv[1]) filename = os.path.abspath(sys.argv[2]) imagefile = os.path.abspath(sys.argv[3]) try: position = sys.argv[4] except IndexError: try: mminfo = mmpython.parse(filename) position = str(int(mminfo.video[0].length / 2.0)) if hasattr(mminfo, 'type'): if mminfo.type in ('MPEG-TS', 'MPEG-PES'): position = str(int(mminfo.video[0].length / 20.0)) except: # else arbitrary consider that file is 1Mbps and grab position at 10% position = os.stat(filename)[ST_SIZE]/1024/1024/10.0 if position < 360: position = '360' else: position = str(int(position)) # chdir to tmp so we have write access os.chdir('/tmp')
def get_metadata(self): try: self.metadata = metadata.parse(self.complete_path) except: self.metadata = {}