From ecc8ede82ef594a7186e7e597ee9ded823616e59 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Fri, 06 May 2011 17:32:54 +0000 Subject: Fix audio recording when no camera present (SL#2691) Introduce the relevant code catches to allow audio recording when no camera is present. Still has some rough edges but is now usable at least. --- diff --git a/button.py b/button.py index e3bcdc6..66cf80b 100644 --- a/button.py +++ b/button.py @@ -53,7 +53,8 @@ class RecdButton(TrayButton): path = 'object-audio.svg' pixbuf = utils.load_colored_svg(path, self._recd.colorStroke, self._recd.colorFill) - ipb.composite(pixbuf, 8, 8, ipb.get_width(), ipb.get_height(), 8, 8, 1, 1, gtk.gdk.INTERP_BILINEAR, 255) + if ipb: + ipb.composite(pixbuf, 8, 8, ipb.get_width(), ipb.get_height(), 8, 8, 1, 1, gtk.gdk.INTERP_BILINEAR, 255) img.set_from_pixbuf(pixbuf) img.show() return img diff --git a/gfx/stub.png b/gfx/stub.png deleted file mode 100644 index 42e593f..0000000 --- a/gfx/stub.png +++ /dev/null Binary files differ diff --git a/glive.py b/glive.py index 07d187b..6464089 100644 --- a/glive.py +++ b/glive.py @@ -42,9 +42,6 @@ OGG_TRAITS = { 0: { 'width': 160, 'height': 120, 'quality': 16 }, 1: { 'width': 400, 'height': 300, 'quality': 16 } } -THUMB_STUB = gtk.gdk.pixbuf_new_from_file( - os.path.join(get_bundle_path(), 'gfx', 'stub.png')) - class Glive: PHOTO_MODE_PHOTO = 0 PHOTO_MODE_AUDIO = 1 @@ -222,6 +219,9 @@ class Glive: scaps.set_property("caps", gst.Caps("video/x-raw-yuv,width=%d,height=%d" % (width, height))) def _create_pipeline(self): + if not self._has_camera: + return + src = gst.element_factory_make("v4l2src", "camsrc") try: # old gst-plugins-good does not have this property @@ -313,20 +313,18 @@ class Glive: return self._xbin.get_by_name("xsink") def play(self, use_xv=True): - if not self._has_camera: - return - if self._get_state() == gst.STATE_PLAYING: return - if use_xv and self._xv_available: - xsink = self._configure_xv() - else: - xsink = self._configure_x() + if self._has_camera: + if use_xv and self._xv_available: + xsink = self._configure_xv() + else: + xsink = self._configure_x() - # X overlay must be set every time, it seems to forget when you stop - # the pipeline. - self.activity.set_glive_sink(xsink) + # X overlay must be set every time, it seems to forget when you stop + # the pipeline. + self.activity.set_glive_sink(xsink) self._pipeline.set_state(gst.STATE_PLAYING) self._playing = True @@ -355,23 +353,23 @@ class Glive: self._pipeline.remove(self._audiobin) self.play() - if not self._audio_pixbuf: - # FIXME: inform model of failure? - return - audio_path = os.path.join(Instance.instancePath, "output.wav") if not os.path.exists(audio_path) or os.path.getsize(audio_path) <= 0: # FIXME: inform model of failure? return - self.model.still_ready(self._audio_pixbuf) + if self._audio_pixbuf: + self.model.still_ready(self._audio_pixbuf) line = 'filesrc location=' + audio_path + ' name=audioFilesrc ! wavparse name=audioWavparse ! audioconvert name=audioAudioconvert ! vorbisenc name=audioVorbisenc ! oggmux name=audioOggmux ! filesink name=audioFilesink' audioline = gst.parse_launch(line) taglist = self._get_tags(constants.TYPE_AUDIO) - pixbuf_b64 = utils.getStringFromPixbuf(self._audio_pixbuf) - taglist[gst.TAG_EXTENDED_COMMENT] = "coverart=" + pixbuf_b64 + + if self._audio_pixbuf: + pixbuf_b64 = utils.getStringFromPixbuf(self._audio_pixbuf) + taglist[gst.TAG_EXTENDED_COMMENT] = "coverart=" + pixbuf_b64 + vorbis_enc = audioline.get_by_name('audioVorbisenc') vorbis_enc.merge_tags(taglist, gst.TAG_MERGE_REPLACE_ALL) @@ -465,8 +463,9 @@ class Glive: self.play() def record_audio(self): - self._audio_pixbuf = None - self._take_photo(self.PHOTO_MODE_AUDIO) + if self._has_camera: + self._audio_pixbuf = None + self._take_photo(self.PHOTO_MODE_AUDIO) # we should be able to add the audiobin on the fly, but unfortunately # this results in several seconds of silence being added at the start diff --git a/mediaview.py b/mediaview.py index 670a0fa..01567ff 100644 --- a/mediaview.py +++ b/mediaview.py @@ -215,12 +215,14 @@ class ImageBox(gtk.EventBox): self._pixbuf = pixbuf def set_size(self, width, height): - if width == self._pixbuf.get_width() and height == self._pixbuf.get_height(): - pixbuf = self._pixbuf - else: - pixbuf = self._pixbuf.scale_simple(width, height, gdk.INTERP_BILINEAR) + if self._pixbuf: + if width == self._pixbuf.get_width() and height == self._pixbuf.get_height(): + pixbuf = self._pixbuf + else: + pixbuf = self._pixbuf.scale_simple(width, height, gdk.INTERP_BILINEAR) + + self._image.set_from_pixbuf(pixbuf) - self._image.set_from_pixbuf(pixbuf) self._image.set_size_request(width, height) self.set_size_request(width, height) @@ -492,8 +494,9 @@ class MediaView(gtk.EventBox): self._switch_mode(MediaView.MODE_STILL) def show_photo(self, path): - pixbuf = gdk.pixbuf_new_from_file(path) - self._image_box.set_pixbuf(pixbuf) + if path: + pixbuf = gdk.pixbuf_new_from_file(path) + self._image_box.set_pixbuf(pixbuf) self._switch_mode(MediaView.MODE_PHOTO) def show_video(self): diff --git a/model.py b/model.py index e6c90c9..7ce2bc1 100644 --- a/model.py +++ b/model.py @@ -130,7 +130,7 @@ class Model: # if we aren't using Xv (e.g. glive is playing as PIP in video # mode), then stop the pipeline so that we switch back to Xv # in the call that follows. - if not self.glive.is_using_xv(): + if self.glive.get_has_camera() and not self.glive.is_using_xv(): self.glive.stop() self.glive.play() @@ -248,9 +248,8 @@ class Model: imgpath = os.path.join(Instance.instancePath, recd.mediaFilename) pixbuf.save(imgpath, "jpeg") - thumbpath = os.path.join(Instance.instancePath, recd.thumbFilename) pixbuf = utils.generate_thumbnail(pixbuf) - pixbuf.save(thumbpath, "png") + pixbuf.save(recd.make_thumb_path(), "png") #now that we've saved both the image and its pixbuf, we get their md5s self.createNewRecordedMd5Sums( recd ) @@ -263,9 +262,8 @@ class Model: recd = self.createNewRecorded(constants.TYPE_VIDEO) os.rename(path, os.path.join(Instance.instancePath, recd.mediaFilename)) - thumb_path = os.path.join(Instance.instancePath, recd.thumbFilename) still = utils.generate_thumbnail(still) - still.save(thumb_path, "png") + still.save(recd.make_thumb_path(), "png") self.createNewRecordedMd5Sums( recd ) @@ -276,14 +274,14 @@ class Model: recd = self.createNewRecorded(constants.TYPE_AUDIO) os.rename(path, os.path.join(Instance.instancePath, recd.mediaFilename)) - image_path = os.path.join(Instance.instancePath, "audioPicture.png") - image_path = utils.getUniqueFilepath(image_path, 0) - still.save(image_path, "png") - recd.audioImageFilename = os.path.basename(image_path) + if still: + image_path = os.path.join(Instance.instancePath, "audioPicture.png") + image_path = utils.getUniqueFilepath(image_path, 0) + still.save(image_path, "png") + recd.audioImageFilename = os.path.basename(image_path) - thumb_path = os.path.join(Instance.instancePath, recd.thumbFilename) - still = utils.generate_thumbnail(still) - still.save(thumb_path, "png") + still = utils.generate_thumbnail(still) + still.save(recd.make_thumb_path(), "png") self.createNewRecordedMd5Sums( recd ) @@ -350,11 +348,6 @@ class Model: mediaFilepath = utils.getUniqueFilepath( mediaFilepath, 0 ) recd.mediaFilename = os.path.basename( mediaFilepath ) - thumbFilename = mediaThumbFilename + "_thumb.jpg" - thumbFilepath = os.path.join( Instance.instancePath, thumbFilename ) - thumbFilepath = utils.getUniqueFilepath( thumbFilepath, 0 ) - recd.thumbFilename = os.path.basename( thumbFilepath ) - stringType = constants.MEDIA_INFO[type]['istr'] # Translators: photo by photographer, e.g. "Photo by Mary" @@ -364,16 +357,16 @@ class Model: recd.colorStroke = color.get_stroke_color() recd.colorFill = color.get_fill_color() - logger.debug('createNewRecorded: ' + str(recd) + ", thumbFilename:" + str(recd.thumbFilename)) + logger.debug('createNewRecorded: ' + str(recd)) return recd def createNewRecordedMd5Sums( self, recd ): recd.thumbMd5 = recd.mediaMd5 = str(uuid.uuid4()) #load the thumbfile - thumbFile = os.path.join(Instance.instancePath, recd.thumbFilename) - tBytes = os.stat(thumbFile)[6] - recd.thumbBytes = tBytes + if recd.thumbFilename: + thumbFile = os.path.join(Instance.instancePath, recd.thumbFilename) + recd.thumbBytes = os.stat(thumbFile)[6] recd.tags = "" @@ -396,7 +389,7 @@ class Model: os.remove(mediaFile) thumbFile = recd.getThumbFilepath() - if os.path.exists(thumbFile): + if thumbFile and os.path.exists(thumbFile): os.remove(thumbFile) else: #remove from the datastore here, since once gone, it is gone... diff --git a/recorded.py b/recorded.py index 27250d3..9296742 100644 --- a/recorded.py +++ b/recorded.py @@ -106,20 +106,28 @@ class Recorded: def getThumbPixbuf( self ): thumbFilepath = self.getThumbFilepath() - if os.path.isfile(thumbFilepath): + if thumbFilepath and os.path.isfile(thumbFilepath): return gtk.gdk.pixbuf_new_from_file(thumbFilepath) else: return None def getThumbFilepath( self ): + if not self.thumbFilename: + return None return os.path.join(Instance.instancePath, self.thumbFilename) + def make_thumb_path(self): + thumbFilename = self.mediaFilename + "_thumb.jpg" + thumbFilepath = os.path.join(Instance.instancePath, thumbFilename) + thumbFilepath = utils.getUniqueFilepath(thumbFilepath, 0) + self.thumbFilename = os.path.basename(thumbFilepath) + return self.getThumbFilepath() def getAudioImagePixbuf( self ): audioPixbuf = None - if (self.audioImageFilename == None): + if self.audioImageFilename == None: audioPixbuf = self.getThumbPixbuf() else: audioFilepath = self.getAudioImageFilepath() diff --git a/serialize.py b/serialize.py index 82618fc..687bbaa 100644 --- a/serialize.py +++ b/serialize.py @@ -162,8 +162,9 @@ def _addRecdXmlAttrs(el, recd, forMeshTransmit): if (recd.type == constants.TYPE_AUDIO) and (not forMeshTransmit): aiPixbuf = recd.getAudioImagePixbuf() - aiPixbufString = str(utils.getStringFromPixbuf(aiPixbuf)) - el.setAttribute('audioImage', aiPixbufString) + if aiPixbuf: + aiPixbufString = str(utils.getStringFromPixbuf(aiPixbuf)) + el.setAttribute('audioImage', aiPixbufString) if (recd.datastoreId != None) and (not forMeshTransmit): el.setAttribute('datastoreId', str(recd.datastoreId)) @@ -178,15 +179,18 @@ def _addRecdXmlAttrs(el, recd, forMeshTransmit): el.setAttribute('mediaMd5', str(recd.mediaMd5)) el.setAttribute('thumbMd5', str(recd.thumbMd5)) el.setAttribute('mediaBytes', str(recd.mediaBytes)) - el.setAttribute('thumbBytes', str(recd.thumbBytes)) + + if recd.thumbBytes: + el.setAttribute('thumbBytes', str(recd.thumbBytes)) # FIXME: can this be removed, or at least autodetected? has not been # changed for ages, should not be relevant el.setAttribute('version', '54') pixbuf = recd.getThumbPixbuf() - thumb64 = str(utils.getStringFromPixbuf(pixbuf)) - el.setAttribute('base64Thumb', thumb64) + if pixbuf: + thumb64 = str(utils.getStringFromPixbuf(pixbuf)) + el.setAttribute('base64Thumb', thumb64) def saveMediaHash(mediaHashs, activity): impl = getDOMImplementation() @@ -222,10 +226,7 @@ def _saveMedia(el, recd, activity): _saveMediaToDatastore(el, recd, activity) def _saveXml(el, recd): - if recd.thumbFilename: - _addRecdXmlAttrs(el, recd, False) - else: - logger.debug("WOAH, ERROR: recd has no thumbFilename?! " + str(recd) ) + _addRecdXmlAttrs(el, recd, False) recd.savedXml = True def _saveMediaToDatastore(el, recd, activity): @@ -265,13 +266,14 @@ def _saveMediaToDatastore(el, recd, activity): datastorePreviewFilepath = recd.getMediaFilepath() datastorePreviewPixbuf = gtk.gdk.pixbuf_new_from_file(datastorePreviewFilepath) - datastorePreviewWidth = 300 - datastorePreviewHeight = 225 - if datastorePreviewPixbuf.get_width() != datastorePreviewWidth: - datastorePreviewPixbuf = datastorePreviewPixbuf.scale_simple(datastorePreviewWidth, datastorePreviewHeight, gtk.gdk.INTERP_NEAREST) + if datastorePreviewPixbuf: + datastorePreviewWidth = 300 + datastorePreviewHeight = 225 + if datastorePreviewPixbuf.get_width() != datastorePreviewWidth: + datastorePreviewPixbuf = datastorePreviewPixbuf.scale_simple(datastorePreviewWidth, datastorePreviewHeight, gtk.gdk.INTERP_NEAREST) - datastorePreviewBase64 = utils.getStringFromPixbuf(datastorePreviewPixbuf) - mediaObject.metadata['preview'] = datastorePreviewBase64 + datastorePreviewBase64 = utils.getStringFromPixbuf(datastorePreviewPixbuf) + mediaObject.metadata['preview'] = datastorePreviewBase64 colors = str(recd.colorStroke) + "," + str(recd.colorFill) mediaObject.metadata['icon-color'] = colors -- cgit v0.9.1