Package conduit :: Package modules :: Module AudioVideoConverterModule
[hide private]

Source Code for Module conduit.modules.AudioVideoConverterModule

  1  import re 
  2  import logging 
  3  log = logging.getLogger("modules.AVConverter") 
  4   
  5  import conduit 
  6  import conduit.utils as Utils 
  7  import conduit.utils.CommandLineConverter as CommandLineConverter 
  8  import conduit.TypeConverter as TypeConverter 
  9  import conduit.datatypes.File as File 
 10  import conduit.datatypes.Audio as Audio 
 11  import conduit.datatypes.Video as Video 
 12   
 13  if Utils.program_installed("ffmpeg"): 
 14      MODULES = { 
 15          "AudioVideoConverter" :  { "type": "converter" } 
 16          } 
 17  else: 
 18      MODULES = {} 
 19   
20 -class FFmpegCommandLineConverter(CommandLineConverter.CommandLineConverter):
21 - def __init__(self, duration=None):
22 CommandLineConverter.CommandLineConverter.__init__(self) 23 self.duration = duration 24 self.percentage_match = re.compile('time=?(\d+\.\d+)')
25
26 - def build_command(self, **kwargs):
27 kwargs['in_file'] = '"%s"' 28 kwargs['out_file'] = '"%s"' 29 30 command = "ffmpeg -i %(in_file)s " 31 #video options 32 if kwargs.get('vcodec', None): command += "-vcodec %(vcodec)s " 33 if kwargs.get('vbitrate', None): command += "-b %(vbitrate)s " 34 if kwargs.get('fps', None): command += "-r %(fps)s " 35 if kwargs.get('vtag', None): command += "-vtag %(vtag)s " 36 if kwargs.get('width', None) and kwargs.get('height', None): 37 command += "-s %(width)sx%(height)s " 38 #audio options 39 if kwargs.get('acodec', None): command += "-acodec %(acodec)s " 40 if kwargs.get('arate', None): command += "-ar %(arate)s " 41 # if kwargs.get('abitrate', None): command += "-ab %(abitrate)s " 42 if kwargs.get('achannels', None): command += "-ac %(achannels)s " 43 #output file, overwrite and container format 44 if kwargs.get('format', None): command += "-f %(format)s " 45 command += "-y %(out_file)s" 46 47 self.command = command % kwargs
48
49 - def calculate_percentage(self, val):
50 return float(val)/self.duration*100.0
51
52 - def check_cancelled(self):
53 return conduit.GLOBALS.cancelled
54
55 -class MencoderCommandLineConverter(CommandLineConverter.CommandLineConverter):
56 - def __init__(self):
57 CommandLineConverter.CommandLineConverter.__init__(self) 58 self.percentage_match = re.compile('(\d+)%')
59
60 - def build_command(self, **kwargs):
61 kwargs['in_file'] = '"%s"' 62 kwargs['out_file'] = '"%s"' 63 64 command = "mencoder %(in_file)s -o %(out_file)s " 65 #audio options 66 if kwargs.get('arate', None): command += "-srate %(arate)s " 67 if kwargs.get('achannels', None): command += "-channels %(achannels) " 68 #only support lavc atm 69 command += "-oac lavc " 70 if kwargs.has_key('acodec') and kwargs.has_key('abitrate'): 71 command += "-lavcopts acodec=%(acodec)s:abitrate=%(abitrate)s " 72 if kwargs.get('achannels', None): 73 command += "-af volnorm,channels=%(achannels) " 74 else: 75 command += "-af volnorm " 76 #video options (only support lavc atm) 77 command += "-ovc lavc " 78 if kwargs.has_key('vcodec') and kwargs.has_key('vbitrate'): 79 command += "-ovc lavc -lavcopts vcodec=%(vcodec)s:vbitrate=%(vbitrate)s " 80 if kwargs.get('width', None) and kwargs.get('height', None): 81 command += "-vf-add scale=%(width)s:%(height)s " 82 if kwargs.get('fps', None): command += "-ofps %(fps)s " 83 if kwargs.get('vtag', None): command += "-ffourcc %(vtag)s " 84 85 self.command = command % kwargs
86
87 - def calculate_percentage(self, val):
88 return float(val)
89
90 - def check_cancelled(self):
91 return conduit.GLOBALS.cancelled
92
93 -class AudioVideoConverter(TypeConverter.Converter):
94 95 #These commands are run to determine attributes about the file 96 #(such as size and duration) prior to transcode. They should be 97 #Robust and work with ALL input files, even if the transode step may 98 #later fail 99 100 VIDEO_INSPECT_COMMAND = 'ffmpeg -an -y -t 0:0:0.001 -i "%s" -f image2 "%s" 2>&1' 101 AUDIO_INSPECT_COMMAND = 'ffmpeg -fs 1 -y -i "%s" -f wav "%s" 2>&1' 102
103 - def __init__(self):
104 self.conversions = { 105 "file/video,file/video" : self.transcode_video, 106 "file,file/video" : self.file_to_video, 107 "file/audio,file/audio" : self.transcode_audio, 108 "file,file/audio" : self.file_to_audio 109 }
110
111 - def transcode_video(self, video, **kwargs):
112 mimetype = video.get_mimetype() 113 if not Video.mimetype_is_video(mimetype): 114 log.debug("File %s is not video type: %s" % (video,mimetype)) 115 return None 116 input_file = video.get_local_uri() 117 118 #run ffmpeg over the video to work out its format, and duration 119 c = CommandLineConverter.CommandLineConverter() 120 c.build_command(AudioVideoConverter.VIDEO_INSPECT_COMMAND) 121 ok,output = c.convert(input_file,"/dev/null",save_output=True) 122 123 if not ok: 124 log.debug("Error getting video information\n%s" % output) 125 return None 126 127 #extract the video parameters 128 pat = re.compile(r'Input.*?Duration: ([\d:]*\.*\d*).*?Stream #\d\.\d: Video:.*?(\d+)x(\d+)',re.DOTALL) 129 try: 130 duration_string,w,h = re.search(pat,output).groups() 131 #make duration into seconds 132 ho,m,s = duration_string