コード例 #1
0
class PluginInterface(plugin.ItemPlugin):
    """
    Make DVD backups (aka dvdrips) using EncodingServer

    This plugin NEEDS a running encodingserver to work properly.
    You can start an encodingserver with "freevo encodingserver start".
    Don't forget that you need some free diskspace in order to use this plugin,
    and don't forget a dvdrip eats quite a bit of space :)
    """
    def __init__(self):
        plugin.ItemPlugin.__init__(self)
        self.server = EncodingClientActions()

    def config(self):
        return [
            ('DVD_BACKUP_MENU', None,
             'A customized menu of encoding parameters'),
        ]

    def actions(self, item):
        if config.DEBUG >= 2:
            #testing stuff
            if hasattr(item, 'type'):
                logger.debug('item.type=\"%s\"', item.type)
            if hasattr(item, 'mode'):
                logger.debug('item.mode=\"%s\"', item.mode)
            if hasattr(item, 'info_type'):
                logger.debug('item.info_type=\"%s\"', item.info_type)
            if hasattr(item, 'name'):
                logger.debug('item.name=\"%s\"', item.name)
            if hasattr(item, 'filename'):
                logger.debug('item.filename=\"%s\"', item.filename)
            if hasattr(item, 'parentname'):
                logger.debug('item.parentname=\"%s\"', item.parentname)
            if hasattr(item, 'media') and hasattr(item.media, 'devicename'):
                logger.debug('item.media.devicename=\"%s\"',
                             item.media.devicename)

        if item.type == 'video' and item.mode == 'dvd' and hasattr(
                item, 'info_type'):
            if item.info_type == "track":  #and item.media and item.media.devicename:
                #for dvd on disc
                self.dvdsource = item.filename
                self.title = int(split(item.url)[-1])

                if hasattr(item, 'media') and hasattr(item.media,
                                                      'devicename'):
                    #we have a "real" dvd disc
                    self.dvdsource = item.media.devicename
                    self.title = int(item.url[6:])

                self.item = item
                return [(self.encoding_profile_menu,
                         _('Backup this dvd title...'))]
        return []

    def encoding_profile_menu(self, menuw=None, arg=None):
        if config.DVD_BACKUP_MENU:
            menu_items = []
            for menu_item in config.DVD_BACKUP_MENU:
                menu_items.append(
                    menu.MenuItem(menu_item[0], self.create_job, menu_item[1]))
        else:
            #create a menu with a few encoding options (1cd, 2cd, xvid, mpeg4)
            #args : tuple, (videocodec, size, multipass, bitrate, audiocodec, container)
            menu_items = [
                menu.MenuItem("XviD, 700mb", self.create_job,
                              (2, 700, False, 0, 0, 0))
            ]
            menu_items.append(
                menu.MenuItem("XviD, 700mb, High Quality", self.create_job,
                              (2, 700, True, 0, 0, 0)))
            menu_items.append(
                menu.MenuItem("XviD, 1400mb", self.create_job,
                              (2, 1400, False, 0, 0, 0, 0, 0)))
            menu_items.append(
                menu.MenuItem("XviD, 1400mb, High Quality", self.create_job,
                              (2, 1400, True, 0, 0, 0)))
            menu_items.append(
                menu.MenuItem("MPEG4, 700mb", self.create_job,
                              (0, 700, False, 0, 0, 0)))
            menu_items.append(
                menu.MenuItem("MPEG4, 700mb, High Quality", self.create_job,
                              (0, 700, True, 0, 0, 0)))
            menu_items.append(
                menu.MenuItem("MPEG4, 1400mb", self.create_job,
                              (0, 1400, False, 0, 0, 0)))
            menu_items.append(
                menu.MenuItem("MPEG4, 1400mb, High Quality", self.create_job,
                              (0, 1400, True, 0, 0, 0)))
            menu_items.append(
                menu.MenuItem("h.264, 700mb", self.create_job,
                              (3, 700, False, 0, 0, 0)))
            menu_items.append(
                menu.MenuItem("h.264, 700mb, High Quality", self.create_job,
                              (3, 700, True, 0, 0, 0)))
            menu_items.append(
                menu.MenuItem("h.264, 1400mb", self.create_job,
                              (3, 1400, False, 0, 0, 0)))
            menu_items.append(
                menu.MenuItem("h.264, 1400mb, High Quality", self.create_job,
                              (3, 1400, True, 0, 0, 0)))

        encoding_menu = menu.Menu(_('Choose your encoding profile'),
                                  menu_items)
        menuw.pushmenu(encoding_menu)

    def create_job(self, menuw=None, arg=None):
        """
        """
        #create a filename for the to-be-encoded dvd title
        #title = int(self.item.url[6:])
        fname = join(config.VIDEO_ITEMS[0][1],
                     "%s_%s" % (self.item.parent.name, self.title))
        #_debug_('title=%s, fname=%s' % (title, fname))
        logger.debug('arg=%r', arg)
        #unwrap settings tupple
        vcodecnr, tgtsize, mpass, vbitrate, acodecnr, contnr = 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()
        try:
            (status,
             resp) = self.server.initEncodingJob(self.dvdsource, fname,
                                                 self.item.parent.name,
                                                 self.title)
            if not status:
                self.error(resp)
                return
        finally:
            box.destroy()

        idnr = resp

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

        container = resp[contnr]

        (status, resp) = self.server.setContainer(idnr, container)
        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()
        if not status:
            self.error(resp)
            return

        vcodec = resp[vcodecnr]

        (status, resp) = self.server.setVideoCodec(idnr, vcodec, tgtsize,
                                                   mpass, vbitrate)
        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()

        if not status:
            self.error(resp)
            return

        acodec = resp[acodecnr]

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

        if not status:
            self.error(resp)
            return

        #And finally, qeue and start the job
        (status, resp) = self.server.queueIt(idnr, True)
        if not status:
            self.error(resp)
            return

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

        logger.debug("boe")
        #menuw.delete_menu()
        #menuw.delete_menu()

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

    def mopup(self):
        self.menuw.delete_menu()
        self.menuw.back_one_menu()
コード例 #2
0
ファイル: dvdbackup.py プロジェクト: adozenlines/freevo1
class PluginInterface(plugin.ItemPlugin):
    """
    Make DVD backups (aka dvdrips) using EncodingServer

    This plugin NEEDS a running encodingserver to work properly.
    You can start an encodingserver with "freevo encodingserver start".
    Don't forget that you need some free diskspace in order to use this plugin,
    and don't forget a dvdrip eats quite a bit of space :)
    """
    def __init__(self):
        plugin.ItemPlugin.__init__(self)
        self.server = EncodingClientActions()


    def config(self):
        return [
            ('DVD_BACKUP_MENU', None, 'A customized menu of encoding parameters'),
        ]


    def actions(self, item):
        if config.DEBUG >= 2:
            #testing stuff
            if hasattr(item, 'type'):
                logger.debug('item.type=\"%s\"', item.type)
            if hasattr(item, 'mode'):
                logger.debug('item.mode=\"%s\"', item.mode)
            if hasattr(item, 'info_type'):
                logger.debug('item.info_type=\"%s\"', item.info_type)
            if hasattr(item, 'name'):
                logger.debug('item.name=\"%s\"', item.name)
            if hasattr(item, 'filename'):
                logger.debug('item.filename=\"%s\"', item.filename)
            if hasattr(item, 'parentname'):
                logger.debug('item.parentname=\"%s\"', item.parentname)
            if hasattr(item, 'media') and hasattr(item.media, 'devicename'):
                logger.debug('item.media.devicename=\"%s\"', item.media.devicename)

        if item.type == 'video' and item.mode == 'dvd' and hasattr(item, 'info_type'):
            if item.info_type == "track": #and item.media and item.media.devicename:
                #for dvd on disc
                self.dvdsource = item.filename
                self.title = int(split(item.url)[-1])

                if hasattr(item, 'media') and hasattr(item.media, 'devicename'):
                    #we have a "real" dvd disc
                    self.dvdsource = item.media.devicename
                    self.title = int(item.url[6:])

                self.item = item
                return [ (self.encoding_profile_menu, _('Backup this dvd title...')) ]
        return []


    def encoding_profile_menu(self, menuw=None, arg=None):
        if config.DVD_BACKUP_MENU:
            menu_items = []
            for menu_item in config.DVD_BACKUP_MENU:
                menu_items.append(menu.MenuItem(menu_item[0], self.create_job, menu_item[1]))
        else:
            #create a menu with a few encoding options (1cd, 2cd, xvid, mpeg4)
            #args : tuple, (videocodec, size, multipass, bitrate, audiocodec, container)
            menu_items = [ menu.MenuItem("XviD, 700mb", self.create_job, (2, 700, False, 0, 0, 0)) ]
            menu_items.append( menu.MenuItem("XviD, 700mb, High Quality", self.create_job, (2, 700, True, 0, 0, 0)) )
            menu_items.append( menu.MenuItem("XviD, 1400mb", self.create_job, (2, 1400, False, 0, 0, 0, 0, 0)) )
            menu_items.append( menu.MenuItem("XviD, 1400mb, High Quality", self.create_job, (2, 1400, True, 0, 0, 0)) )
            menu_items.append( menu.MenuItem("MPEG4, 700mb", self.create_job, (0, 700, False, 0, 0, 0)) )
            menu_items.append( menu.MenuItem("MPEG4, 700mb, High Quality", self.create_job, (0, 700, True, 0, 0, 0)) )
            menu_items.append( menu.MenuItem("MPEG4, 1400mb", self.create_job, (0, 1400, False, 0, 0, 0)) )
            menu_items.append( menu.MenuItem("MPEG4, 1400mb, High Quality", self.create_job, (0, 1400, True, 0, 0, 0)) )
            menu_items.append( menu.MenuItem("h.264, 700mb", self.create_job, (3, 700, False, 0, 0, 0)) )
            menu_items.append( menu.MenuItem("h.264, 700mb, High Quality", self.create_job, (3, 700, True, 0, 0, 0)) )
            menu_items.append( menu.MenuItem("h.264, 1400mb", self.create_job, (3, 1400, False, 0, 0, 0)) )
            menu_items.append( menu.MenuItem("h.264, 1400mb, High Quality", self.create_job, (3, 1400, True, 0, 0, 0)) )

        encoding_menu = menu.Menu(_('Choose your encoding profile'), menu_items)
        menuw.pushmenu(encoding_menu)


    def create_job(self, menuw=None, arg=None):
        """
        """
        #create a filename for the to-be-encoded dvd title
        #title = int(self.item.url[6:])
        fname = join(config.VIDEO_ITEMS[0][1], "%s_%s" % (self.item.parent.name, self.title))
        #_debug_('title=%s, fname=%s' % (title, fname))
        logger.debug('arg=%r', arg)
        #unwrap settings tupple
        vcodecnr, tgtsize, mpass, vbitrate, acodecnr, contnr = 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()
        try:
            (status, resp) = self.server.initEncodingJob(self.dvdsource, fname, self.item.parent.name, self.title)
            if not status:
                self.error(resp)
                return
        finally:
            box.destroy()

        idnr = resp

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

        container = resp[contnr]

        (status, resp) = self.server.setContainer(idnr, container)
        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()
        if not status:
            self.error(resp)
            return

        vcodec = resp[vcodecnr]

        (status, resp) = self.server.setVideoCodec(idnr, vcodec, tgtsize, mpass, vbitrate)
        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()

        if not status:
            self.error(resp)
            return

        acodec = resp[acodecnr]

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

        if not status:
            self.error(resp)
            return

        #And finally, qeue and start the job
        (status, resp) = self.server.queueIt(idnr, True)
        if not status:
            self.error(resp)
            return

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

        logger.debug("boe")
        #menuw.delete_menu()
        #menuw.delete_menu()


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


    def mopup(self):
        self.menuw.delete_menu()
        self.menuw.back_one_menu()
コード例 #3
0
ファイル: reencode.py プロジェクト: adozenlines/freevo1
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()
コード例 #4
0
ファイル: reencode-old.py プロジェクト: spartrekus/freevo1
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()
コード例 #5
0
ファイル: reencode.py プロジェクト: spartrekus/freevo1
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()
コード例 #6
0
ファイル: reencode-old.py プロジェクト: adozenlines/freevo1
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()