Exemplo n.º 1
0
    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()
Exemplo n.º 2
0
    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()
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    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()
Exemplo n.º 5
0
    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
Exemplo n.º 6
0
    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