def __init__(self, name="", uri=None, **kwargs): """ @param name: the name of the project @param uri: the uri of the project """ Loggable.__init__(self) self.log("name:%s, uri:%s", name, uri) self.name = name self.settings = None self.description = "" self.uri = uri self.urichanged = False self.format = None self.sources = SourceList() self.sources.connect("source-added", self._sourceAddedCb) self.sources.connect("source-removed", self._sourceRemovedCb) self._dirty = False self.timeline = Timeline() self.factory = TimelineSourceFactory(self.timeline) self.pipeline = Pipeline() self.view_action = ViewAction() self.view_action.addProducers(self.factory) self.seeker = Seeker(80) self.settings = ExportSettings() self._videocaps = self.settings.getVideoCaps()
def __init__(self, name="", uri=None, **kwargs): """ name : the name of the project uri : the uri of the project """ Loggable.__init__(self) self.log("name:%s, uri:%s", name, uri) self.name = name self.settings = None self.description = "" self.uri = uri self.urichanged = False self.format = None self.sources = SourceList() self.sources.connect("source-removed", self._sourceRemovedCb) self.settingssigid = 0 self._dirty = False self.timeline = Timeline() self.factory = TimelineSourceFactory(self.timeline) self.pipeline = Pipeline() self.view_action = ViewAction() self.view_action.addProducers(self.factory)
def __init__(self, pitivi): gst.log("Creating new WebcamManager Dialog") self.pitivi = pitivi GladeWindow.__init__(self) # Create gtk widget using glade model self.draw_window = self.widgets["draw_window"] self.draw_window.unset_flags(gtk.DOUBLE_BUFFERED) self.draw_window.unset_flags(gtk.SENSITIVE) self.record_btn = self.widgets["record_btn"] self.close_btn = self.widgets["close_btn"] self.close_btn.connect("clicked", self.close) self.record_btn.connect("clicked", self.threaded_recording) self.window.connect("destroy", self.close) self.record_btn = self.record_btn.get_children()[0] self.record_btn = self.record_btn.get_children()[0].get_children()[1] self.record_btn.set_label("Start Recording") self.sourcefactories = SourceList() self._audiodev = None self._videodev = None self._vdevcombo = self.widgets["videodev_combo"] self._vdevcombo.set_active(0) self._vdevcombo.set_model(gtk.ListStore(str, object)) self._vdevcombo.set_attributes(self._vdevcombo.child.get_cell_renderers()[0], text=0) self._adevcombo = self.widgets["audiodev_combo"] self._adevcombo.set_active(0) self._adevcombo.set_model(gtk.ListStore(str, object)) self._adevcombo.set_attributes(self._adevcombo.child.get_cell_renderers()[0], text=0) self._updateVideoCombo() self._updateAudioCombo() self.filepath = None self.sink = SinkBin() CallbackThread(self._setupPlayer).start()
def __init__(self): self.sourcefactories = SourceList() self.capture_pipe = None self.player = None glade_dir = os.path.dirname(os.path.abspath(__file__)) self.objectpool_ui = gtk.glade.XML(os.path.join(glade_dir, "net_capture.glade")) self.stream_window = self.objectpool_ui.get_widget("network_capture") self.screen = self.objectpool_ui.get_widget("screen") self.capture_btn = self.objectpool_ui.get_widget("capture_btn") self.preview_btn = self.objectpool_ui.get_widget("preview_btn") self.close_btn = self.objectpool_ui.get_widget("close_btn") self.port = self.objectpool_ui.get_widget("port") self.address = self.objectpool_ui.get_widget("address") self.uri = self.objectpool_ui.get_widget("url") self.status = self.objectpool_ui.get_widget("status") self.http_radiobtn = self.objectpool_ui.get_widget("protocol") self.udp_radiobtn = self.objectpool_ui.get_widget("udp") self.rtsp_radiobtn = self.objectpool_ui.get_widget("rtsp") self.http_radiobtn.connect("toggled", self.on_protocol_toggled, "http") self.udp_radiobtn.connect("toggled", self.on_protocol_toggled, "udp") self.rtsp_radiobtn.connect("toggled", self.on_protocol_toggled, "rtsp") self.address.connect("changed", self.on_address_port_changed, "address") self.port.connect("changed", self.on_address_port_changed, "port") self.close_btn.connect("clicked", self.close) self.stream_window.connect("destroy", self.close) dic = { "on_close_clicked" : self.close, "on_preview_btn_clicked" : self.live_pipeline, "on_capture_btn_clicked" : self.capture_pipeline } self.objectpool_ui.signal_autoconnect(dic) self.capture_btn = self.capture_btn.get_children()[0] self.capture_btn = self.capture_btn.get_children()[0].get_children()[1] self.capture_btn.set_label("Capture")
def setUp(self): self.sourcelist = SourceList()
class TestSourceList(TestCase): def setUp(self): self.sourcelist = SourceList() def testAddUriDiscoveryOk(self): """ Test the simple case of adding an uri. """ uri = "file:///ciao" factory = FileSourceFactory(uri) self.sourcelist.addUri(uri) self.failUnlessEqual(len(self.sourcelist.getSources()), 0) self.failUnlessRaises(SourceListError, self.sourcelist.addUri, uri) # mock discovery-done self.sourcelist.discoverer.emit("discovery-done", uri, factory) self.failUnlessEqual(len(self.sourcelist.getSources()), 1) # can't add again self.failUnlessRaises(SourceListError, self.sourcelist.addUri, uri) def testAddUriDiscoveryOkSourceGone(self): """ Test that we don't explode if discoverer finishes analyzing a source that in the meantime was removed. """ uri = "file:///ciao" factory = FileSourceFactory(uri) self.sourcelist.addUri(uri) self.sourcelist.removeUri(uri) self.sourcelist.discoverer.emit("discovery-done", uri, factory) self.failUnlessEqual(len(self.sourcelist.getSources()), 0) # this shouldn't fail since we removed the factory before the discovery # was complete self.sourcelist.addUri(uri) def testAddUriDiscoveryErrorSourceGone(self): """ Same as the test above, but testing the discovery-error handler. """ uri = "file:///ciao" factory = FileSourceFactory(uri) self.sourcelist.addUri(uri) self.sourcelist.removeUri(uri) self.sourcelist.discoverer.emit("discovery-error", uri, "error", "verbose debug") self.failUnlessEqual(len(self.sourcelist.getSources()), 0) # this shouldn't fail since we removed the factory before the discovery # was complete self.sourcelist.addUri(uri) def testAddUriDiscoveryError(self): uri = "file:///ciao" factory = FileSourceFactory(uri) self.sourcelist.addUri(uri) self.failUnlessEqual(len(self.sourcelist.getSources()), 0) self.failUnlessRaises(SourceListError, self.sourcelist.addUri, uri) # mock discovery-done self.sourcelist.discoverer.emit("discovery-error", uri, "error", "verbose debug") self.failUnlessEqual(len(self.sourcelist.getSources()), 0) # there was an error, the factory wasn't added so this shouldn't raise self.sourcelist.addUri(uri)
class Project(Signallable, Loggable): """The base class for PiTiVi projects @ivar name: The name of the project @type name: C{str} @ivar description: A description of the project @type description: C{str} @ivar sources: The sources used by this project @type sources: L{SourceList} @ivar timeline: The timeline @type timeline: L{Timeline} @ivar pipeline: The timeline's pipeline @type pipeline: L{Pipeline} @ivar factory: The timeline factory @type factory: L{TimelineSourceFactory} @ivar format: The format under which the project is currently stored. @type format: L{FormatterClass} @ivar loaded: Whether the project is fully loaded or not. @type loaded: C{bool} Signals: - C{loaded} : The project is now fully loaded. """ __signals__ = { "settings-changed" : ['old', 'new'], "project-changed" : [], } def __init__(self, name="", uri=None, **kwargs): """ @param name: the name of the project @param uri: the uri of the project """ Loggable.__init__(self) self.log("name:%s, uri:%s", name, uri) self.name = name self.settings = None self.description = "" self.uri = uri self.urichanged = False self.format = None self.sources = SourceList() self.sources.connect("source-added", self._sourceAddedCb) self.sources.connect("source-removed", self._sourceRemovedCb) self._dirty = False self.timeline = Timeline() self.factory = TimelineSourceFactory(self.timeline) self.pipeline = Pipeline() self.view_action = ViewAction() self.view_action.addProducers(self.factory) self.seeker = Seeker(80) self.settings = ExportSettings() self._videocaps = self.settings.getVideoCaps() def release(self): self.pipeline.release() self.pipeline = None #{ Settings methods def getSettings(self): """ return the currently configured settings. """ self.debug("self.settings %s", self.settings) return self.settings def setSettings(self, settings): """ Sets the given settings as the project's settings. @param settings: The new settings for the project. @type settings: ExportSettings """ assert settings self.log("Setting %s as the project's settings", settings) oldsettings = self.settings self.settings = settings self._projectSettingsChanged() self.emit('settings-changed', oldsettings, settings) #} #{ Save and Load features def setModificationState(self, state): self._dirty = state if state: self.emit('project-changed') def hasUnsavedModifications(self): return self._dirty def _projectSettingsChanged(self): settings = self.getSettings() self._videocaps = settings.getVideoCaps() if self.timeline: self.timeline.updateVideoCaps(self._videocaps) for fact in self.sources.getSources(): fact.setFilterCaps(self._videocaps) if self.pipeline.getState() != gst.STATE_NULL: self.pipeline.stop() self.pipeline.pause() def _sourceAddedCb(self, sourcelist, factory): factory.setFilterCaps(self._videocaps) def _sourceRemovedCb(self, sourclist, uri, factory): self.timeline.removeFactory(factory)
class Project(Signallable, Loggable): """The base class for PiTiVi projects @ivar name: The name of the project @type name: C{str} @ivar description: A description of the project @type description: C{str} @ivar sources: The sources used by this project @type sources: L{SourceList} @ivar timeline: The timeline @type timeline: L{Timeline} @ivar pipeline: The timeline's pipeline @type pipeline: L{Pipeline} @ivar factory: The timeline factory @type factory: L{TimelineSourceFactory} @ivar format: The format under which the project is currently stored. @type format: L{FormatterClass} @ivar loaded: Whether the project is fully loaded or not. @type loaded: C{bool} Signals: - C{loaded} : The project is now fully loaded. """ __signals__ = { "settings-changed" : ['old', 'new'], } def __init__(self, name="", uri=None, **kwargs): """ name : the name of the project uri : the uri of the project """ Loggable.__init__(self) self.log("name:%s, uri:%s", name, uri) self.name = name self.settings = None self.description = "" self.uri = uri self.urichanged = False self.format = None self.sources = SourceList() self.sources.connect("source-added", self._sourceAddedCb) self.sources.connect("source-removed", self._sourceRemovedCb) self._dirty = False self.timeline = Timeline() self.factory = TimelineSourceFactory(self.timeline) self.pipeline = Pipeline() self.view_action = ViewAction() self.view_action.addProducers(self.factory) self.seeker = Seeker(80) self.getCapsFromSettings() def getCapsFromSettings(self): settings = self.getSettings() #formatstr = "video/x-raw-rgb,width=(int)%d,height=(int)%d;"\ # "video/x-raw-yuv,width=(int)%d,height=(int)%d" #capstr = formatstr % ( # settings.videowidth, # settings.videoheight, # settings.videowidth, # settings.videoheight) #self._videocaps = gst.Caps(capstr) self._videocaps = settings.getVideoCaps() def release(self): self.pipeline.release() self.pipeline = None #{ Settings methods def getSettings(self): """ return the currently configured settings. If no setting have been explicitely set, some smart settings will be chosen. """ self.debug("self.settings %s", self.settings) return self.settings or self.getAutoSettings() def setSettings(self, settings): """ Sets the given settings as the project's settings. If settings is None, the current settings will be unset """ self.log("Setting %s as the project's settings", settings) oldsettings = self.settings self.settings = settings self._projectSettingsChanged() self.emit('settings-changed', oldsettings, settings) def unsetSettings(self, unused_settings): """ Remove the currently configured settings.""" self.setSettings(None) def getAutoSettings(self): """ Computes and returns smart settings for the project. If the project only has one source, it will be that source's settings. If it has more than one, it will return the largest setting that suits all contained sources. """ settings = ExportSettings() if not self.timeline: self.warning("project doesn't have a timeline, returning default settings") return settings # FIXME: this is ugly, but rendering for now assumes at most one audio # and one video tracks have_audio = have_video = False for track in self.timeline.tracks: if isinstance(track.stream, VideoStream) and track.duration != 0: have_video = True elif isinstance(track.stream, AudioStream) and track.duration != 0: have_audio = True if not have_audio: settings.aencoder = None if not have_video: settings.vencoder = None return settings #} #{ Save and Load features def save(self, location=None, overwrite=False): """ Save the project to the given location. @param location: The location to write to. If not specified, the current project location will be used (if set). @type location: C{URI} @param overwrite: Whether to overwrite existing location. @type overwrite: C{bool} """ # import here to break circular import from pitivi.formatters.format import save_project from pitivi.formatters.base import FormatterError self.log("saving...") location = location or self.uri if location == None: raise FormatterError("Location unknown") save_project(self, location or self.uri, self.format, overwrite) self.uri = location def setModificationState(self, state): self._dirty = state def hasUnsavedModifications(self): return self._dirty def _projectSettingsChanged(self): self.getCapsFromSettings() for fact in self.sources.getSources(): fact.setFilterCaps(self._videocaps) if self.pipeline.getState() != gst.STATE_NULL: self.pipeline.stop() self.pipeline.pause() def _sourceAddedCb(self, sourcelist, factory): factory.setFilterCaps(self._videocaps) def _sourceRemovedCb(self, sourclist, uri, factory): self.timeline.removeFactory(factory)
class WebcamManagerDialog(GladeWindow): """ Webcan capture dialog box """ glade_file = "cam_capture.glade" def __init__(self, pitivi): gst.log("Creating new WebcamManager Dialog") self.pitivi = pitivi GladeWindow.__init__(self) # Create gtk widget using glade model self.draw_window = self.widgets["draw_window"] self.draw_window.unset_flags(gtk.DOUBLE_BUFFERED) self.draw_window.unset_flags(gtk.SENSITIVE) self.record_btn = self.widgets["record_btn"] self.close_btn = self.widgets["close_btn"] self.close_btn.connect("clicked", self.close) self.record_btn.connect("clicked", self.threaded_recording) self.window.connect("destroy", self.close) self.record_btn = self.record_btn.get_children()[0] self.record_btn = self.record_btn.get_children()[0].get_children()[1] self.record_btn.set_label("Start Recording") self.sourcefactories = SourceList() self._audiodev = None self._videodev = None self._vdevcombo = self.widgets["videodev_combo"] self._vdevcombo.set_active(0) self._vdevcombo.set_model(gtk.ListStore(str, object)) self._vdevcombo.set_attributes(self._vdevcombo.child.get_cell_renderers()[0], text=0) self._adevcombo = self.widgets["audiodev_combo"] self._adevcombo.set_active(0) self._adevcombo.set_model(gtk.ListStore(str, object)) self._adevcombo.set_attributes(self._adevcombo.child.get_cell_renderers()[0], text=0) self._updateVideoCombo() self._updateAudioCombo() self.filepath = None self.sink = SinkBin() CallbackThread(self._setupPlayer).start() def show_all(self): self.window.show_all() # Perform record in a seperate thread def threaded_recording(self, w): CallbackThread(self.do_recording, w).start() # Record button action callback def do_recording(self, w): if self.record_btn.get_label() == "Start Recording": gst.debug("recording started") self.filepath = 'file://'+tempfile.mktemp(suffix=".ogg", prefix="pitivi-webcam-capture-") self.player.record(self.filepath, ExportSettings()) self.record_btn.set_label("Stop Recording") self.player.set_state(gst.STATE_PLAYING) else: gst.debug("recording stopped") self.player.stopRecording() # FIXME : use the generic way for adding a file self.sourcefactories.addUris([self.filepath]) self.player.set_state(gst.STATE_PLAYING) self.record_btn.set_label("Start Recording") # For Setting up audio,video sinks def setSinks(self): self.sink.connectSink(self.player, True, True) bus = self.player.get_bus() bus.add_signal_watch() bus.enable_sync_message_emission() bus.connect('sync-message::element', self.on_sync_message) # Close the Webcamdialog def close(self, w): self.window.hide() self.player.set_state(gst.STATE_NULL) self.window.destroy() # For draw_window syncs def on_sync_message(self, bus, message): if message.structure is None: return message_name = message.structure.get_name() if message_name == 'prepare-xwindow-id': # Assign the viewport imagesink = message.src imagesink.set_property('force-aspect-ratio', True) try: imagesink.set_xwindow_id(self.draw_window.window.xid) except: gst.warning("Couldn't set the XID on our video sink !") def _setupPlayer(self): gst.debug("Creating initial SmartCaptureBin") # figure out adev probe = self.pitivi.deviceprobe if probe is not None and len(probe.getAudioSourceDevices()): adev = probe.getAudioSourceDevices()[0] else: adev = None self._changeSelectedAudio(adev) if len(probe.getVideoSourceDevices()): vdev = probe.getVideoSourceDevices()[0] else: vdev = None self._changeSelectedVideo(vdev) if probe is not None: probe.connect("device-added", self._deviceAddedCb) probe.connect("device-removed", self._deviceRemovedCb) if hasattr(self, "player"): self.player.set_state(gst.STATE_NULL) self.player = SmartCaptureBin(audiodevice=adev, videodevice=vdev) self.setSinks() # FIXME : check for state change failures self.player.set_state(gst.STATE_PLAYING) def _resetPlayer(self): ## call me in another thread ! gst.debug("Setting previous to NULL") self.player.set_state(gst.STATE_NULL) gst.debug("Creating new SmartCaptureBin(%r,%r)" % (self._audiodev, self._videodev)) self.player = SmartCaptureBin(audiodevice = self._audiodev, videodevice = self._videodev) gst.debug("Calling setSinks()") self.setSinks() gst.debug("Finally setting to PLAYING...") res = self.player.set_state(gst.STATE_PLAYING) gst.debug("... which returned %r" % res) def _changeSelectedCombo(self, combo, device): gst.debug("device %r" % device) model = combo.get_model() idx = 0 for name, dev in model: if dev == device: break idx += 1 combo.set_active(idx) def _changeSelectedAudio(self, device): self._audiodev = device self._changeSelectedCombo(self._adevcombo, device) def _changeSelectedVideo(self, device): self._videodev = device self._changeSelectedCombo(self._vdevcombo, device) def _deviceAddedCb(self, probe, device): gst.debug("device %r appeared" % device) self._updateAudioCombo() self._updateVideoCombo() def _deviceRemovedCb(self, probe, device): gst.debug("device %r went away" % device) if self._audiodev == device: devs = self.pitivi.deviceprobe.getAudioSourceDevices() if len(devs): self._changeSelectedAudio(devs[0]) else: self._audiodev = None elif self._videodev == device: devs = self.pitivi.deviceprobe.getVideoSourceDevices() if len(devs): self._changeSelectedVideo(devs[0]) else: self._videodev = None self._updateAudioCombo() self._updateVideoCombo() def _updateCombo(self, combo, devices): model = combo.get_model() if len(devices) == len(model): # nothing changed return model.clear() for dev in devices: model.append([dev.name, dev]) def _updateAudioCombo(self): self._updateCombo(self._adevcombo, self.pitivi.deviceprobe.getAudioSourceDevices()) self._changeSelectedAudio(self._audiodev) def _updateVideoCombo(self): self._updateCombo(self._vdevcombo, self.pitivi.deviceprobe.getVideoSourceDevices()) self._changeSelectedVideo(self._videodev) def _adevComboChangedCb(self, widget): # get the active device row = widget.get_model()[widget.get_active()] if len(row) < 2: return dev = row[1] gst.debug("device %r" % dev) if dev == self._audiodev: return self._changeSelectedAudio(dev) if not hasattr(self, "player"): return CallbackThread(self._resetPlayer).start() def _vdevComboChangedCb(self, widget): row = widget.get_model()[widget.get_active()] if len(row) < 2: return dev = row[1] gst.debug("device %r" % dev) if dev == self._videodev: return self._changeSelectedVideo(dev) if not hasattr(self, "player"): return CallbackThread(self._resetPlayer).start()
class Project(Signallable, Loggable): """The base class for PiTiVi projects @ivar name: The name of the project @type name: C{str} @ivar description: A description of the project @type description: C{str} @ivar sources: The sources used by this project @type sources: L{SourceList} @ivar timeline: The timeline @type timeline: L{Timeline} @ivar pipeline: The timeline's pipeline @type pipeline: L{Pipeline} @ivar factory: The timeline factory @type factory: L{TimelineSourceFactory} @ivar format: The format under which the project is currently stored. @type format: L{FormatterClass} @ivar loaded: Whether the project is fully loaded or not. @type loaded: C{bool} Signals: - C{loaded} : The project is now fully loaded. """ __signals__ = { "settings-changed": ['old', 'new'], "project-changed": [], } def __init__(self, name="", uri=None, **kwargs): """ @param name: the name of the project @param uri: the uri of the project """ Loggable.__init__(self) self.log("name:%s, uri:%s", name, uri) self.name = name self.settings = None self.description = "" self.uri = uri self.urichanged = False self.format = None self.sources = SourceList() self.sources.connect("source-added", self._sourceAddedCb) self.sources.connect("source-removed", self._sourceRemovedCb) self._dirty = False self.timeline = Timeline() self.factory = TimelineSourceFactory(self.timeline) self.pipeline = Pipeline() self.view_action = ViewAction() self.view_action.addProducers(self.factory) self.seeker = Seeker(80) self.settings = ExportSettings() self._videocaps = self.settings.getVideoCaps() def release(self): self.pipeline.release() self.pipeline = None #{ Settings methods def getSettings(self): """ return the currently configured settings. """ self.debug("self.settings %s", self.settings) return self.settings def setSettings(self, settings): """ Sets the given settings as the project's settings. @param settings: The new settings for the project. @type settings: ExportSettings """ assert settings self.log("Setting %s as the project's settings", settings) oldsettings = self.settings self.settings = settings self._projectSettingsChanged() self.emit('settings-changed', oldsettings, settings) #} #{ Save and Load features def setModificationState(self, state): self._dirty = state if state: self.emit('project-changed') def hasUnsavedModifications(self): return self._dirty def _projectSettingsChanged(self): settings = self.getSettings() self._videocaps = settings.getVideoCaps() if self.timeline: self.timeline.updateVideoCaps(self._videocaps) for fact in self.sources.getSources(): fact.setFilterCaps(self._videocaps) if self.pipeline.getState() != gst.STATE_NULL: self.pipeline.stop() self.pipeline.pause() def _sourceAddedCb(self, sourcelist, factory): factory.setFilterCaps(self._videocaps) def _sourceRemovedCb(self, sourclist, uri, factory): self.timeline.removeFactory(factory)
class Project(Signallable, Loggable): """The base class for PiTiVi projects @ivar name: The name of the project @type name: C{str} @ivar description: A description of the project @type description: C{str} @ivar sources: The sources used by this project @type sources: L{SourceList} @ivar timeline: The timeline @type timeline: L{Timeline} @ivar pipeline: The timeline's pipeline @type pipeline: L{Pipeline} @ivar factory: The timeline factory @type factory: L{TimelineSourceFactory} @ivar format: The format under which the project is currently stored. @type format: L{FormatterClass} @ivar loaded: Whether the project is fully loaded or not. @type loaded: C{bool} Signals: - C{loaded} : The project is now fully loaded. """ __signals__ = { "settings-changed": None, } def __init__(self, name="", uri=None, **kwargs): """ name : the name of the project uri : the uri of the project """ Loggable.__init__(self) self.log("name:%s, uri:%s", name, uri) self.name = name self.settings = None self.description = "" self.uri = uri self.urichanged = False self.format = None self.sources = SourceList() self.sources.connect("source-removed", self._sourceRemovedCb) self.settingssigid = 0 self._dirty = False self.timeline = Timeline() self.factory = TimelineSourceFactory(self.timeline) self.pipeline = Pipeline() self.view_action = ViewAction() self.view_action.addProducers(self.factory) def release(self): self.pipeline.release() self.pipeline = None #{ Settings methods def _settingsChangedCb(self, unused_settings): self.emit('settings-changed') def getSettings(self): """ return the currently configured settings. If no setting have been explicitely set, some smart settings will be chosen. """ self.debug("self.settings %s", self.settings) return self.settings or self.getAutoSettings() def setSettings(self, settings): """ Sets the given settings as the project's settings. If settings is None, the current settings will be unset """ self.log("Setting %s as the project's settings", settings) if self.settings: self.settings.disconnect(self.settingssigid) self.settings = settings self.emit('settings-changed') self.settingssigid = self.settings.connect('settings-changed', self._settingsChangedCb) def unsetSettings(self, unused_settings): """ Remove the currently configured settings.""" self.setSettings(None) def getAutoSettings(self): """ Computes and returns smart settings for the project. If the project only has one source, it will be that source's settings. If it has more than one, it will return the largest setting that suits all contained sources. """ settings = ExportSettings() if not self.timeline: self.warning( "project doesn't have a timeline, returning default settings") return settings # FIXME: this is ugly, but rendering for now assumes at most one audio # and one video tracks have_audio = have_video = False for track in self.timeline.tracks: if isinstance(track.stream, VideoStream) and track.duration != 0: have_video = True elif isinstance(track.stream, AudioStream) and track.duration != 0: have_audio = True if not have_audio: settings.aencoder = None if not have_video: settings.vencoder = None return settings #} #{ Save and Load features def save(self, location=None, overwrite=False): """ Save the project to the given location. @param location: The location to write to. If not specified, the current project location will be used (if set). @type location: C{URI} @param overwrite: Whether to overwrite existing location. @type overwrite: C{bool} """ # import here to break circular import from pitivi.formatters.format import save_project from pitivi.formatters.base import FormatterError self.log("saving...") location = location or self.uri if location == None: raise FormatterError("Location unknown") save_project(self, location or self.uri, self.format, overwrite) self.uri = location def setModificationState(self, state): self._dirty = state def hasUnsavedModifications(self): return self._dirty def _sourceRemovedCb(self, sourclist, uri, factory): self.timeline.removeFactory(factory)