Package flumotion :: Package wizard :: Module conversionsteps
[hide private]

Source Code for Module flumotion.wizard.conversionsteps

  1  # -*- Mode: Python -*- 
  2  # vi:si:et:sw=4:sts=4:ts=4 
  3  # 
  4  # Flumotion - a streaming media server 
  5  # Copyright (C) 2004,2005,2006,2007,2008 Fluendo, S.L. (www.fluendo.com). 
  6  # All rights reserved. 
  7   
  8  # This file may be distributed and/or modified under the terms of 
  9  # the GNU General Public License version 2 as published by 
 10  # the Free Software Foundation. 
 11  # This file is distributed without any warranty; without even the implied 
 12  # warranty of merchantability or fitness for a particular purpose. 
 13  # See "LICENSE.GPL" in the source distribution for more information. 
 14   
 15  # Licensees having purchased or holding a valid Flumotion Advanced 
 16  # Streaming Server license may use this file in accordance with the 
 17  # Flumotion Advanced Streaming Server Commercial License Agreement. 
 18  # See "LICENSE.Flumotion" in the source distribution for more information. 
 19   
 20  # Headers in this file shall remain intact. 
 21   
 22  import gettext 
 23   
 24  from flumotion.common.errors import NoBundleError 
 25  from flumotion.common.i18n import N_ 
 26  from flumotion.wizard.models import AudioEncoder, VideoEncoder, Muxer 
 27  from flumotion.wizard.workerstep import WorkerWizardStep 
 28   
 29  __version__ = "$Rev: 6969 $" 
 30  _ = gettext.gettext 
 31   
 32  _PREFERRED_VIDEO_ENCODER = "theora" 
 33  _PREFERRED_AUDIO_ENCODER = "vorbis" 
 34   
 35  # the denominator arg for all calls of this function was sniffed from 
 36  # the glade file's spinbutton adjustment 
 37   
38 -def _fraction_from_float(number, denominator):
39 """ 40 Return a string to be used in serializing to XML. 41 """ 42 return "%d/%d" % (number * denominator, denominator)
43 44
45 -class ConversionStep(WorkerWizardStep):
46 name = 'Encoding' 47 title = _('Encoding') 48 section = _('Conversion') 49 gladeFile = 'encoding-wizard.glade' 50
51 - def __init__(self, wizard):
52 self._audioEncoder = None 53 self._videoEncoder = None 54 WorkerWizardStep.__init__(self, wizard)
55 56 # Public API 57
58 - def getAudioPage(self):
59 if self.wizard.hasAudio(): 60 return self._getAudioPage() 61 return None
62
63 - def getVideoEncoder(self):
64 """Returns the selected video encoder or None 65 @returns: encoder or None 66 @rtype: L{flumotion.wizard.models.VideoEncoder} 67 """ 68 return self._videoEncoder
69
70 - def getAudioEncoder(self):
71 """Returns the selected audio encoder or None 72 @returns: encoder or None 73 @rtype: L{flumotion.wizard.models.AudioEncoder} 74 """ 75 return self._audioEncoder
76
77 - def getMuxerType(self):
78 """Returns the component-type, such as "ogg-muxer" 79 of the currently selected muxer. 80 @returns: the muxer 81 @rtype: string 82 """ 83 entry = self.muxer.get_selected() 84 return entry.componentType
85
86 - def getMuxerFormat(self):
87 """Returns the format of the muxer, such as "ogg". 88 @returns: the muxer format 89 @rtype: string 90 """ 91 entry = self.muxer.get_selected() 92 return entry.getProvidedMediaTypes()[0]
93
94 - def getAudioFormat(self):
95 """Returns the format of the audio encoder, such as "vorbis" 96 @returns: the audio format 97 @rtype: string 98 """ 99 if self._audioEncoder: 100 entry = self.audio.get_selected() 101 return entry.getProvidedMediaTypes()[0]
102
103 - def getVideoFormat(self):
104 """Returns the format of the video encoder, such as "theora" 105 @returns: the video format 106 @rtype: string 107 """ 108 if self._videoEncoder: 109 entry = self.video.get_selected() 110 return entry.getProvidedMediaTypes()[0]
111 112 # WizardStep 113
114 - def activated(self):
115 data = [('muxer', self.muxer, None)] 116 117 audio_producer = self.wizard.getAudioProducer() 118 if audio_producer: 119 data.append(('audio-encoder', self.audio, _PREFERRED_AUDIO_ENCODER)) 120 else: 121 self.audio.hide() 122 self.label_audio.hide() 123 124 video_producer = self.wizard.getVideoProducer() 125 if video_producer: 126 data.append(('video-encoder', self.video, _PREFERRED_VIDEO_ENCODER)) 127 else: 128 self.video.hide() 129 self.label_video.hide() 130 131 # If there is data in the combo already, do not populate it, 132 # Because it means we're pressing "back" in the wizard and the 133 # combo is already populated. 134 if not len(self.video) or not len(self.audio): 135 self._populateCombos(data)
136
137 - def getNext(self):
138 if self.wizard.hasVideo(): 139 return self._getVideoPage() 140 elif self.wizard.hasAudio(): 141 return self._getAudioPage() 142 else: 143 raise AssertionError
144 145 # Private 146
147 - def _populateCombos(self, combos, provides=None):
148 self.debug("populating combos %r", combos) 149 for ctype, combo, default_type in combos: 150 d = self.wizard.getWizardEntries( 151 wizardTypes=[ctype], 152 provides=provides) 153 d.addCallback(self._addEntries, ctype, combo, default_type) 154 combo.prefill([('...', None)]) 155 combo.set_sensitive(False) 156 self.wizard.waitForTask('querying encoders') 157 d.addCallback(lambda x: self.wizard.taskFinished())
158
159 - def _addEntries(self, entries, ctype, combo, default_type):
160 self.debug('adding entries for ctype %s: %r with default_type %s', ctype, entries, default_type) 161 data = [] 162 for entry in entries: 163 item = (N_(entry.description), entry) 164 provided_media_types = entry.getProvidedMediaTypes() 165 self.debug("adding entry %r", provided_media_types) 166 if default_type and default_type in provided_media_types: 167 data.insert(0, item) 168 else: 169 data.append(item) 170 combo.prefill(data) 171 combo.set_sensitive(True)
172
173 - def _createDummyModel(self, entry):
174 if entry.type == 'audio-encoder': 175 encoder = AudioEncoder() 176 elif entry.type == 'video-encoder': 177 encoder = VideoEncoder() 178 else: 179 raise AssertionError 180 181 encoder.componentType = entry.componentType 182 encoder.worker = self.worker 183 184 if entry.type == 'audio-encoder': 185 self._audioEncoder = encoder 186 else: 187 self._videoEncoder = encoder
188
189 - def _loadPlugin(self, entry):
190 def gotFactory(factory): 191 return factory(self.wizard)
192 193 def no_bundle(failure): 194 failure.trap(NoBundleError)
195 196 d = self.wizard.getWizardEntry(entry.componentType) 197 d.addCallback(gotFactory) 198 d.addErrback(no_bundle) 199 200 return d 201
202 - def _loadStep(self, combo):
203 entry = combo.get_selected() 204 assert entry, 'combo %s has nothing selected' % (combo,) 205 206 def pluginLoaded(plugin, entry): 207 if plugin is None: 208 self._createDummyModel(entry) 209 return None 210 # FIXME: verify that factory implements IEncoderPlugin 211 step = plugin.getConversionStep() 212 if isinstance(step, WorkerWizardStep): 213 self.wizard.workerChangedForStep(step, self.worker) 214 return step
215 216 d = self._loadPlugin(entry) 217 d.addCallback(pluginLoaded, entry) 218 219 return d 220
221 - def _getAudioPage(self):
222 def stepLoaded(step): 223 if step is not None: 224 self._audioEncoder = step.model 225 self.wizard.taskFinished() 226 return step
227 self.wizard.waitForTask('audio encoder page') 228 d = self._loadStep(self.audio) 229 d.addCallback(stepLoaded) 230 return d 231
232 - def _getVideoPage(self):
233 def stepLoaded(step): 234 if step is not None: 235 self._videoEncoder = step.model 236 self.wizard.taskFinished() 237 return step
238 self.wizard.waitForTask('video encoder page') 239 d = self._loadStep(self.video) 240 d.addCallback(stepLoaded) 241 return d 242
243 - def _muxerChanged(self):
244 muxer_entry = self.muxer.get_selected() 245 # '...' used while waiting for the query to be done 246 if muxer_entry is None: 247 return 248 self._populateCombos([('audio-encoder', self.audio, _PREFERRED_AUDIO_ENCODER), 249 ('video-encoder', self.video, _PREFERRED_VIDEO_ENCODER)], 250 provides=muxer_entry.getAcceptedMediaTypes())
251 252 # Callbacks 253
254 - def on_muxer__changed(self, combo):
255 self._muxerChanged()
256