Changeset 229 for indytube/trunk

Show
Ignore:
Timestamp:
10/14/07 08:15:21 (15 months ago)
Author:
andy
Message:

Updates to the IndyTubeTranscoder? class.

separate the actual file transcoding and template construction into a method

Experimental PerspectiveBroker? derived classes - a server and client impl for doing media downloading, bittorrent seeding, and transcoding

Location:
indytube/trunk
Files:
2 added
2 modified

Legend:

Unmodified
Added
Removed
  • indytube/trunk/indytube.conf

    r190 r229  
    3535LOG_FILE=/opt/indytube/plumi-wetube.log 
    3636LOG_LEVEL=logging.INFO 
     37 
     38[pb-server] 
     39PROTOCOL_PORT = "tcp:9119" 
     40TORRENT_DIR = u"/home/andy/src/EngageMedia/indytube-trunk/torrentDir/" 
     41DOWNLOAD_DIR = u"/home/andy/src/EngageMedia/indytube-trunk/downloadDir/" 
     42SERVER_NAME = "indytube-pb-server" 
  • indytube/trunk/indytube.py

    r173 r229  
    11#!/usr/bin/python2.4 
    22 
     3#standard library imports 
    34import ConfigParser 
    45import os 
     
    910 
    1011#3rd party libraries 
    11 # templating system 
     12#templating system 
    1213from Cheetah.Template import Template 
    1314#twisted networking 
     
    1516 
    1617class IndyTubeTranscoder(object): 
     18   """ The IndyTube transcoding class . Invokes mencoder and ffmpeg2theora """ 
     19   #holds statistics of files checked, and successfully transcoded, for each pass. 
     20   checked = 0 
     21   converted = 0 
    1722 
    1823   def __init__(self): 
     
    8085        """do one transcoding loop""" 
    8186        logging.info("Starting indytube... in %s " % self.VIDEO_FILE_DIRECTORY) 
    82         checked = 0 
    83         converted = 0 
     87        self.checked = 0 
     88        self.converted = 0 
    8489        for root,dir,files in os.walk(self.VIDEO_FILE_DIRECTORY): 
    8590                for f in files: 
    86  
    87                         #Start the transcoding attempt here, with file 'f' 
    88                         # 
    89                         (stem,extension)=os.path.splitext(f) 
    90                         if extension.lower() in self.CONVERT_THESE:  #we should convert the file 
    91                                 checked = checked + 1 
    92  
    93                                 relative_directory=root[len(self.VIDEO_FILE_DIRECTORY):] 
    94                                 if relative_directory.startswith(os.sep): 
    95                                         relative_directory=relative_directory[1:]  # make sure we are relative 
    96  
    97                                 videofile = os.path.join(root,f) 
    98                                 lockfile = os.path.join(root,stem+".wetube_lock")  # we are encoding already 
    99                                 skipfile = os.path.join(root,stem+".wetube_skip")  # we tried and failed, don't bother again 
    100                                 flvfile  = os.path.join(self.FLV_FILE_DIRECTORY,relative_directory,stem+".flv") 
    101                                 theorafile = os.path.join(self.FLV_FILE_DIRECTORY,relative_directory,stem+".ogg") 
    102                                 includefile  = os.path.join(self.INCLUDE_FILE_DIRECTORY,relative_directory,stem+self.INCLUDE_FILE_SUFFIX) 
    103                                 #logging.info("check for %s, %s, %s " % (lockfile, skipfile, flvfile)) 
    104  
    105                                 #check that another encoder isnt already processing this file (lockfile) or that we havent tried and failed before (skipfile) 
    106                                 if not(os.path.exists(lockfile) or os.path.exists(skipfile)): 
    107                                         #OK, valid video file ready to try to transcode 
    108                                         logging.debug("Checking file %s, using extension %s " % ( os.path.join(root,f), extension)) 
    109                                         try: 
    110                                                 os.mknod(lockfile)                # touch the lock file 
    111  
    112                                                 # if the flv file (autogenerated) or html snippet is not there, then reencode! 
    113                                                 if not(os.path.exists(flvfile)) or not(os.path.exists(includefile)): 
    114                                                         logging.info('OK to try encoding: '+videofile) 
    115                                                          
    116                                                         #pipe_to_null = '> /dev/null 2>&1' 
    117                                                         if self.DO_ENCODING: #maybe we just want to regenerate the include file! 
    118                                                                 #mencoder flv conversion 
    119                                                                 start_time=time.time() 
    120                                                                 encoder_command = self.MENCODER_LOCATION + " -quiet " + videofile + " -o " + flvfile + " " + self.MENCODER_OPTIONS 
    121                                                                 os.system('nice -n '+self.BE_HOW_NICE+' '+encoder_command) 
    122                                                                 finish_time=time.time() 
    123                                                                 logging.info("Encoded %s in %.2f seconds, using cmd -- %s" % (videofile,finish_time-start_time,encoder_command)) 
    124                                                                 flvtool_command = self.FLVTOOL_LOCATION+" -U stdin "+flvfile 
    125                                                                 os.system("cat "+ flvfile +" | "+ 'nice -n '+ self.BE_HOW_NICE+' '+flvtool_command)  
    126  
    127                                                                 #ffmpeg2theora , theora/ogg conversion 
    128                                                                 start_time=time.time()   
    129                                                                 theora_cmd =  self.FFMPEG2THEORA_COMMAND + ' ' + videofile + " -o " + theorafile 
    130                                                                 os.system('nice -n '+ self.BE_HOW_NICE+' '+ theora_cmd) 
    131                                                                 finish_time=time.time() 
    132                                                                 logging.info("Encoded %s in %.2f seconds, using cmd -- %s" % (videofile,finish_time-start_time,theora_cmd)) 
    133  
    134                                                                 converted = converted + 1 
    135  
    136                                                         else: 
    137                                                                 logging.debug("skipped encoding, will just do html template generation, if flv exists as non-zero size") 
    138                      
    139                                                 else: 
    140                                                         logging.debug("flv file and html file already exists, not doing transcoding") 
    141  
    142                                                 #make the flash HTML snippet if the flv got created correctly. 
    143                                                 #XXX todo, separate out the flv and ogg theora (java applet) html snippet 
    144                                                 if os.path.exists(flvfile) and os.path.getsize(flvfile)>0: 
    145                                                         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)) 
    146                                                         data_map={ 
    147                                                                         'flowplayer_location':self.FLOWPLAYER_LOCATION,  
    148                                                                         'videofile':relative_directory+'/'+stem+".flv",  
    149                                                                         'videobaseurl':self.VIDEO_SERVER_URL,  
    150                                                                         'splashbaseurl':self.SPLASH_IMAGE_BASE,  
    151                                                                         'splashfile':self.SPLASH_IMAGE_FILE,  
    152                                                                         'cortado_location':self.CORTADO_LOCATION,  
    153                                                                         'oggfile':stem+".ogg",  
    154                                                                         'mirid':stem} 
    155                                                         t = Template(file=self.INCLUDE_TEMPLATE, searchList=[data_map])   
    156                                                         f=open(includefile, 'w') 
    157                                                         f.write(t.respond()) 
    158                                                         f.close() 
    159  
    160                                                 else: 
    161                                                         logging.info("FLV file size is zero - assuming encoding failed! Permanently skipping file!") 
    162                                                         os.mknod(skipfile) 
    163                         
    164                                                 #finished transcoding block , remove lock file  
    165                                                 os.remove(lockfile) 
    166  
    167                                         except: 
    168                                                 logging.info("Error while processing %s: %s" % (videofile,traceback.format_exc())) 
    169                                                 os.remove(lockfile) 
    170                                                 #remove this process's lockfile, this exception will stop the entire process 
    171                                                 os.remove(self.ENCODER_LOCKFILE) 
    172  
    173                                 else: 
    174                                         logging.debug(' lock file or skip file present for file %s ' % videofile) 
     91                        ok = self.attempt_transcode_file(f) 
     92                        self.checked = self.checked + 1 
     93                        if ok: 
     94                                self.converted = self.converted + 1 
    17595 
    17696        #remove this process's lockfile, we have finished the loop 
    17797        os.remove(self.ENCODER_LOCKFILE) 
    178         logging.info("Ending indytube... We checked %s eligble files, converted %s files " % (checked, converted)) 
     98        logging.info("Ending indytube... We checked %s eligble files, converted %s files " % (self.checked, self.converted)) 
    17999 
    180100        ## end : do_transcoding_loop 
     101 
     102def attempt_transcode_file(self, f): 
     103        '''Start the transcoding attempt with file 'f'. Converts to FLV format, possibly OGG/Theora in future. Produces HTML snippets for including 
     104           the players appropriate for the produced video format. At the moment, this is FlowPlayer for FLV, and Cortado java applet for OGG/Theora ''' 
     105        #whether or not the transcoding worked for the given file 'f' 
     106        worked = False 
     107 
     108        (stem,extension)=os.path.splitext(f) 
     109        if extension.lower() in self.CONVERT_THESE:  #we should convert the file 
     110 
     111                relative_directory=root[len(self.VIDEO_FILE_DIRECTORY):] 
     112                if relative_directory.startswith(os.sep): 
     113                        relative_directory=relative_directory[1:]  # make sure we are relative 
     114 
     115                        videofile = os.path.join(root,f) 
     116                        lockfile = os.path.join(root,stem+".wetube_lock")  # we are encoding already 
     117                        skipfile = os.path.join(root,stem+".wetube_skip")  # we tried and failed, don't bother again 
     118                        flvfile  = os.path.join(self.FLV_FILE_DIRECTORY,relative_directory,stem+".flv") 
     119                        theorafile = os.path.join(self.FLV_FILE_DIRECTORY,relative_directory,stem+".ogg") 
     120                        includefile  = os.path.join(self.INCLUDE_FILE_DIRECTORY,relative_directory,stem+self.INCLUDE_FILE_SUFFIX) 
     121                        #logging.info("check for %s, %s, %s " % (lockfile, skipfile, flvfile)) 
     122 
     123                        #check that another encoder isnt already processing this file (lockfile) or that we havent tried and failed before (skipfile) 
     124                        if not(os.path.exists(lockfile) or os.path.exists(skipfile)): 
     125                                #OK, valid video file ready to try to transcode 
     126                                logging.debug("Checking file %s, using extension %s " % ( os.path.join(root,f), extension)) 
     127                                try: 
     128                                        # touch the lock file 
     129                                        os.mknod(lockfile) 
     130 
     131                                        # if the flv file (autogenerated) or html snippet is not there, then reencode! 
     132                                        if not(os.path.exists(flvfile)) or not(os.path.exists(includefile)): 
     133                                                logging.info('OK to try encoding: '+videofile) 
     134                                                         
     135                                                #pipe_to_null = '> /dev/null 2>&1' 
     136                                                if self.DO_ENCODING: #maybe we just want to regenerate the include file! 
     137                                                        #mencoder flv conversion 
     138                                                        start_time=time.time() 
     139                                                        encoder_command = self.MENCODER_LOCATION + " -quiet " + videofile + " -o " + flvfile + " " + self.MENCODER_OPTIONS 
     140                                                        os.system('nice -n '+self.BE_HOW_NICE+' '+encoder_command) 
     141                                                        finish_time=time.time() 
     142                                                        logging.info("Encoded %s in %.2f seconds, using cmd -- %s" % (videofile,finish_time-start_time,encoder_command)) 
     143                                                        flvtool_command = self.FLVTOOL_LOCATION+" -U stdin "+flvfile 
     144                                                        os.system("cat "+ flvfile +" | "+ 'nice -n '+ self.BE_HOW_NICE+' '+flvtool_command)  
     145 
     146                                                        #ffmpeg2theora , theora/ogg conversion 
     147                                                        start_time=time.time()   
     148                                                        theora_cmd =  self.FFMPEG2THEORA_COMMAND + ' ' + videofile + " -o " + theorafile 
     149                                                        os.system('nice -n '+ self.BE_HOW_NICE+' '+ theora_cmd) 
     150                                                        finish_time=time.time() 
     151                                                        logging.info("Encoded %s in %.2f seconds, using cmd -- %s" % (videofile,finish_time-start_time,theora_cmd)) 
     152 
     153                                                else: 
     154                                                        logging.debug("skipped encoding, will just do html template generation, if flv exists as non-zero size") 
     155                     
     156                                        else: 
     157                                                logging.debug("flv file and html file already exists, not doing transcoding") 
     158 
     159                                        #make the flash HTML snippet if the flv got created correctly. 
     160                                        #XXX todo, separate out the flv and ogg theora (java applet) html snippet 
     161                                        if os.path.exists(flvfile) and os.path.getsize(flvfile)>0: 
     162                                                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)) 
     163                                                data_map={ 
     164                                                        'flowplayer_location':self.FLOWPLAYER_LOCATION,  
     165                                                        'videofile':relative_directory+'/'+stem+".flv",  
     166                                                        'videobaseurl':self.VIDEO_SERVER_URL,  
     167                                                        'splashbaseurl':self.SPLASH_IMAGE_BASE,  
     168                                                        'splashfile':self.SPLASH_IMAGE_FILE,  
     169                                                        'cortado_location':self.CORTADO_LOCATION,  
     170                                                        'oggfile':stem+".ogg",  
     171                                                        'mirid':stem 
     172                                                        } 
     173                                                t = Template(file=self.INCLUDE_TEMPLATE, searchList=[data_map])   
     174                                                f=open(includefile, 'w') 
     175                                                f.write(t.respond()) 
     176                                                f.close() 
     177 
     178                                                # OK ! It Worked. 
     179                                                worked = True 
     180 
     181                                        else: 
     182                                                logging.info("FLV file size is zero - assuming encoding failed! Permanently skipping file!") 
     183                                                os.mknod(skipfile) 
     184                        
     185                                        #finished transcoding block , remove lock file  
     186                                        os.remove(lockfile) 
     187 
     188                                except: 
     189                                        logging.info("Error while processing %s: %s" % (videofile,traceback.format_exc())) 
     190                                        os.remove(lockfile) 
     191                                        #remove this process's lockfile, this exception will stop the entire process 
     192                                        os.remove(self.ENCODER_LOCKFILE) 
     193 
     194                        else: 
     195                                logging.debug(' lock file or skip file present for file %s ' % videofile) 
     196         
     197        #return a status value 
     198        return worked 
    181199 
    182200def main(): 
     
    204222    looperInvoker(indytuber) 
    205223    #start the twisted reactor 
     224    # see http://twistedmatrix.com/trac/wiki/FrequentlyAskedQuestions#Igetexceptions.ValueError:signalonlyworksinmainthreadwhenItrytorunmyTwistedprogramWhatswrong 
     225    # if you want to not install the signal handlers 
    206226    reactor.run() 
    207227