def play(self, arg=None, menuw=None, alternateplayer=False): """ execute commands if defined """ if config.VIDEO_PRE_PLAY: os.system(config.VIDEO_PRE_PLAY) """ play the item. """ if not self.possible_player: for p in plugin.getbyname(plugin.VIDEO_PLAYER, True): rating = p.rate(self) * 10 if config.VIDEO_PREFERED_PLAYER == p.name: rating += 1 if hasattr(self, 'force_player') and p.name == self.force_player: rating += 100 self.possible_player.append((rating, p)) self.possible_player.sort(lambda l, o: -cmp(l[0], o[0])) if alternateplayer: self.possible_player.reverse() if not self.possible_player: return self.player_rating, self.player = self.possible_player[0] if self.parent: self.parent.current_item = self if not self.menuw: self.menuw = menuw # if we have variants, play the first one as default if self.variants: self.variants[0].play(arg, menuw) return # if we have subitems (a movie with more than one file), # we start playing the first that is physically available if self.subitems: self.error_in_subitem = 0 self.last_error_msg = '' self.current_subitem = None result = self.set_next_available_subitem() if self.current_subitem: # 'result' is always 1 in this case # The media is available now for playing # Pass along the options, without loosing the subitem's own # options if self.current_subitem.mplayer_options: if self.mplayer_options: self.current_subitem.mplayer_options += ' ' + self.mplayer_options else: self.current_subitem.mplayer_options = self.mplayer_options # When playing a subitem, the menu must be hidden. If it is not, # the playing will stop after the first subitem, since the # PLAY_END/USER_END event is not forwarded to the parent # videoitem. # And besides, we don't need the menu between two subitems. self.menuw.hide() self.last_error_msg = self.current_subitem.play( arg, self.menuw) if self.last_error_msg: self.error_in_subitem = 1 # Go to the next playable subitem, using the loop in # eventhandler() self.eventhandler(PLAY_END) elif not result: # No media at all was found: error ConfirmBox(text=(_('No media found for "%s".\n') + _('Please insert the media.')) % self.name, handler=self.play).show() return # normal plackback of one file if self.url.startswith('file://'): file = self.filename if self.media_id: mountdir, file = util.resolve_media_mountdir( self.media_id, file) if mountdir: util.mount(mountdir) else: self.menuw.show() ConfirmBox(text=(_('No media found for "%s".\n') + _('Please insert the media.')) % file, handler=self.play).show() return elif self.media: util.mount(os.path.dirname(self.filename)) elif self.mode in ('dvd', 'vcd') and not self.filename and not self.media: media = util.check_media(self.media_id) if media: self.media = media else: self.menuw.show() ConfirmBox(text=(_('No media found for "%s".\n') + _('Please insert the media.')) % self.url, handler=self.play).show() return if self.player_rating < 10: AlertBox(text=_('No player for this item found')).show() return mplayer_options = self.mplayer_options.split(' ') if not mplayer_options: mplayer_options = [] if arg: mplayer_options += arg.split(' ') if self.menuw.visible: self.menuw.hide() self.plugin_eventhandler(PLAY, menuw) error = self.player.play(mplayer_options, self) if error: # If we are a subitem we don't show any error message before # having tried all the subitems if hasattr(self.parent, 'subitems') and self.parent.subitems: return error else: AlertBox(text=error, handler=self.error_handler).show()
def __play(self, arg=None, menuw=None): # execute commands if defined if config.VIDEO_PRE_PLAY: os.system(config.VIDEO_PRE_PLAY) if self.parent: self.parent.current_item = self if not self.menuw: self.menuw = menuw # if we have variants, play the first one as default if self.variants: self.variants[0].play(arg, menuw) return # if we have subitems (a movie with more than one file), # we start playing the first that is physically available if self.subitems: self.error_in_subitem = 0 self.last_error_msg = '' self.current_subitem = None result = self.set_next_available_subitem() if self.current_subitem: # 'result' is always 1 in this case # The media is available now for playing # Pass along the options, without loosing the subitem's own # options if self.current_subitem.mplayer_options: if self.mplayer_options: # With this set the player options are incorrect when there is more than 1 item #self.current_subitem.mplayer_options += ' ' + self.mplayer_options pass else: self.current_subitem.mplayer_options = self.mplayer_options # When playing a subitem, the menu must be hidden. If it is not, # the playing will stop after the first subitem, since the # PLAY_END/USER_END event is not forwarded to the parent # videoitem. # And besides, we don't need the menu between two subitems. self.menuw.hide() self.last_error_msg = self.current_subitem.play( arg, self.menuw) if self.last_error_msg: self.error_in_subitem = 1 # Go to the next playable subitem, using the loop in # eventhandler() self.eventhandler(PLAY_END) elif not result: # No media at all was found: error ConfirmBox(text=(_( 'No media found for "%(name)s".\nPlease insert the media "%(media_id)s".' )) % ({ 'name': self.name, 'media_id': self.media_id }), handler=self.play).show() return # normal plackback of one file if self.url.startswith('file://'): file = self.filename if self.media_id: mountdir, file = util.resolve_media_mountdir( self.media_id, file) if mountdir: util.mount(mountdir) else: self.menuw.show() ConfirmBox(text=(_('No media found for "%(file)s".\nPlease insert the media "%(media_id)s".')) % \ ({'file': file, 'media_id': self.media_id}), handler=self.play).show() return elif self.media: util.mount(os.path.dirname(self.filename)) # dvd and vcd elif self.mode in ('dvd', 'vcd') and not self.filename and not self.media: media = util.check_media(self.media_id) if media: self.media = media else: self.menuw.show() ConfirmBox(text=(_( 'No media found for "%(media_id)s".\nPlease insert the media "%(url)s".' )) % ({ 'media_id': self.media_id, 'url': self.url }), handler=self.play).show() return mplayer_options = self.mplayer_options.split(' ') if not mplayer_options: mplayer_options = [] if arg: mplayer_options += arg.split(' ') if self.menuw.visible: self.menuw.hide() self.plugin_eventhandler(PLAY, menuw) self.menuw.delete_submenu() error = self.player.play(mplayer_options, self) # Clear any resume settings self['resume'] = '' if error: # If we are a subitem we don't show any error message before # having tried all the subitems if hasattr(self.parent, 'subitems') and self.parent.subitems: return error else: AlertBox(text=error, handler=self.error_handler).show()
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
def __play(self, arg=None, menuw=None): # execute commands if defined if config.VIDEO_PRE_PLAY: os.system(config.VIDEO_PRE_PLAY) if self.parent: self.parent.current_item = self if not self.menuw: self.menuw = menuw # if we have variants, play the first one as default if self.variants: self.variants[0].play(arg, menuw) return # if we have subitems (a movie with more than one file), # we start playing the first that is physically available if self.subitems: self.error_in_subitem = 0 self.last_error_msg = '' self.current_subitem = None result = self.set_next_available_subitem() if self.current_subitem: # 'result' is always 1 in this case # The media is available now for playing # Pass along the options, without loosing the subitem's own # options if self.current_subitem.mplayer_options: if self.mplayer_options: # With this set the player options are incorrect when there is more than 1 item #self.current_subitem.mplayer_options += ' ' + self.mplayer_options pass else: self.current_subitem.mplayer_options = self.mplayer_options # When playing a subitem, the menu must be hidden. If it is not, # the playing will stop after the first subitem, since the # PLAY_END/USER_END event is not forwarded to the parent # videoitem. # And besides, we don't need the menu between two subitems. self.menuw.hide() self.last_error_msg = self.current_subitem.play(arg, self.menuw) if self.last_error_msg: self.error_in_subitem = 1 # Go to the next playable subitem, using the loop in # eventhandler() self.eventhandler(PLAY_END) elif not result: # No media at all was found: error ConfirmBox(text=(_('No media found for "%(name)s".\nPlease insert the media "%(media_id)s".')) % ({'name': self.name, 'media_id': self.media_id}), handler=self.play).show() return # normal plackback of one file if self.url.startswith('file://'): file = self.filename if self.media_id: mountdir, file = util.resolve_media_mountdir(self.media_id,file) if mountdir: util.mount(mountdir) else: self.menuw.show() ConfirmBox(text=(_('No media found for "%(file)s".\nPlease insert the media "%(media_id)s".')) % \ ({'file': file, 'media_id': self.media_id}), handler=self.play).show() return elif self.media: util.mount(os.path.dirname(self.filename)) # dvd and vcd elif self.mode in ('dvd', 'vcd') and not self.filename and not self.media: media = util.check_media(self.media_id) if media: self.media = media else: self.menuw.show() ConfirmBox(text=(_('No media found for "%(media_id)s".\nPlease insert the media "%(url)s".')) % ({ 'media_id': self.media_id, 'url': self.url}), handler=self.play).show() return mplayer_options = self.mplayer_options.split(' ') if not mplayer_options: mplayer_options = [] if arg: mplayer_options += arg.split(' ') if self.menuw.visible: self.menuw.hide() self.plugin_eventhandler(PLAY, menuw) self.menuw.delete_submenu() error = self.player.play(mplayer_options, self) # Clear any resume settings self['resume'] = '' if error: # If we are a subitem we don't show any error message before # having tried all the subitems if hasattr(self.parent, 'subitems') and self.parent.subitems: return error else: AlertBox(text=error, handler=self.error_handler).show()
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
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