4 Base classes for the external programs API.
14 Abstraction of the API class for the transcoder program.
23 # Recommended formats.
32 # File extensions by container. First value is for audio files and the
33 # second one is for (audio-)video files.
35 "avi": ["avi", "avi"],
36 "flv": ["flv", "flv"],
37 "mp4": ["mp4", "mp4"],
38 "ogg": ["oga", "ogv"],
39 "webm": ["webm", "webm"],
40 "mpegts": ["mts", "mts"]
52 def __init__(self, input_file, name=None, prog_bin=None):
53 self.input_file = input_file
54 if prog_bin is not None:
55 self.prog_bin = prog_bin
58 name = cis_util.get_name(input_file)
62 def transcode(self, container, a_codec=None, v_codec=None,
63 a_bitrate=None, a_samplingrate=None, a_channels=None,
64 v_bitrate=None, v_framerate=None, v_resolution=None, v_dar=None):
66 Transcodes the input file to an audio-video file.
68 @param container: possible values are listed in containers member
70 @param a_codec possible values are listed in a_codecs member as keys
71 @param v_codec possible values are listed in v_codecs member as keys
72 @param a_bitrate (numeric) audio bit rate
73 @param a_samplingrate (numeric) audio sampling rate in Hz
74 @param a_channels (numeric) number of audio channels
75 @param v_bitrate (numeric) video bit rate
76 @param v_framerate (numeric) number of frames per second for a video
77 @param v_resolution (string) video image size as <width>x<height>
78 @param v_dar video display aspect ratio as <den>x<num> or float
79 @return output file name
83 if a_codec is None and v_codec is None:
84 raise ValueError('No audio or video codec specified.')
86 if a_codec is not None and type(a_codec) is not str:
87 raise TypeError('Audio codec must be string.')
89 if v_codec is not None and type(v_codec) is not str:
90 raise TypeError('Video codec must be string.')
92 if a_samplingrate is not None and type(a_samplingrate) is not int:
93 raise TypeError('Audio sampling rate must be an integer.')
95 if a_channels is not None and type(a_channels) is not int:
96 raise TypeError('Audio channels parameter must be an integer.')
98 if v_framerate is not None and type(v_framerate) is not int:
99 raise TypeError('Video frate rate must be an integer.')
101 if v_resolution is not None \
102 and re.match('[\d]+x[\d]+', v_resolution) is None:
103 raise ValueError('Video resolution must be a string like <width>x<height>.')
105 if v_dar is not None and (type(v_dar) is not float \
106 and re.match('[\d]+:[\d]+', v_dar) is None):
107 raise ValueError('Video display aspect ratio must be a float or a string like <den>:<num>.')
109 self.output_file = self.dest_path + self.name
110 if v_resolution is not None:
111 self.output_file += '_'
112 self.output_file += v_resolution[(v_resolution.rindex('x')+1):]
113 self.output_file += 'p'
114 ext = self.tr_extension(container, (v_codec is not None))
116 self.output_file += '.' + ext
118 return self._transcode(self.tr_container(container),
119 self.tr_a_codec(a_codec), self.tr_v_codec(v_codec),
120 a_bitrate, a_samplingrate, a_channels,
121 v_bitrate, v_framerate, v_resolution, v_dar)
123 def _transcode(self, container, a_codec=None, v_codec=None,
124 a_bitrate=None, a_samplingrate=None, a_channels=None,
125 v_bitrate=None, v_framerate=None, v_resolution=None, v_dar=None):
127 Called by transcode; must be overridden by a child class which
128 effectively transcodes the input file.
130 @return output file name
134 def tr_container(self, name):
135 """ Translates container API name into external program identifier."""
137 if not self.containers.has_key(name) or self.containers[name] is None:
138 raise api_exceptions.NotImplementedException("Container " + name)
140 return self.containers[name]
142 def tr_extension(self, name, video=True):
143 """ Translates container API name into file extension."""
150 if not self.extensions.has_key(name) or self.extensions[name] is None:
153 return self.extensions[name][i]
155 def tr_a_codec(self, name):
156 """ Translates audio codec API name into external program identifier."""
158 if not self.a_codecs.has_key(name) or self.a_codecs[name] is None:
159 raise api_exceptions.NotImplementedException("Audio Codec " + name)
161 return self.a_codecs[name]
163 def tr_v_codec(self, name):
164 """ Translates video codec API name into external program identifier."""
166 if not self.v_codecs.has_key(name) or self.v_codecs[name] is None:
167 raise api_exceptions.NotImplementedException("Video Codec " + name)
169 return self.v_codecs[name]
172 class BaseThumbExtractor:
174 Abstraction of the API class for the thumbnail extraction program.
176 Thumbnail extracted are in JPEG format.
184 def __init__(self, input_file, name=None, prog_bin=None):
185 self.input_file = input_file
186 if prog_bin is not None:
187 self.prog_bin = prog_bin
190 name = cis_util.get_name(input_file)
194 def extract_thumb(self, seek_pos, resolution="120x90", index=0):
196 Extracts a thumbnail from the video from a specified position
197 expressed in seconds (int/float).
199 index: an index appended to the image name in order to avoid
204 def extract_random_thumb(self, resolution="120x90", index=0):
206 Extracts a thumbnail from the video from a random position.
208 duration = self.get_video_duration()
209 seek_pos = random.random() * duration
210 self.extract_thumb(seek_pos, resolution, index)
212 def extract_summary_thumbs(self, count, resolution="120x90"):
214 Extracts a series of thumbnails from a video by taking several
217 The snapshots are taken from equally spaced positions such that
218 `count` thumbs are extracted.
220 duration = self.get_video_duration()
221 interval = duration / (count + 1)
223 n_thumbs_extracted = 0
225 for index in range (0, count):
226 thumb_extracted = True
228 self.extract_thumb(seek_pos, resolution, n_thumbs_extracted)
229 except api_exceptions.ThumbExtractionException as e:
230 thumb_extracted = False
233 n_thumbs_extracted += 1
237 return n_thumbs_extracted
239 def get_output_file_name(self, index):
240 """ Returns the name required as output file name based on index. """
241 output_file_name = self.dest_path + self.name \
242 + '_t' + ("%02d" % index) + '.jpg'
243 return output_file_name
245 def get_video_duration(self):
249 class BaseFileTransferer:
251 Ensures file transfer from the Web Server to the CIS (here).
253 Several implementations can be done by extending this class for
254 file transfer protocol such as FTP, SCP, RSYNC, HTTP etc.
260 def __init__(self, local_path='', remote_path=''):
261 """ Initialize by setting local and remote paths for file transfer. """
262 self.local_path = local_path
263 self.remote_path = remote_path
268 def get(self, files):
270 Transfers files locally from the Web Server.
272 files: a list of file name strings
276 def put(self, files):
278 Transfers files from the Web Server locally.
280 files: a list of file name strings
286 This method should be called when the instance is no longer required.
288 Class's destructor calls this method.
295 def get_video_duration(input_file, formated=False):
297 Returns the number of seconds of a video (int/float) if formated is
298 False and a string for duration formated as [HH:]:mm:ss otherwise.