Show
Ignore:
Timestamp:
07/03/09 10:03:30 (13 months ago)
Author:
andy
Message:

transcoder queue runs properly now

removed HTML generation - out of place here

added properties on transcoder queue for high/low quality versions of FLV, OGV conversion

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • plumimediaqueue/trunk/src/plumimediaqueue/queues/transcoding.py

    r656 r922  
    44 
    55from plumimediaqueue.models import Queue, NetworkMediaItem 
    6  
    7 import logging 
    8 import os 
     6from plumimediaqueue.events.interfaces import IJobResetEvent 
     7 
     8import logging , os , traceback , time, subprocess 
    99 
    1010class ITranscodingQueue(IQueue): 
     
    1414                    ) 
    1515 
     16    mencoder_installed_location = Text( 
     17                            title = u"MEncoder",  
     18                            description=u"The file path to a MEncoder executable" 
     19                            ) 
     20 
     21    ffmpeg2theora_installed_location = Text( 
     22                            title = u"ffmpeg2theora",  
     23                            description=u"The file path to a ffmpeg2theora executable" 
     24                        )  
     25 
     26    flvtool_installed_location = Text( 
     27                            title = u"flvtool2",  
     28                            description=u"The file path to a flvtool2 executable" 
     29                        )  
     30 
    1631    mencoder_flv_options = Text( 
    1732                            title = u"MEncoder command line to produce FLV files.",  
    1833                            description=u"The set of options to pass to MEncoder when transcoding" 
    1934                            ) 
     35 
     36    ffmpeg2theora_options = Text( 
     37                            title = u"ffmpeg2theora command line to produce OGV files.",  
     38                            description=u"The set of options to pass to ffmpeg2theora when transcoding" 
     39                            ) 
     40 
     41 
     42    mencoder_flv_highquality_options = Text( 
     43                            title = u"MEncoder command line to produce high quality FLV files.",  
     44                            description=u"The set of options to pass to MEncoder when transcoding" 
     45                            ) 
     46 
     47    ffmpeg2theora_highquality_options = Text( 
     48                            title = u"ffmpeg2theora command line to produce high-quality OGV files.",  
     49                            description=u"The set of options to pass to ffmpeg2theora when transcoding" 
     50                            ) 
     51 
     52    nice_level = Text( 
     53                            title = u"Unix nice level", 
     54                            description=u"The level to 'renice' the transcoding processes" 
     55                            ) 
     56 
     57 
    2058 
    2159    file_extensions =  List( 
     
    2563                            ) 
    2664 
    27     flowplayer_URL_SWF = URI ( 
    28                             title=u'URL of Flowplayer SWF', 
    29                             description=u'Network address of FlowPlayer movie to serve.' 
    30                             ) 
    31  
    32     videohost_URL = URI ( 
    33                             title=u'URL of transcoded media server.', 
    34                             description=u'Network domain name for transcoded media server.' 
    35                             ) 
    36  
    37  
    3865class TranscodingQueue(Queue): 
    3966    grok.implements(ITranscodingQueue) 
    4067 
    4168    #set a sensible default for downloading 
    42     transcoding_dir=os.path.join(os.getcwd(),'download_queue_files')  
     69    transcoding_dir=os.path.join(os.getcwd(),'transcoding_queue_files')  
     70 
     71    mencoder_installed_location = '/usr/local/bin/mencoder' 
     72    ffmpeg2theora_installed_location = '/usr/bin/ffmpeg2theora' 
     73    flvtool_installed_location = '/usr/bin/flvtool2' 
    4374 
    4475    mencoder_flv_options='-really-quiet -of lavf -oac mp3lame -lameopts abr:br=56 -ovc lavc -lavcopts vcodec=flv:keyint=50:vbitrate=150:mbd=2:mv0:trell:v4mv:cbp:last_pred=3 -vf scale=320:240 -srate 22050' 
    4576 
     77    mencoder_flv_highquality_options='-really-quiet -of lavf -oac mp3lame -lameopts abr:br=56 -ovc lavc -lavcopts vcodec=flv:keyint=50:vbitrate=250:mbd=2:mv0:trell:v4mv:cbp:last_pred=3 -vf scale=720:480 -srate 22050' 
     78 
    4679    file_extensions=['.avi','.qt','.mov','.mpeg','.mp4','.mpg','.asf','.wmv','.3gp','.m4v','.ogm','.ogg','.divx','flv'] 
    4780 
    48     flowplayer_URL_SWF = 'http://flv.plumi.org/flowplayer/FlowPlayer.swf' 
    49  
    50     videohost_URL = '' 
     81    ffmpeg2theora_options = '-p preview' 
     82 
     83    ffmpeg2theora_highquality_options = '-p pro' 
     84     
     85    nice_level = '10' 
    5186 
    5287    def __init__(self,id=None): 
     
    6398 
    6499@grok.subscribe(NetworkMediaItem, grok.IObjectAddedEvent) 
     100@grok.subscribe(NetworkMediaItem, IJobResetEvent) 
    65101def handle(obj, event): 
    66102    #check if the JobItem is STARTING 
     
    78114 
    79115def attempt_transcode_file(transcoding_queue, networkmediaitem): 
    80         """Start the transcoding attempt with file 'f'. Converts to FLV format, and OGG/Theora. Produces HTML snippets for including the players appropriate for the produced video format. At the moment, this is FlowPlayer/JW Player for FLV, and Cortado java applet for OGG/Theora""" 
     116        """Start the transcoding attempt with file 'f'. Converts to FLV format, and OGG/Theora. XXX other mobile formats """ 
    81117        #whether or not the transcoding worked for the given file 'f' 
    82118        worked = False 
     119 
     120        #from this queue, we can get our sibling queue 'download' 
     121        #XXX abstract the names in app.py , and give them constants 
     122        dld_dir=transcoding_queue.__parent__['download'].download_dir 
    83123 
    84124        #get filepath, and then split into stem and extension, and return false straight away if not in recognised set. 
     
    89129 
    90130        #setup filenames we will need. 
    91         videofile = f 
    92         lockfile = f+".trans_lock"  # we are encoding already 
    93         skipfile = f+".trans_skip"  # we tried and failed, don't bother again 
    94         flvfile  = transcoding_queue.transcoding_dir + stem +  ".flv" # output FLV file 
    95         theorafile = transcoding_queue.transcoding_dir + ".ogg" # output OGG file 
    96         includefile  = self.INCLUDE_FILE_DIRECTORY+stem+self.INCLUDE_FILE_SUFFIX 
    97         logging.info("using %s, %s, %s %s %s " % (lockfile, skipfile, flvfile, theorafile, includefile)) 
     131        original_videofile = f 
     132        video_file = f.replace(dld_dir,transcoding_queue.transcoding_dir) 
     133        lockfile = video_file+".trans_lock"  # we are encoding already 
     134        skipfile = video_file+".trans_skip"  # we tried and failed, don't bother again 
     135        flvfile  = video_file +  ".flv" # output FLV file 
     136        theorafile = video_file + ".ogv" # output OGG file 
     137        logging.info("using %s, %s, %s, %s %s " % (video_file, lockfile, skipfile, flvfile, theorafile)) 
    98138 
    99139        #check that another encoder isnt already processing this file (lockfile) or that we havent tried and failed before (skipfile) 
    100         if os.path.exists(skipfile) or os.path(lockfile): 
     140        if os.path.exists(skipfile) or os.path.exists(lockfile): 
    101141            #dont do it 
    102142            return False 
    103143 
    104144        #OK, valid video file ready to try to transcode 
    105         logging.info("Checking file %s, using extension %s " % (videofile, extension)) 
     145        logging.info("Using original file %s, using extension %s " % (original_videofile, extension)) 
    106146        try: 
     147            #lets make sure all the directories are created 
     148            try: 
     149                os.makedirs(os.path.dirname(lockfile)) 
     150            except: 
     151                #the dirs may already exist 
     152                pass 
     153 
    107154            # touch the lock file 
    108155            #we should catch the exception here, and return FALSE! 
     
    112159                logging.info("lock file creation failed! ABORTING. %s " % lockfile) 
    113160                return False 
    114             #lets make sure all the directories are created 
    115             try: 
    116                 os.makedirs(os.path.dirname(flvfile)) 
    117             except: 
    118                 #the dirs may already exist 
    119                 pass 
    120161             
    121             logging.info('OK to try encoding: '+videofile) 
     162            logging.info('OK to try encoding: '+original_videofile) 
    122163            #mencoder flv conversion 
    123164            start_time=time.time() 
    124             encoder_command = self.MENCODER_LOCATION + " -quiet " + videofile + " -o " + flvfile + " " + self.MENCODER_OPTIONS 
    125             encoder_command_string = 'nice -n '+self.BE_HOW_NICE+' '+encoder_command 
     165            encoder_command = transcoding_queue.mencoder_installed_location + " -quiet " + original_videofile + " -o " + flvfile + " " + transcoding_queue.mencoder_flv_options 
     166            encoder_command_string = 'nice -n '+ transcoding_queue.nice_level +' '+encoder_command 
    126167            output,error = subprocess.Popen([encoder_command_string],shell=True,stdout=subprocess.PIPE,cwd=os.getcwd()).communicate() 
    127168            logging.debug("FLV transcoder output: %s ; error: %s" %(output,error)) 
    128             flvtool_command = self.FLVTOOL_LOCATION+" -U stdin "+flvfile 
    129             flvtool_command_string = "cat "+ flvfile +" | "+ 'nice -n '+ self.BE_HOW_NICE+' '+flvtool_command 
     169            flvtool_command = transcoding_queue.flvtool_installed_location+" -U stdin "+flvfile 
     170            flvtool_command_string = "cat "+ flvfile +" | "+ 'nice -n '+ transcoding_queue.nice_level + ' '+flvtool_command 
    130171            output,error = subprocess.Popen([flvtool_command_string],shell=True,stdout=subprocess.PIPE,cwd=os.getcwd()).communicate() 
    131172            logging.debug("FLV tool output: %s ; error: %s" %(output,error)) 
    132173            #XXX update the set of transformed file paths on the item. 
    133174            finish_time=time.time() 
    134             logging.info("Encoded %s in %.2f seconds, using cmd -- %s" % (videofile,finish_time-start_time,encoder_command_string)) 
     175            logging.info("Encoded %s in %.2f seconds, using cmd -- %s" % (original_videofile,finish_time-start_time,encoder_command_string)) 
    135176 
    136177            #ffmpeg2theora , theora/ogg conversion 
    137178            start_time=time.time()   
    138             theora_cmd =  self.FFMPEG2THEORA_COMMAND + ' ' + videofile + " -o " + theorafile 
    139             theora_cmd_string='nice -n '+ self.BE_HOW_NICE+' '+ theora_cmd 
     179            theora_cmd =  transcoding_queue.ffmpeg2theora_installed_location + ' ' + transcoding_queue.ffmpeg2theora_options + " -o " + theorafile + ' ' + original_videofile 
     180            theora_cmd_string='nice -n '+ transcoding_queue.nice_level+ ' '+ theora_cmd 
    140181            output,error = subprocess.Popen([theora_cmd_string],shell=True,stdout=subprocess.PIPE,cwd=os.getcwd()).communicate() 
    141182            logging.debug("Theora output: %s ; error: %s" %(output,error)) 
    142183            #XXX update the set of transformed file paths on the item. 
    143184            finish_time=time.time() 
    144             logging.info("Encoded %s in %.2f seconds, using cmd -- %s" % (videofile,finish_time-start_time,theora_cmd_string)) 
     185            logging.info("Encoded %s in %.2f seconds, using cmd -- %s" % (original_videofile,finish_time-start_time,theora_cmd_string)) 
    145186 
    146187            if os.path.exists(flvfile) and os.path.getsize(flvfile)>0 and os.path.exists(theorafile) and os.path.getsize(theorafile)>0: 
    147188                # OK ! It Worked. 
     189 
     190                #update the object with the details of the new file paths. 
     191                networkmediaitem.processed_filepaths=(flvfile,theorafile) 
     192                 
    148193                worked = True 
    149194            else: 
     
    154199                return False 
    155200 
    156             #Now, make the flash HTML snippet if the flv and Theora got created correctly. 
    157             #XXX todo, separate out the flv and ogg theora (java applet) html snippet 
    158             if os.path.exists(flvfile) and os.path.getsize(flvfile)>0: 
    159                     #lets make sure all the directories are created 
    160                     try: 
    161                         os.makedirs(os.path.dirname(includefile)) 
    162                     except: 
    163                         #the dirs may already exist 
    164                         pass 
    165  
    166                     logging.info("Making html template - original size of %s: %.1fMB, Encoded size: %.1fMB" % (videofile,os.path.getsize(videofile)/1000000.0,os.path.getsize(flvfile)/1000000.0)) 
    167                     data_map={ 
    168                         'flowplayer_location':self.FLOWPLAYER_LOCATION,  
    169                         'videofile':flvfile, 
    170                         'videobaseurl':self.VIDEO_SERVER_URL,  
    171                         'splashbaseurl':self.SPLASH_IMAGE_BASE,  
    172                         'splashfile':self.SPLASH_IMAGE_FILE,  
    173                         'cortado_location':self.CORTADO_LOCATION,  
    174                         'oggfile':theorafile, 
    175                     } 
    176                     template = Template(file=self.INCLUDE_TEMPLATE, searchList=[data_map])   
    177                     file_template=open(includefile, 'w') 
    178                     file_template.write(template.respond()) 
    179                     file_template.close() 
    180  
    181                        
    182201        except: 
    183             logging.info("Error while processing %s: %s" % (videofile,traceback.format_exc())) 
     202            logging.info("Error while processing %s: %s" % (original_videofile,traceback.format_exc())) 
    184203            #catch exception to remove lock file. 
    185204            os.remove(lockfile) 
    186205            return False 
    187206 
     207        os.remove(lockfile) 
    188208        #return a status value if we managed to get all the way here. 
    189209        return worked