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
25
27 kwargs['in_file'] = '"%s"'
28 kwargs['out_file'] = '"%s"'
29
30 command = "ffmpeg -i %(in_file)s "
31
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
39 if kwargs.get('acodec', None): command += "-acodec %(acodec)s "
40 if kwargs.get('arate', None): command += "-ar %(arate)s "
41
42 if kwargs.get('achannels', None): command += "-ac %(achannels)s "
43
44 if kwargs.get('format', None): command += "-f %(format)s "
45 command += "-y %(out_file)s"
46
47 self.command = command % kwargs
48
50 return float(val)/self.duration*100.0
51
54
59
61 kwargs['in_file'] = '"%s"'
62 kwargs['out_file'] = '"%s"'
63
64 command = "mencoder %(in_file)s -o %(out_file)s "
65
66 if kwargs.get('arate', None): command += "-srate %(arate)s "
67 if kwargs.get('achannels', None): command += "-channels %(achannels) "
68
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
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
89
92
94
95
96
97
98
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
110
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
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
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
132 ho,m,s = duration_string.split(':')
133 duration = (60.0*60.0*float(ho)) + (60*float(m)) + float(s)
134 except AttributeError:
135 log.debug("Error parsing ffmpeg output")
136 return None
137 log.debug("Input Video %s: size=%swx%sh, duration=%ss" % (input_file,w,h,duration))
138
139 if kwargs.get('width',None) != None and kwargs.get('height',None) != None:
140 kwargs['width'],kwargs['height'] = Utils.get_proportional_resize(
141 desiredW=int(kwargs['width']),
142 desiredH=int(kwargs['height']),
143 currentW=int(w),
144 currentH=int(h)
145 )
146
147
148 output_file = video.to_tempfile()
149 if kwargs.has_key("file_extension"):
150 video.force_new_file_extension(".%s" % kwargs["file_extension"])
151
152
153 if kwargs.get("mencoder", False) and Utils.program_installed("mencoder"):
154 c = MencoderCommandLineConverter()
155 else:
156 c = FFmpegCommandLineConverter(duration=duration)
157 c.build_command(**kwargs)
158 ok,output = c.convert(
159 input_file,
160 output_file,
161 callback=lambda x: log.debug("Trancoding video %s%% complete" % x),
162 save_output=True
163 )
164
165 if not ok:
166 log.debug("Error transcoding video\n%s" % output)
167 return None
168
169 return video
170
172 mimetype = audio.get_mimetype()
173 if not Audio.mimetype_is_audio(mimetype):
174 log.debug("File %s is not audio type: %s" % (audio,mimetype))
175 return None
176 input_file = audio.get_local_uri()
177
178
179 c = CommandLineConverter.CommandLineConverter()
180 c.build_command(AudioVideoConverter.AUDIO_INSPECT_COMMAND)
181 ok,output = c.convert(input_file,"/dev/null",save_output=True)
182
183 if not ok:
184 log.debug("Error getting audio information\n%s" % output)
185 return None
186
187
188 pat = re.compile(r'Input.*?Duration: ([\d:]*\.*\d*)',re.DOTALL)
189 try:
190 duration_string = re.search(pat,output).group(1)
191
192 h,m,s = duration_string.split(':')
193 duration = (60.0*60.0*float(h)) + (60*float(m)) + float(s)
194 except AttributeError:
195 log.debug("Error parsing ffmpeg output")
196 return None
197 log.debug("Input Audio %s: duration=%ss" % (input_file,duration))
198
199
200 output_file = audio.to_tempfile()
201 if kwargs.has_key("file_extension"):
202 audio.force_new_file_extension(".%s" % kwargs["file_extension"])
203
204
205 c = FFmpegCommandLineConverter(duration=duration)
206 c.build_command(**kwargs)
207 ok,output = c.convert(
208 input_file,
209 output_file,
210 callback=lambda x: log.debug("Trancoding audio %s%% complete" % x),
211 save_output=True
212 )
213
214 if not ok:
215 log.debug("Error transcoding audio\n%s" % output)
216 return None
217
218 return audio
219
233
247