Beispiel #1
0
class PluginInterface(plugin.ItemPlugin):
    """
    Archive recorded TV programmes using EncodingServer

    This plugin needs a running encodingserver to work properly.
    You can start an encodingserver with 'freevo encodingserver start'.

    To activate, put the following line in local_conf.py:
    | plugin.activate('video.reencode')
    """

    def __init__(self):
        logger.debug('reencode.PluginInterface.__init__(self)')
        plugin.ItemPlugin.__init__(self)
        self.server = EncodingClientActions()
        self.title = ''
        self.source = ''
        self.output = ''
        self.resetprofile()
        self.timeslice = [ None, None ]
        self.warn_once_savedir = True

    def resetprofile(self):
        self.profile = {}
        self.timeslice = [ None, None ]
        self.profile['container'] = config.REENCODE_CONTAINER
        self.profile['resolution'] = config.REENCODE_RESOLUTION
        self.profile['videocodec'] = config.REENCODE_VIDEOCODEC
        self.profile['altprofile'] = config.REENCODE_ALTPROFILE
        self.profile['audiocodec'] = config.REENCODE_AUDIOCODEC
        self.profile['numpasses'] = config.REENCODE_NUMPASSES
        self.profile['numthreads'] = config.REENCODE_NUMTHREADS
        self.profile['videobitrate'] = config.REENCODE_VIDEOBITRATE
        self.profile['audiobitrate'] = config.REENCODE_AUDIOBITRATE
        self.profile['videofilter'] = config.REENCODE_VIDEOFILTER


    def config(self):
        '''config is called automatically, for default settings run:
        freevo plugins -i video.reencode
        '''
        logger.log( 9, 'config(self)')
        return [
            ('REENCODE_CONTAINER', 'avi', 'Container type'),
            ('REENCODE_RESOLUTION', 'Optimal', 'Resolution'),
            ('REENCODE_VIDEOCODEC', 'XviD', 'Video codec'),
            ('REENCODE_ALTPROFILE', None, 'Alternate Encoding Profile'),
            ('REENCODE_VIDEOBITRATE', '800', 'Video bit rate'),
            ('REENCODE_AUDIOCODEC', 'MPEG 1 Layer 3 (mp3)', 'Audio codec'),
            ('REENCODE_AUDIOBITRATE', '128', 'Audio bit rate'),
            ('REENCODE_NUMPASSES', '2', 'Number of passes'),
            ('REENCODE_VIDEOFILTER', 'None', 'Video Filter'),
            ('REENCODE_NUMTHREADS','1','Number of Encoding Threads'),
        ]


    #def eventhandler(self, event, menuw=None, arg=None):
    #    _debug_('eventhandler(self, event=%r, menuw=%r, arg=%r)' % (event, menuw, arg), 2)
    #    return self.item.eventhandler(event, menuw=menuw, arg=arg)


    def prepare_output(self, source):
        """Prepare the output file path. Note that we strip the extension from the output file name"""
        output = os.path.splitext(source)[0]
        directory = os.path.dirname(output)
        #can we write in that directory? If so, the reencoded file will go there
        if directory and os.path.isabs(output) and os.path.isdir(directory) and \
                os.access(directory, os.R_OK | os.W_OK | os.X_OK):
            return output
        basename = os.path.basename(output)
        if basename == '':
            basename = 'reencoded_video'

        # check that we have a default place where we can write the resulting
        # reencoded file (it is up to the user to create the dir with correct
        # permission)
        directory = config.ENCODINGSERVER_SAVEDIR
        if directory and os.path.isdir(directory) and os.access(directory, os.R_OK | os.W_OK | os.X_OK):
            return os.path.join(directory, basename)
        else:
            #in this case, it all ends into a temporary file
            return os.path.join('.', basename)


    def actions(self, item):
        logger.log( 9, 'actions(self, item)')

        if item.type == 'video' and item.mode == 'file':
            self.item = item
            self.title = item.name
            self.source = item.filename
            #this is temporarily set , since it is called too often
            #(even when browsing a directory ot TV recordings)
            self.output = '(to be set later)'
            #
            logger.log( 8, 'item.__dict__:', item.__dict__)
            return [ (self.encoding_profile_menu, _('Transcode this program...')) ]
        return []


    def getattr(self, attr):
        '''callback function from the skin fxd file to get the display format
        of an item, the attr represents the expression in the skin
        '''
        logger.log( 9, 'getattr(self, attr=%r)', attr)
        if attr == 'disp_title':
            return '%s' % (self.title)
        if attr == 'disp_filename':
            # note that this may be changed by the encodingserver
            # by calling the uniquify_filename()
            # in particular if many jobs are encoded in short sequence
            self.output = self.prepare_output(self.source)
            return uniquify_filename(self.output + '.' +self.profile['container'])
        elif attr == 'disp_container':
            return '%s' % (self.profile['container'])
        elif attr == 'disp_resolution':
            return '%s' % (self.profile['resolution'])
        elif attr == 'disp_videocodec':
            return '%s' % (self.profile['videocodec'])
        elif attr == 'altprofile':
            return '%s' % (self.profile['altprofile'])
        elif attr == 'disp_videobitrate':
            return '%s' % (self.profile['videobitrate'])
        elif attr == 'disp_audiocodec':
            return '%s' % (self.profile['audiocodec'])
        elif attr == 'disp_audiobitrate':
            return '%s' % (self.profile['audiobitrate'])
        elif attr == 'disp_numpasses':
            return '%s' % (self.profile['numpasses'])
        elif attr == 'disp_numthreads':
            return '%s' % (self.profile['numthreads'])
        elif attr == 'disp_videofilter':
            return '%s' % (self.profile['videofilter'])
        return '"%s" not defined' % (attr)


    def encoding_profile_menu(self, menuw=None, arg=None):
        logger.log( 9, 'encoding_profile_menu(self, menuw=%r, arg=%r)', menuw, arg)
        menu_items = []
        menu_items += [ menu.MenuItem(_('Start Encoding'), self.create_job, self.profile) ]
        menu_items += [ menu.MenuItem(_('Select Encoding Profile'), action=self.select_profile) ]
        menu_items += [ menu.MenuItem(_('Modify Container'), action=self.mod_container) ]
        menu_items += [ menu.MenuItem(_('Modify Start Time'), action=self.mod_start_time) ]
        menu_items += [ menu.MenuItem(_('Modify End Time'), action=self.mod_end_time) ]
        menu_items += [ menu.MenuItem(_('Modify Resolution'), action=self.mod_resolution) ]
        menu_items += [ menu.MenuItem(_('Modify Video Codec'), action=self.mod_videocodec) ]
        menu_items += [ menu.MenuItem(_('Modify Video Bit Rate'), action=self.mod_videobitrate) ]
        menu_items += [ menu.MenuItem(_('Modify Audio Codec'), action=self.mod_audiocodec) ]
        menu_items += [ menu.MenuItem(_('Modify Audio Bit Rate'), action=self.mod_audiobitrate) ]
        menu_items += [ menu.MenuItem(_('Modify Number of passes'), action=self.mod_numpasses) ]
        menu_items += [ menu.MenuItem(_('Modify Number of Encoder Threads'), action=self.mod_numthreads) ]
        menu_items += [ menu.MenuItem(_('Modify Video Filter (not implemented)'), action=self.mod_videofilter) ]
        encoding_menu = menu.Menu(_('Choose your encoding profile'), menu_items, item_types = 'video encoding menu')
        encoding_menu.infoitem = self
        menuw.pushmenu(encoding_menu)
        menuw.refresh()


    def select_profile(self, arg=None, menuw=None):
        logger.log( 9, 'select_profile(self, arg=None, menuw=None)')
        menu_items = []
        menu_items += [ menu.MenuItem(_('Xvid Low Quality'), action=self.select_encoding_profile, arg='xvid_low') ]
        menu_items += [ menu.MenuItem(_('Xvid High Quality'), action=self.select_encoding_profile, arg='xvid_high') ]
        menu_items += [ menu.MenuItem(_('iPod'), action=self.select_encoding_profile, arg='ipod') ]
        menu_items += [ menu.MenuItem(_('DVD'), action=self.select_encoding_profile, arg='MPEG 2 (lavc)') ]
        encoding_menu = menu.Menu(_('Select Profile'), menu_items, item_types = 'video encoding menu')
        encoding_menu.infoitem = self
        menuw.pushmenu(encoding_menu)
        menuw.refresh()


    def set_start_time(self, arg=None, menuw=None):
        self.timeslice[0] = arg
        if menuw:
            menuw.back_one_menu(arg='reload')


    def set_end_time(self, arg=None, menuw=None):
        self.timeslice[1] = arg
        if menuw:
            menuw.back_one_menu(arg='reload')


    def _select_time(self, arg=None, menuw=None, which=None):
        bookmarkfile = util.get_bookmarkfile(self.item.filename)
        if not os.path.exists(bookmarkfile):
            self.error(_('No bookmarks are set for this video'))
            return
        menu_items = []
        menu_items = [ menu.MenuItem(_('Do not set'), action=which, arg=None),]
        for line in util.readfile(bookmarkfile):
            sec = int(line)
            hour = int(sec/3600)
            min = int((sec-(hour*3600))/60)
            time = '%0.2d:%0.2d:%0.2d' % (hour,min,sec % 60)
            menu_items.append(menu.MenuItem(time, action=which, arg=sec))
        encoding_menu = menu.Menu(_('Select Time'), menu_items, item_types = 'video encoding menu')
        encoding_menu.infoitem = self
        menuw.pushmenu(encoding_menu)
        menuw.refresh()


    def mod_start_time(self, arg=None, menuw=None):
        self._select_time(arg, menuw, self.set_start_time)


    def mod_end_time(self, arg=None, menuw=None):
        self._select_time(arg, menuw, self.set_end_time)


    def mod_container(self, arg=None, menuw=None):
        logger.log( 9, 'mod_container(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for container in self.server.getContainerCAP()[1]:
            items.append(menu.MenuItem(container, action=self.alter_prop, arg=('container', container)))
        container_menu = menu.Menu(_('Modify Container'), items, item_types = 'video encoding menu')
        container_menu.infoitem = self
        menuw.pushmenu(container_menu)
        menuw.refresh()


    def mod_resolution(self, arg=None, menuw=None):
        logger.log( 9, 'mod_resolution(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for resolution in ('Optimal', '1920:1080', '1280:720', '852:480', '720:576', '720:480', '320:240'):
            items.append(menu.MenuItem(resolution, action=self.alter_prop, arg=('resolution', resolution)))
        resolution_menu = menu.Menu(_('Modify Resolution'), items, item_types = 'video encoding menu')
        resolution_menu.infoitem = self
        menuw.pushmenu(resolution_menu)
        menuw.refresh()


    def mod_videocodec(self, arg=None, menuw=None):
        logger.log( 9, 'mod_videocodec(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for videocodec in self.server.getVideoCodecCAP()[1]:
            items.append(menu.MenuItem(videocodec, action=self.alter_prop, arg=('videocodec', videocodec)))
        videocodec_menu = menu.Menu(_('Modify Video Codec'), items, item_types = 'video encoding menu')
        videocodec_menu.infoitem = self
        menuw.pushmenu(videocodec_menu)
        menuw.refresh()


    def mod_videobitrate(self, arg=None, menuw=None):
        logger.log( 9, 'mod_videobitrate(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for videobitrate in range(400, 2001, 200):
            items.append(menu.MenuItem(videobitrate, action=self.alter_prop, arg=('videobitrate', videobitrate)))
        videobitrate_menu = menu.Menu(_('Modify Video Bitrate'), items, item_types = 'video encoding menu')
        videobitrate_menu.infoitem = self
        menuw.pushmenu(videobitrate_menu)
        menuw.refresh()


    def mod_audiocodec(self, arg=None, menuw=None):
        logger.log( 9, 'mod_audiocodec(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for audiocodec in self.server.getAudioCodecCAP()[1]:
            items.append(menu.MenuItem(audiocodec, action=self.alter_prop, arg=('audiocodec', audiocodec)))
        audiocodec_menu = menu.Menu(_('Modify Video Codec'), items, item_types = 'video encoding menu')
        audiocodec_menu.infoitem = self
        menuw.pushmenu(audiocodec_menu)
        menuw.refresh()


    def mod_audiobitrate(self, arg=None, menuw=None):
        logger.log( 9, 'mod_audiobitrate(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for audiobitrate in (64, 128, 192, 224):
            items.append(menu.MenuItem(audiobitrate, action=self.alter_prop, arg=('audiobitrate', audiobitrate)))
        audiobitrate_menu = menu.Menu(_('Modify Audio Bitrate'), items, item_types = 'video encoding menu')
        audiobitrate_menu.infoitem = self
        menuw.pushmenu(audiobitrate_menu)
        menuw.refresh()


    def mod_numpasses(self, arg=None, menuw=None):
        logger.log( 9, 'mod_numpasses(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for numpasses in (1, 2):
            items.append(menu.MenuItem(numpasses, action=self.alter_prop, arg=('numpasses', numpasses)))
        numpasses_menu = menu.Menu(_('Modify Number of Passes'), items, item_types = 'video encoding menu')
        numpasses_menu.infoitem = self
        menuw.pushmenu(numpasses_menu)
        menuw.refresh()


    def mod_numthreads(self, arg=None, menuw=None):
        logger.log( 9, 'mod_numthreads(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for numthreads in (1, 2, 3, 4, 5, 6, 7, 8):
            items.append(menu.MenuItem(numthreads, action=self.alter_prop, arg=('numthreads', numthreads)))
        numthreads_menu = menu.Menu(_('Modify Number of Encoding threads'), items, item_types = 'video encoding menu')
        numthreads_menu.infoitem = self
        menuw.pushmenu(numthreads_menu)
        menuw.refresh()


    def mod_videofilter(self, arg=None, menuw=None):
        logger.log( 9, 'mod_videofilter(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for videofilter in self.server.getVideoFiltersCAP()[1]:
            items.append(menu.MenuItem(videofilter, action=self.alter_prop, arg=('videofilter', videofilter)))
        videofilter_menu = menu.Menu(_('Modify Video Filter'), items, item_types = 'video encoding menu')
        videofilter_menu.infoitem = self
        menuw.pushmenu(videofilter_menu)
        menuw.refresh()


    def select_encoding_profile(self, arg=None, menuw=None):
        logger.log( 9, 'select_encoding_profile(self, arg=%r, menuw=%r)', arg, menuw)

        if arg == 'xvid_low':
            self.profile['container'] = 'avi'
            self.profile['resolution'] = 'Optimal'
            self.profile['videocodec'] = 'XviD'
            self.profile['altprofile'] = None
            self.profile['videobitrate'] = 800
            self.profile['audiocodec'] = 'MPEG 1 Layer 3 (mp3)'
            self.profile['audiobitrate'] = 128
            self.profile['numpasses'] = 1
            self.profile['videofilter'] = 'None'
        elif arg == 'xvid_high':
            self.profile['container'] = 'avi'
            self.profile['resolution'] = 'Optimal'
            self.profile['videocodec'] = 'XviD'
            self.profile['altprofile'] = None
            self.profile['videobitrate'] = 1200
            self.profile['audiocodec'] = 'MPEG 1 Layer 3 (mp3)'
            self.profile['audiobitrate'] = 128
            self.profile['numpasses'] = 2
            self.profile['videofilter'] = 'None'
        elif arg == 'ipod':
            self.profile['container'] = 'mp4'
            self.profile['resolution'] = '320:240'
            self.profile['videocodec'] = 'MPEG 4 (lavc)'
            self.profile['altprofile'] = 'vcodec=mpeg4:mbd=2:cmp=2:subcmp=2:trell=yes:v4mv=yes:vglobal=1'
            self.profile['videobitrate'] = 1200
            self.profile['audiocodec'] = 'AAC (iPod)'
            self.profile['audiobitrate'] = 192
            self.profile['numpasses'] = 2
            self.profile['videofilter'] = 'ipod'
        elif arg == 'MPEG 2 (lavc)':
            self.profile['container'] = 'mpeg'
            self.profile['resolution'] = '720:480'
            self.profile['videocodec'] = 'MPEG 2 (lavc)'
            self.profile['altprofile'] = None
            self.profile['videobitrate'] = 5200
            self.profile['audiocodec'] = 'AC3'
            self.profile['audiobitrate'] = 224
            self.profile['numpasses'] = 1
            self.profile['videofilter'] = 'None'
        else:
            logger.error('Unknown Profile "%s"', arg)
            self.error(_('Unknown Profile')+(' "%s"' % (arg)))
            return

        if menuw:
            menuw.back_one_menu(arg='reload')


    def alter_prop(self, arg=(None, None), menuw=None):
        logger.log( 9, 'alter_prop(self, arg=%r, menuw=%r)', arg, menuw)
        (prop, val) = arg

        if prop == 'container':
            self.profile['container'] = val
        elif prop == 'resolution':
            self.profile['resolution'] = val
        elif prop == 'videocodec':
            self.profile['videocodec'] = val
        elif prop == 'altprofile':
            self.profile['altprofile'] = val
        elif prop == 'videobitrate':
            self.profile['videobitrate'] = val
        elif prop == 'audiocodec':
            self.profile['audiocodec'] = val
        elif prop == 'audiobitrate':
            self.profile['audiobitrate'] = val
        elif prop == 'numpasses':
            self.profile['numpasses'] = val
        elif prop == 'numthreads':
            self.profile['numthreads'] = val
        elif prop == 'videofilter':
            self.profile['videofilter'] = val
        else:
            logger.error('Unknown property "%s"', prop)
            self.error(_('Unknown Property')+(' "%s"' % (prop)))
            return

        if menuw:
            menuw.back_one_menu(arg='reload')


    def alter_name(self, name):
        '''alter_name is not used'''
        logger.log( 9, 'alter_name(self, name=%r)', name)
        self.menuw.refresh()


    def create_job(self, menuw=None, arg=None):
        logger.log( 9, 'create_job(self, arg=%r, menuw=%r)', arg, menuw)

        profile = arg

        # note that this may later be changed by the uniquify_filename()
        self.output = self.prepare_output(self.source)

        if self.output[:2] == './' and self.warn_once_savedir :
            #it will go into the encodingserver temporary dir, and we cant tell it from
            # this process
            self.warn_once_savedir = False

            AlertBox(text=_('This encoding job will be written to a temporary '
                'directory. Please set the variable ENCODINGSERVER_SAVEDIR to a '
                'directory where the reencoded file can be written to.')).show()
            return

        #we are going to create a job and send it to the encoding server, this can take some time while analyzing

        box = PopupBox(text=_('Please wait, analyzing video...'))
        box.show()
        (status, resp) = self.server.initEncodingJob(self.source, self.output, self.title)
        idnr = resp
        logger.debug('initEncodingJob:status:%s resp:%s', status, resp)
        if not status:
            box.destroy()
            self.error(_('Failed to analyze video.'))
            return

        (status, resp) = self.server.setTimeslice(idnr, self.timeslice)
        logger.debug('setTimeslice:status:%s resp:%s', status, resp)
        if not status:
            box.destroy()
            self.error(resp)
            return

        (status, resp) = self.server.waitCropDetect(idnr)
        logger.debug('WaitCropDetect:status:%s resp:%s', status, resp)
        if not status:
            box.destroy()
            self.error(resp)
            return

        box.destroy()
        if not status:
            self.error(resp)
            return

        (status, resp) = self.server.setContainer(idnr, profile['container'])
        logger.debug('setContainer:status:%s resp:%s', status, resp)
        if not status:
            self.error(resp)
            return

        multipass = profile['numpasses'] > 1
        (status, resp) = self.server.setVideoCodec(idnr, profile['videocodec'], 0, multipass,
            profile['videobitrate'], profile['altprofile'])
        logger.debug('setVideoCodec:status:%s resp:%s', status, resp)
        if not status:
            self.error(resp)
            return

        (status, resp) = self.server.setAudioCodec(idnr, profile['audiocodec'], profile['audiobitrate'])
        logger.debug('setAudioCodec:status:%s resp:%s', status, resp)
        if not status:
            self.error(resp)
            return

        (status, resp) = self.server.setNumThreads(idnr, profile['numthreads'])
        logger.debug('setNumThreads:status:%s resp:%s', status, resp)
        if not status:
            self.error(resp)
            return

        (status, resp) = self.server.setVideoRes(idnr, profile['resolution'])
        logger.debug('setVideoRes:status:%s resp:%s', status, resp)
        if not status:
            self.error(resp)
            return

        #(status, resp) = self.server.setVideoFilters(idnr, vfilters)
        #_debug_('setVideoFilters:status:%s resp:%s' % (status, resp))

        #And finally, queue and start the job
        (status, resp) = self.server.queueIt(idnr, True)
        logger.debug('queueIt:status:%s resp:%s', status, resp)

        if not status:
            self.error(resp)
            return

        self.menuw = menuw
        AlertBox(width=400, height=200, text=_('Encoding started'), handler=self.mopup).show()

        self.resetprofile()
        logger.debug('boe')
        #menuw.delete_menu()
        #menuw.delete_menu()


    def error(self, text=''):
        logger.debug('error(self, text=%r)', text)
        AlertBox(width=400, height=200, text='ERROR: %s' % text).show()


    def mopup(self):
        logger.debug('mopup(self)')
        self.menuw.delete_menu()
        self.menuw.back_one_menu()
Beispiel #2
0
class PluginInterface(plugin.ItemPlugin):
    """
    Archive recorded TV programmes using EncodingServer

    This plugin needs a running encodingserver to work properly.
    You can start an encodingserver with 'freevo encodingserver start'.

    To activate, put the following line in local_conf.py:
    | plugin.activate('video.reencode')
    """
    def __init__(self):
        logger.debug('reencode.PluginInterface.__init__(self)')
        plugin.ItemPlugin.__init__(self)
        self.server = EncodingClientActions()
        self.title = ''
        self.source = ''
        self.output = ''
        self.resetprofile()
        self.timeslice = [None, None]
        self.warn_once_savedir = True

    def resetprofile(self):
        self.profile = {}
        self.timeslice = [None, None]
        self.profile['container'] = config.REENCODE_CONTAINER
        self.profile['resolution'] = config.REENCODE_RESOLUTION
        self.profile['videocodec'] = config.REENCODE_VIDEOCODEC
        self.profile['altprofile'] = config.REENCODE_ALTPROFILE
        self.profile['audiocodec'] = config.REENCODE_AUDIOCODEC
        self.profile['numpasses'] = config.REENCODE_NUMPASSES
        self.profile['numthreads'] = config.REENCODE_NUMTHREADS
        self.profile['videobitrate'] = config.REENCODE_VIDEOBITRATE
        self.profile['audiobitrate'] = config.REENCODE_AUDIOBITRATE
        self.profile['videofilter'] = config.REENCODE_VIDEOFILTER

    def config(self):
        '''config is called automatically, for default settings run:
        freevo plugins -i video.reencode
        '''
        logger.log(9, 'config(self)')
        return [
            ('REENCODE_CONTAINER', 'avi', 'Container type'),
            ('REENCODE_RESOLUTION', 'Optimal', 'Resolution'),
            ('REENCODE_VIDEOCODEC', 'XviD', 'Video codec'),
            ('REENCODE_ALTPROFILE', None, 'Alternate Encoding Profile'),
            ('REENCODE_VIDEOBITRATE', '800', 'Video bit rate'),
            ('REENCODE_AUDIOCODEC', 'MPEG 1 Layer 3 (mp3)', 'Audio codec'),
            ('REENCODE_AUDIOBITRATE', '128', 'Audio bit rate'),
            ('REENCODE_NUMPASSES', '2', 'Number of passes'),
            ('REENCODE_VIDEOFILTER', 'None', 'Video Filter'),
            ('REENCODE_NUMTHREADS', '1', 'Number of Encoding Threads'),
        ]

    #def eventhandler(self, event, menuw=None, arg=None):
    #    _debug_('eventhandler(self, event=%r, menuw=%r, arg=%r)' % (event, menuw, arg), 2)
    #    return self.item.eventhandler(event, menuw=menuw, arg=arg)

    def prepare_output(self, source):
        """Prepare the output file path. Note that we strip the extension from the output file name"""
        output = os.path.splitext(source)[0]
        directory = os.path.dirname(output)
        #can we write in that directory? If so, the reencoded file will go there
        if directory and os.path.isabs(output) and os.path.isdir(directory) and \
                os.access(directory, os.R_OK | os.W_OK | os.X_OK):
            return output
        basename = os.path.basename(output)
        if basename == '':
            basename = 'reencoded_video'

        # check that we have a default place where we can write the resulting
        # reencoded file (it is up to the user to create the dir with correct
        # permission)
        directory = config.ENCODINGSERVER_SAVEDIR
        if directory and os.path.isdir(directory) and os.access(
                directory, os.R_OK | os.W_OK | os.X_OK):
            return os.path.join(directory, basename)
        else:
            #in this case, it all ends into a temporary file
            return os.path.join('.', basename)

    def actions(self, item):
        logger.log(9, 'actions(self, item)')

        if item.type == 'video' and item.mode == 'file':
            self.item = item
            self.title = item.name
            self.source = item.filename
            #this is temporarily set , since it is called too often
            #(even when browsing a directory ot TV recordings)
            self.output = '(to be set later)'
            #
            logger.log(8, 'item.__dict__:', item.__dict__)
            return [(self.encoding_profile_menu,
                     _('Transcode this program...'))]
        return []

    def getattr(self, attr):
        '''callback function from the skin fxd file to get the display format
        of an item, the attr represents the expression in the skin
        '''
        logger.log(9, 'getattr(self, attr=%r)', attr)
        if attr == 'disp_title':
            return '%s' % (self.title)
        if attr == 'disp_filename':
            # note that this may be changed by the encodingserver
            # by calling the uniquify_filename()
            # in particular if many jobs are encoded in short sequence
            self.output = self.prepare_output(self.source)
            return uniquify_filename(self.output + '.' +
                                     self.profile['container'])
        elif attr == 'disp_container':
            return '%s' % (self.profile['container'])
        elif attr == 'disp_resolution':
            return '%s' % (self.profile['resolution'])
        elif attr == 'disp_videocodec':
            return '%s' % (self.profile['videocodec'])
        elif attr == 'altprofile':
            return '%s' % (self.profile['altprofile'])
        elif attr == 'disp_videobitrate':
            return '%s' % (self.profile['videobitrate'])
        elif attr == 'disp_audiocodec':
            return '%s' % (self.profile['audiocodec'])
        elif attr == 'disp_audiobitrate':
            return '%s' % (self.profile['audiobitrate'])
        elif attr == 'disp_numpasses':
            return '%s' % (self.profile['numpasses'])
        elif attr == 'disp_numthreads':
            return '%s' % (self.profile['numthreads'])
        elif attr == 'disp_videofilter':
            return '%s' % (self.profile['videofilter'])
        return '"%s" not defined' % (attr)

    def encoding_profile_menu(self, menuw=None, arg=None):
        logger.log(9, 'encoding_profile_menu(self, menuw=%r, arg=%r)', menuw,
                   arg)
        menu_items = []
        menu_items += [
            menu.MenuItem(_('Start Encoding'), self.create_job, self.profile)
        ]
        menu_items += [
            menu.MenuItem(_('Select Encoding Profile'),
                          action=self.select_profile)
        ]
        menu_items += [
            menu.MenuItem(_('Modify Container'), action=self.mod_container)
        ]
        menu_items += [
            menu.MenuItem(_('Modify Start Time'), action=self.mod_start_time)
        ]
        menu_items += [
            menu.MenuItem(_('Modify End Time'), action=self.mod_end_time)
        ]
        menu_items += [
            menu.MenuItem(_('Modify Resolution'), action=self.mod_resolution)
        ]
        menu_items += [
            menu.MenuItem(_('Modify Video Codec'), action=self.mod_videocodec)
        ]
        menu_items += [
            menu.MenuItem(_('Modify Video Bit Rate'),
                          action=self.mod_videobitrate)
        ]
        menu_items += [
            menu.MenuItem(_('Modify Audio Codec'), action=self.mod_audiocodec)
        ]
        menu_items += [
            menu.MenuItem(_('Modify Audio Bit Rate'),
                          action=self.mod_audiobitrate)
        ]
        menu_items += [
            menu.MenuItem(_('Modify Number of passes'),
                          action=self.mod_numpasses)
        ]
        menu_items += [
            menu.MenuItem(_('Modify Number of Encoder Threads'),
                          action=self.mod_numthreads)
        ]
        menu_items += [
            menu.MenuItem(_('Modify Video Filter (not implemented)'),
                          action=self.mod_videofilter)
        ]
        encoding_menu = menu.Menu(_('Choose your encoding profile'),
                                  menu_items,
                                  item_types='video encoding menu')
        encoding_menu.infoitem = self
        menuw.pushmenu(encoding_menu)
        menuw.refresh()

    def select_profile(self, arg=None, menuw=None):
        logger.log(9, 'select_profile(self, arg=None, menuw=None)')
        menu_items = []
        menu_items += [
            menu.MenuItem(_('Xvid Low Quality'),
                          action=self.select_encoding_profile,
                          arg='xvid_low')
        ]
        menu_items += [
            menu.MenuItem(_('Xvid High Quality'),
                          action=self.select_encoding_profile,
                          arg='xvid_high')
        ]
        menu_items += [
            menu.MenuItem(_('iPod'),
                          action=self.select_encoding_profile,
                          arg='ipod')
        ]
        menu_items += [
            menu.MenuItem(_('DVD'),
                          action=self.select_encoding_profile,
                          arg='MPEG 2 (lavc)')
        ]
        encoding_menu = menu.Menu(_('Select Profile'),
                                  menu_items,
                                  item_types='video encoding menu')
        encoding_menu.infoitem = self
        menuw.pushmenu(encoding_menu)
        menuw.refresh()

    def set_start_time(self, arg=None, menuw=None):
        self.timeslice[0] = arg
        if menuw:
            menuw.back_one_menu(arg='reload')

    def set_end_time(self, arg=None, menuw=None):
        self.timeslice[1] = arg
        if menuw:
            menuw.back_one_menu(arg='reload')

    def _select_time(self, arg=None, menuw=None, which=None):
        bookmarkfile = util.get_bookmarkfile(self.item.filename)
        if not os.path.exists(bookmarkfile):
            self.error(_('No bookmarks are set for this video'))
            return
        menu_items = []
        menu_items = [
            menu.MenuItem(_('Do not set'), action=which, arg=None),
        ]
        for line in util.readfile(bookmarkfile):
            sec = int(line)
            hour = int(sec / 3600)
            min = int((sec - (hour * 3600)) / 60)
            time = '%0.2d:%0.2d:%0.2d' % (hour, min, sec % 60)
            menu_items.append(menu.MenuItem(time, action=which, arg=sec))
        encoding_menu = menu.Menu(_('Select Time'),
                                  menu_items,
                                  item_types='video encoding menu')
        encoding_menu.infoitem = self
        menuw.pushmenu(encoding_menu)
        menuw.refresh()

    def mod_start_time(self, arg=None, menuw=None):
        self._select_time(arg, menuw, self.set_start_time)

    def mod_end_time(self, arg=None, menuw=None):
        self._select_time(arg, menuw, self.set_end_time)

    def mod_container(self, arg=None, menuw=None):
        logger.log(9, 'mod_container(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for container in self.server.getContainerCAP()[1]:
            items.append(
                menu.MenuItem(container,
                              action=self.alter_prop,
                              arg=('container', container)))
        container_menu = menu.Menu(_('Modify Container'),
                                   items,
                                   item_types='video encoding menu')
        container_menu.infoitem = self
        menuw.pushmenu(container_menu)
        menuw.refresh()

    def mod_resolution(self, arg=None, menuw=None):
        logger.log(9, 'mod_resolution(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for resolution in ('Optimal', '1920:1080', '1280:720', '852:480',
                           '720:576', '720:480', '320:240'):
            items.append(
                menu.MenuItem(resolution,
                              action=self.alter_prop,
                              arg=('resolution', resolution)))
        resolution_menu = menu.Menu(_('Modify Resolution'),
                                    items,
                                    item_types='video encoding menu')
        resolution_menu.infoitem = self
        menuw.pushmenu(resolution_menu)
        menuw.refresh()

    def mod_videocodec(self, arg=None, menuw=None):
        logger.log(9, 'mod_videocodec(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for videocodec in self.server.getVideoCodecCAP()[1]:
            items.append(
                menu.MenuItem(videocodec,
                              action=self.alter_prop,
                              arg=('videocodec', videocodec)))
        videocodec_menu = menu.Menu(_('Modify Video Codec'),
                                    items,
                                    item_types='video encoding menu')
        videocodec_menu.infoitem = self
        menuw.pushmenu(videocodec_menu)
        menuw.refresh()

    def mod_videobitrate(self, arg=None, menuw=None):
        logger.log(9, 'mod_videobitrate(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for videobitrate in range(400, 2001, 200):
            items.append(
                menu.MenuItem(videobitrate,
                              action=self.alter_prop,
                              arg=('videobitrate', videobitrate)))
        videobitrate_menu = menu.Menu(_('Modify Video Bitrate'),
                                      items,
                                      item_types='video encoding menu')
        videobitrate_menu.infoitem = self
        menuw.pushmenu(videobitrate_menu)
        menuw.refresh()

    def mod_audiocodec(self, arg=None, menuw=None):
        logger.log(9, 'mod_audiocodec(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for audiocodec in self.server.getAudioCodecCAP()[1]:
            items.append(
                menu.MenuItem(audiocodec,
                              action=self.alter_prop,
                              arg=('audiocodec', audiocodec)))
        audiocodec_menu = menu.Menu(_('Modify Video Codec'),
                                    items,
                                    item_types='video encoding menu')
        audiocodec_menu.infoitem = self
        menuw.pushmenu(audiocodec_menu)
        menuw.refresh()

    def mod_audiobitrate(self, arg=None, menuw=None):
        logger.log(9, 'mod_audiobitrate(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for audiobitrate in (64, 128, 192, 224):
            items.append(
                menu.MenuItem(audiobitrate,
                              action=self.alter_prop,
                              arg=('audiobitrate', audiobitrate)))
        audiobitrate_menu = menu.Menu(_('Modify Audio Bitrate'),
                                      items,
                                      item_types='video encoding menu')
        audiobitrate_menu.infoitem = self
        menuw.pushmenu(audiobitrate_menu)
        menuw.refresh()

    def mod_numpasses(self, arg=None, menuw=None):
        logger.log(9, 'mod_numpasses(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for numpasses in (1, 2):
            items.append(
                menu.MenuItem(numpasses,
                              action=self.alter_prop,
                              arg=('numpasses', numpasses)))
        numpasses_menu = menu.Menu(_('Modify Number of Passes'),
                                   items,
                                   item_types='video encoding menu')
        numpasses_menu.infoitem = self
        menuw.pushmenu(numpasses_menu)
        menuw.refresh()

    def mod_numthreads(self, arg=None, menuw=None):
        logger.log(9, 'mod_numthreads(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for numthreads in (1, 2, 3, 4, 5, 6, 7, 8):
            items.append(
                menu.MenuItem(numthreads,
                              action=self.alter_prop,
                              arg=('numthreads', numthreads)))
        numthreads_menu = menu.Menu(_('Modify Number of Encoding threads'),
                                    items,
                                    item_types='video encoding menu')
        numthreads_menu.infoitem = self
        menuw.pushmenu(numthreads_menu)
        menuw.refresh()

    def mod_videofilter(self, arg=None, menuw=None):
        logger.log(9, 'mod_videofilter(self, arg=%r, menuw=%r)', arg, menuw)
        items = []
        for videofilter in self.server.getVideoFiltersCAP()[1]:
            items.append(
                menu.MenuItem(videofilter,
                              action=self.alter_prop,
                              arg=('videofilter', videofilter)))
        videofilter_menu = menu.Menu(_('Modify Video Filter'),
                                     items,
                                     item_types='video encoding menu')
        videofilter_menu.infoitem = self
        menuw.pushmenu(videofilter_menu)
        menuw.refresh()

    def select_encoding_profile(self, arg=None, menuw=None):
        logger.log(9, 'select_encoding_profile(self, arg=%r, menuw=%r)', arg,
                   menuw)

        if arg == 'xvid_low':
            self.profile['container'] = 'avi'
            self.profile['resolution'] = 'Optimal'
            self.profile['videocodec'] = 'XviD'
            self.profile['altprofile'] = None
            self.profile['videobitrate'] = 800
            self.profile['audiocodec'] = 'MPEG 1 Layer 3 (mp3)'
            self.profile['audiobitrate'] = 128
            self.profile['numpasses'] = 1
            self.profile['videofilter'] = 'None'
        elif arg == 'xvid_high':
            self.profile['container'] = 'avi'
            self.profile['resolution'] = 'Optimal'
            self.profile['videocodec'] = 'XviD'
            self.profile['altprofile'] = None
            self.profile['videobitrate'] = 1200
            self.profile['audiocodec'] = 'MPEG 1 Layer 3 (mp3)'
            self.profile['audiobitrate'] = 128
            self.profile['numpasses'] = 2
            self.profile['videofilter'] = 'None'
        elif arg == 'ipod':
            self.profile['container'] = 'mp4'
            self.profile['resolution'] = '320:240'
            self.profile['videocodec'] = 'MPEG 4 (lavc)'
            self.profile[
                'altprofile'] = 'vcodec=mpeg4:mbd=2:cmp=2:subcmp=2:trell=yes:v4mv=yes:vglobal=1'
            self.profile['videobitrate'] = 1200
            self.profile['audiocodec'] = 'AAC (iPod)'
            self.profile['audiobitrate'] = 192
            self.profile['numpasses'] = 2
            self.profile['videofilter'] = 'ipod'
        elif arg == 'MPEG 2 (lavc)':
            self.profile['container'] = 'mpeg'
            self.profile['resolution'] = '720:480'
            self.profile['videocodec'] = 'MPEG 2 (lavc)'
            self.profile['altprofile'] = None
            self.profile['videobitrate'] = 5200
            self.profile['audiocodec'] = 'AC3'
            self.profile['audiobitrate'] = 224
            self.profile['numpasses'] = 1
            self.profile['videofilter'] = 'None'
        else:
            logger.error('Unknown Profile "%s"', arg)
            self.error(_('Unknown Profile') + (' "%s"' % (arg)))
            return

        if menuw:
            menuw.back_one_menu(arg='reload')

    def alter_prop(self, arg=(None, None), menuw=None):
        logger.log(9, 'alter_prop(self, arg=%r, menuw=%r)', arg, menuw)
        (prop, val) = arg

        if prop == 'container':
            self.profile['container'] = val
        elif prop == 'resolution':
            self.profile['resolution'] = val
        elif prop == 'videocodec':
            self.profile['videocodec'] = val
        elif prop == 'altprofile':
            self.profile['altprofile'] = val
        elif prop == 'videobitrate':
            self.profile['videobitrate'] = val
        elif prop == 'audiocodec':
            self.profile['audiocodec'] = val
        elif prop == 'audiobitrate':
            self.profile['audiobitrate'] = val
        elif prop == 'numpasses':
            self.profile['numpasses'] = val
        elif prop == 'numthreads':
            self.profile['numthreads'] = val
        elif prop == 'videofilter':
            self.profile['videofilter'] = val
        else:
            logger.error('Unknown property "%s"', prop)
            self.error(_('Unknown Property') + (' "%s"' % (prop)))
            return

        if menuw:
            menuw.back_one_menu(arg='reload')

    def alter_name(self, name):
        '''alter_name is not used'''
        logger.log(9, 'alter_name(self, name=%r)', name)
        self.menuw.refresh()

    def create_job(self, menuw=None, arg=None):
        logger.log(9, 'create_job(self, arg=%r, menuw=%r)', arg, menuw)

        profile = arg

        # note that this may later be changed by the uniquify_filename()
        self.output = self.prepare_output(self.source)

        if self.output[:2] == './' and self.warn_once_savedir:
            #it will go into the encodingserver temporary dir, and we cant tell it from
            # this process
            self.warn_once_savedir = False

            AlertBox(text=_(
                'This encoding job will be written to a temporary '
                'directory. Please set the variable ENCODINGSERVER_SAVEDIR to a '
                'directory where the reencoded file can be written to.')).show(
                )
            return

        #we are going to create a job and send it to the encoding server, this can take some time while analyzing

        box = PopupBox(text=_('Please wait, analyzing video...'))
        box.show()
        (status, resp) = self.server.initEncodingJob(self.source, self.output,
                                                     self.title)
        idnr = resp
        logger.debug('initEncodingJob:status:%s resp:%s', status, resp)
        if not status:
            box.destroy()
            self.error(_('Failed to analyze video.'))
            return

        (status, resp) = self.server.setTimeslice(idnr, self.timeslice)
        logger.debug('setTimeslice:status:%s resp:%s', status, resp)
        if not status:
            box.destroy()
            self.error(resp)
            return

        (status, resp) = self.server.waitCropDetect(idnr)
        logger.debug('WaitCropDetect:status:%s resp:%s', status, resp)
        if not status:
            box.destroy()
            self.error(resp)
            return

        box.destroy()
        if not status:
            self.error(resp)
            return

        (status, resp) = self.server.setContainer(idnr, profile['container'])
        logger.debug('setContainer:status:%s resp:%s', status, resp)
        if not status:
            self.error(resp)
            return

        multipass = profile['numpasses'] > 1
        (status, resp) = self.server.setVideoCodec(idnr, profile['videocodec'],
                                                   0, multipass,
                                                   profile['videobitrate'],
                                                   profile['altprofile'])
        logger.debug('setVideoCodec:status:%s resp:%s', status, resp)
        if not status:
            self.error(resp)
            return

        (status, resp) = self.server.setAudioCodec(idnr, profile['audiocodec'],
                                                   profile['audiobitrate'])
        logger.debug('setAudioCodec:status:%s resp:%s', status, resp)
        if not status:
            self.error(resp)
            return

        (status, resp) = self.server.setNumThreads(idnr, profile['numthreads'])
        logger.debug('setNumThreads:status:%s resp:%s', status, resp)
        if not status:
            self.error(resp)
            return

        (status, resp) = self.server.setVideoRes(idnr, profile['resolution'])
        logger.debug('setVideoRes:status:%s resp:%s', status, resp)
        if not status:
            self.error(resp)
            return

        #(status, resp) = self.server.setVideoFilters(idnr, vfilters)
        #_debug_('setVideoFilters:status:%s resp:%s' % (status, resp))

        #And finally, queue and start the job
        (status, resp) = self.server.queueIt(idnr, True)
        logger.debug('queueIt:status:%s resp:%s', status, resp)

        if not status:
            self.error(resp)
            return

        self.menuw = menuw
        AlertBox(width=400,
                 height=200,
                 text=_('Encoding started'),
                 handler=self.mopup).show()

        self.resetprofile()
        logger.debug('boe')
        #menuw.delete_menu()
        #menuw.delete_menu()

    def error(self, text=''):
        logger.debug('error(self, text=%r)', text)
        AlertBox(width=400, height=200, text='ERROR: %s' % text).show()

    def mopup(self):
        logger.debug('mopup(self)')
        self.menuw.delete_menu()
        self.menuw.back_one_menu()
Beispiel #3
0
class PluginInterface(plugin.ItemPlugin):
    """
    Plug-in to archive recorded TV programmes using EncodingServer

    This plugin NEEDS a running encodingserver to work properly.
    You can start an encodingserver with "freevo encodingserver start".
    """
    def __init__(self):
        logger.debug('reencode-old.PluginInterface.__init__(self)')
        plugin.ItemPlugin.__init__(self)
        self.server = EncodingClientActions()

    def actions(self, item):
        logger.debug('actions(self, item)')

        if item.type == 'video' and item.mode == 'file':
            # TODO: use a config variable
            (filename, extn) = os.path.splitext(item.filename)
            if extn in ['.mpeg', '.mpg']:
                #for dvd on disc
                self.dvdsource = item.filename

                self.title = item.name
                self.source = item.filename
                self.filename = filename + '.avi'

                self.item = item
                return [(self.encoding_profile_menu,
                         _('Re-encode this program...'))]
        return []

    def encoding_profile_menu(self, menuw=None, arg=None):
        logger.debug('encoding_profile_menu(self, menuw=None, arg=None)')
        #create a menu with a few encoding options (1cd, 2cd, xvid, mpeg4)
        #args : tuple, (videocodec, size, multipass
        menu_items = [
            menu.MenuItem("XviD, 800bps", self.create_job,
                          (0, 0, 1, None, 700, False, 800))
        ]
        menu_items.append(
            menu.MenuItem("XviD, 800bps, High Quality", self.create_job,
                          (0, 0, 1, None, 700, True, 800)))
        menu_items.append(
            menu.MenuItem("XviD, 1200bps", self.create_job,
                          (0, 0, 1, None, 1400, False, 1200)))
        menu_items.append(
            menu.MenuItem("XviD, 1200bps, High Quality", self.create_job,
                          (0, 0, 1, None, 1400, True, 1200)))
        menu_items.append(
            menu.MenuItem("DivX, 800bps", self.create_job,
                          (0, 0, 0, None, 700, False, 800)))
        menu_items.append(
            menu.MenuItem("DivX, 800bps, High Quality", self.create_job,
                          (0, 0, 0, None, 700, True, 800)))
        menu_items.append(
            menu.MenuItem("DivX, 1200bps", self.create_job,
                          (0, 0, 0, None, 1400, False, 1200)))
        menu_items.append(
            menu.MenuItem("DivX, 1200bps, High Quality", self.create_job,
                          (0, 0, 0, None, 1400, True, 1200)))
        menu_items.append(
            menu.MenuItem("iPod", self.create_job,
                          (2, 2, 2, None, None, False, 1200)))
        encoding_menu = menu.Menu(_('Choose your encoding profile'),
                                  menu_items)
        menuw.pushmenu(encoding_menu)

    def create_job(self, menuw=None, arg=None):
        logger.debug('create_job(self, menuw=None, arg=None)')
        print 'arg:', arg
        #unwrap settings tupple
        (contnr, audionr, vcodecnr, vfilter, tgtsize, mpass, vbitrate) = arg

        #we are going to create a job and send it to the encoding server, this can take some time while analyzing

        box = PopupBox(text=_('Please wait, analyzing video...'))
        box.show()

        (status, resp) = self.server.initEncodingJob(self.source,
                                                     self.filename, self.title)
        print 'initEncodingJob:status:', status, ' resp:', resp

        box.destroy()

        if not status:
            self.error(resp)
            return

        idnr = resp

        #ask for possible containers and set the first one (should be avi), we will get a list
        (status, resp) = self.server.getContainerCAP(idnr)
        print 'getContainerCAP:status:', status, ' resp:', resp

        if not status:
            self.error(resp)
            return

        container = resp[contnr]

        (status, resp) = self.server.setContainer(idnr, container)
        print 'setContainer:status:', status, ' resp:', resp

        if not status:
            self.error(resp)
            return

        #ask for possible videocodec and set the first one (should be mpeg4), we will get a list
        (status, resp) = self.server.getVideoCodecCAP(idnr)
        print 'getVideoCodecCAP:status:', status, ' resp:', resp

        if not status:
            self.error(resp)
            return

        vcodec = resp[vcodecnr]

        (status, resp) = self.server.setVideoCodec(idnr, vcodec, tgtsize,
                                                   mpass, vbitrate)
        print 'setVideoCodec:status:', status, ' resp:', resp

        if not status:
            self.error(resp)
            return

        #ask for possible audiocodec and set the first one (should be mp3), we will get a list
        #Audiocodec call isn't necessary atm, it defaults to 128 kbit mp3, but this might change in the future
        #so we play safe
        (status, resp) = self.server.getAudioCodecCAP(idnr)
        print 'getAudioCodecCAP:status:', status, ' resp:', resp

        if not status:
            self.error(resp)
            return

        acodec = resp[audionr]

        (status, resp) = self.server.setAudioCodec(idnr, acodec, 128)
        print 'setAudioCodec:status:', status, ' resp:', resp

        if not status:
            self.error(resp)
            return

        (status, resp) = self.server.getVideoFiltersCAP(idnr)
        print 'getVideoFiltersCAP:status:', status, ' resp:', resp

        if not status:
            self.error(resp)
            return

        #vfilters=resp[vfilter]
        #(status, resp) = self.server.setVideoFilters(idnr, vfilters)
        #print 'setVideoFilter:status:', status, ' resp:', resp

        #And finally, qeue and start the job
        (status, resp) = self.server.queueIt(idnr, True)
        print 'queueIt:status:', status, ' resp:', resp

        if not status:
            self.error(resp)
            return

        self.menuw = menuw
        AlertBox(width=400,
                 height=200,
                 text=_("Encoding started"),
                 handler=self.mopup).show()

        print "boe"
        #menuw.delete_menu()
        #menuw.delete_menu()

    def error(self, text=""):
        logger.debug('error(self, text="")')
        AlertBox(width=400, height=200, text="ERROR: %s" % text).show()

    def mopup(self):
        logger.debug('mopup(self)')
        self.menuw.delete_menu()
        self.menuw.back_one_menu()
Beispiel #4
0
class PluginInterface(plugin.ItemPlugin):
    """
    Plug-in to archive recorded TV programmes using EncodingServer

    This plugin NEEDS a running encodingserver to work properly.
    You can start an encodingserver with "freevo encodingserver start".
    """

    def __init__(self):
        logger.debug('reencode-old.PluginInterface.__init__(self)')
        plugin.ItemPlugin.__init__(self)
        self.server = EncodingClientActions()


    def actions(self, item):
        logger.debug('actions(self, item)')

        if item.type == 'video' and item.mode == 'file':
            # TODO: use a config variable
            (filename, extn) = os.path.splitext(item.filename)
            if extn in ['.mpeg','.mpg']:
                #for dvd on disc
                self.dvdsource = item.filename

                self.title = item.name
                self.source = item.filename
                self.filename = filename+'.avi'

                self.item = item
                return [ (self.encoding_profile_menu, _('Re-encode this program...')) ]
        return []

    def encoding_profile_menu(self, menuw=None, arg=None):
        logger.debug('encoding_profile_menu(self, menuw=None, arg=None)')
        #create a menu with a few encoding options (1cd, 2cd, xvid, mpeg4)
        #args : tuple, (videocodec, size, multipass
        menu_items = [ menu.MenuItem("XviD, 800bps", self.create_job, (0,0,1,None,700,False,800)) ]
        menu_items.append( menu.MenuItem("XviD, 800bps, High Quality", self.create_job, (0,0,1,None,700,True,800)) )
        menu_items.append( menu.MenuItem("XviD, 1200bps", self.create_job, (0,0,1,None,1400,False,1200)) )
        menu_items.append( menu.MenuItem("XviD, 1200bps, High Quality", self.create_job, (0,0,1,None,1400,True,1200)) )
        menu_items.append( menu.MenuItem("DivX, 800bps", self.create_job, (0,0,0,None,700,False,800)) )
        menu_items.append( menu.MenuItem("DivX, 800bps, High Quality", self.create_job, (0,0,0,None,700,True,800)) )
        menu_items.append( menu.MenuItem("DivX, 1200bps", self.create_job, (0,0,0,None,1400,False,1200)) )
        menu_items.append( menu.MenuItem("DivX, 1200bps, High Quality", self.create_job, (0,0,0,None,1400,True,1200)) )
        menu_items.append( menu.MenuItem("iPod", self.create_job,(2,2,2,None,None,False,1200)) )
        encoding_menu = menu.Menu(_('Choose your encoding profile'), menu_items)
        menuw.pushmenu(encoding_menu)

    def create_job(self, menuw=None, arg=None):
        logger.debug('create_job(self, menuw=None, arg=None)')
        print 'arg:', arg
        #unwrap settings tupple
        (contnr, audionr, vcodecnr, vfilter, tgtsize, mpass, vbitrate) = arg

        #we are going to create a job and send it to the encoding server, this can take some time while analyzing

        box = PopupBox(text=_('Please wait, analyzing video...'))
        box.show()

        (status, resp) = self.server.initEncodingJob(self.source, self.filename, self.title)
        print 'initEncodingJob:status:', status, ' resp:', resp

        box.destroy()

        if not status:
            self.error(resp)
            return

        idnr = resp

        #ask for possible containers and set the first one (should be avi), we will get a list
        (status, resp) = self.server.getContainerCAP(idnr)
        print 'getContainerCAP:status:', status, ' resp:', resp

        if not status:
            self.error(resp)
            return

        container = resp[contnr]

        (status, resp) = self.server.setContainer(idnr, container)
        print 'setContainer:status:', status, ' resp:', resp

        if not status:
            self.error(resp)
            return

        #ask for possible videocodec and set the first one (should be mpeg4), we will get a list
        (status, resp) = self.server.getVideoCodecCAP(idnr)
        print 'getVideoCodecCAP:status:', status, ' resp:', resp

        if not status:
            self.error(resp)
            return

        vcodec = resp[vcodecnr]

        (status, resp) = self.server.setVideoCodec(idnr, vcodec, tgtsize, mpass, vbitrate)
        print 'setVideoCodec:status:', status, ' resp:', resp

        if not status:
            self.error(resp)
            return

        #ask for possible audiocodec and set the first one (should be mp3), we will get a list
        #Audiocodec call isn't necessary atm, it defaults to 128 kbit mp3, but this might change in the future
        #so we play safe
        (status, resp) = self.server.getAudioCodecCAP(idnr)
        print 'getAudioCodecCAP:status:', status, ' resp:', resp

        if not status:
            self.error(resp)
            return

        acodec = resp[audionr]

        (status, resp) = self.server.setAudioCodec(idnr, acodec, 128)
        print 'setAudioCodec:status:', status, ' resp:', resp

        if not status:
            self.error(resp)
            return

        (status, resp) = self.server.getVideoFiltersCAP(idnr)
        print 'getVideoFiltersCAP:status:', status, ' resp:', resp

        if not status:
            self.error(resp)
            return

        #vfilters=resp[vfilter]
        #(status, resp) = self.server.setVideoFilters(idnr, vfilters)
        #print 'setVideoFilter:status:', status, ' resp:', resp

        #And finally, qeue and start the job
        (status, resp) = self.server.queueIt(idnr, True)
        print 'queueIt:status:', status, ' resp:', resp

        if not status:
            self.error(resp)
            return

        self.menuw = menuw
        AlertBox(width=400, height=200, text=_("Encoding started"), handler=self.mopup).show()

        print "boe"
        #menuw.delete_menu()
        #menuw.delete_menu()


    def error(self, text=""):
        logger.debug('error(self, text="")')
        AlertBox(width=400, height=200, text="ERROR: %s" % text).show()


    def mopup(self):
        logger.debug('mopup(self)')
        self.menuw.delete_menu()
        self.menuw.back_one_menu()