Hey Guys, I was hoping to get more work done on this but haven't had the chance to work on it any further. This patch switches Record to use the WebM video format as specified by google. It should work on our F14 builds. The videos will playback in Record, but you will have to patch your mimetypes files to add support to other programs. In particular you should add video/webm to the /usr/share/sugar/data/mime.defaults file.
I do know that one thing that needs to be fixed is the preview image shown while the recording is being encoded is displayed in greyscale instead of color. Other than that I am quite happy with the recording quality. You will still notice an audio hiccup at between 14 and 20 seconds of the start of the recording. This is where we would previously lose audio sync. With this patch the sync re-adjusts itself but leaves a small hiccup in the audio track. Hope this is useful to someone. -Jon
From 42c66aaf17686be5b5320698c7d258e11164812d Mon Sep 17 00:00:00 2001 From: Jon Nettleton <[email protected]> Date: Fri, 8 Apr 2011 05:50:25 -0700 Subject: [PATCH] Convert to using WebM video format This switches Record to use vp8 video and ogg audio in a matroska container. This is the standard that makes up the WebM video format. The encoder quality and performance seems to be better than the existing ogg/theora combination. --- constants.py | 4 +- glive.py | 59 +++++++++++++++++++++++++++++---------------------------- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/constants.py b/constants.py index 9b0ed4a..2381029 100644 --- a/constants.py +++ b/constants.py @@ -26,8 +26,8 @@ MEDIA_INFO[TYPE_PHOTO] = { MEDIA_INFO[TYPE_VIDEO] = { 'name' : 'video', - 'mime' : 'video/ogg', - 'ext' : 'ogg', + 'mime' : 'video/webm', + 'ext' : 'webm', 'istr' : _('Video') } diff --git a/glive.py b/glive.py index 07d187b..14288cf 100644 --- a/glive.py +++ b/glive.py @@ -38,9 +38,9 @@ import utils logger = logging.getLogger('glive') -OGG_TRAITS = { - 0: { 'width': 160, 'height': 120, 'quality': 16 }, - 1: { 'width': 400, 'height': 300, 'quality': 16 } } +WEBM_TRAITS = { + 0: { 'width': 160, 'height': 120, 'quality': 5 }, + 1: { 'width': 400, 'height': 300, 'quality': 5 } } THUMB_STUB = gtk.gdk.pixbuf_new_from_file( os.path.join(get_bundle_path(), 'gfx', 'stub.png')) @@ -180,13 +180,14 @@ class Glive: colorspace = gst.element_factory_make("ffmpegcolorspace", "vbcolorspace") - enc = gst.element_factory_make("theoraenc", "vbenc") - enc.set_property("quality", 16) + enc = gst.element_factory_make("vp8enc", "vbenc") + enc.set_property("quality", 5) + enc.set_property("speed", 2) - mux = gst.element_factory_make("oggmux", "vbmux") + mux = gst.element_factory_make("matroskamux", "vbmux") sink = gst.element_factory_make("filesink", "vbfile") - sink.set_property("location", os.path.join(Instance.instancePath, "output.ogg")) + sink.set_property("location", os.path.join(Instance.instancePath, "output.webm")) self._videobin = gst.Bin("videobin") self._videobin.add(queue, scale, scalecapsfilter, colorspace, enc, mux, sink) @@ -217,7 +218,7 @@ class Glive: def _config_videobin(self, quality, width, height): vbenc = self._videobin.get_by_name("vbenc") - vbenc.set_property("quality", 16) + vbenc.set_property("quality", 5) scaps = self._videobin.get_by_name("scalecaps") scaps.set_property("caps", gst.Caps("video/x-raw-yuv,width=%d,height=%d" % (width, height))) @@ -366,7 +367,7 @@ class Glive: 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' + line = 'filesrc location=' + audio_path + ' name=audioFilesrc ! wavparse name=audioWavparse ! audioconvert name=audioAudioconvert ! vorbisenc name=audioVorbisenc ! matroskamux name=audioOggmux ! filesink name=audioFilesink' audioline = gst.parse_launch(line) taglist = self._get_tags(constants.TYPE_AUDIO) @@ -376,7 +377,7 @@ class Glive: vorbis_enc.merge_tags(taglist, gst.TAG_MERGE_REPLACE_ALL) audioFilesink = audioline.get_by_name('audioFilesink') - audioOggFilepath = os.path.join(Instance.instancePath, "output.ogg") + audioOggFilepath = os.path.join(Instance.instancePath, "output.webm") audioFilesink.set_property("location", audioOggFilepath) audioBus = audioline.get_bus() @@ -448,10 +449,10 @@ class Glive: if not self._has_camera: return - self._ogg_quality = quality - self._config_videobin(OGG_TRAITS[quality]['quality'], - OGG_TRAITS[quality]['width'], - OGG_TRAITS[quality]['height']) + self._webm_quality = quality + self._config_videobin(WEBM_TRAITS[quality]['quality'], + WEBM_TRAITS[quality]['width'], + WEBM_TRAITS[quality]['height']) # If we use pad blocking and adjust the pipeline on-the-fly, the # resultant video has bad A/V sync :( @@ -501,12 +502,12 @@ class Glive: thumbline = self._thumb_pipes[-1] thumbline.get_by_name('thumb_fakesink').disconnect(self._thumb_handoff_handler) - ogg_path = os.path.join(Instance.instancePath, "output.ogg") #ogv - if not os.path.exists(ogg_path) or os.path.getsize(ogg_path) <= 0: + webm_path = os.path.join(Instance.instancePath, "output.webm") #ogv + if not os.path.exists(webm_path) or os.path.getsize(webm_path) <= 0: # FIXME: inform model of failure? return - line = 'filesrc location=' + ogg_path + ' name=thumbFilesrc ! oggdemux name=thumbOggdemux ! theoradec name=thumbTheoradec ! tee name=thumb_tee ! queue name=thumb_queue ! ffmpegcolorspace name=thumbFfmpegcolorspace ! jpegenc name=thumbJPegenc ! fakesink name=thumb_fakesink' + line = 'filesrc location=' + webm_path + ' name=thumbFilesrc ! matroskademux name=thumbOggdemux ! vp8dec name=thumbTheoradec ! tee name=thumb_tee ! queue name=thumb_queue ! ffmpegcolorspace name=thumbFfmpegcolorspace ! jpegenc name=thumbJPegenc ! fakesink name=thumb_fakesink' thumbline = gst.parse_launch(line) thumb_queue = thumbline.get_by_name('thumb_queue') thumb_queue.set_property("leaky", True) @@ -532,11 +533,11 @@ class Glive: self._thumb_element('thumb_tee').unlink(self._thumb_element('thumb_queue')) - oggFilepath = os.path.join(Instance.instancePath, "output.ogg") #ogv + webmFilepath = os.path.join(Instance.instancePath, "output.webm") #ogv wavFilepath = os.path.join(Instance.instancePath, "output.wav") - muxFilepath = os.path.join(Instance.instancePath, "mux.ogg") #ogv + muxFilepath = os.path.join(Instance.instancePath, "mux.webm") #ogv - muxline = gst.parse_launch('filesrc location=' + str(oggFilepath) + ' name=muxVideoFilesrc ! oggdemux name=muxOggdemux ! theoraparse ! oggmux name=muxOggmux ! filesink location=' + str(muxFilepath) + ' name=muxFilesink filesrc location=' + str(wavFilepath) + ' name=muxAudioFilesrc ! wavparse name=muxWavparse ! audioconvert name=muxAudioconvert ! vorbisenc name=muxVorbisenc ! muxOggmux.') + muxline = gst.parse_launch('filesrc location=' + str(webmFilepath) + ' name=muxVideoFilesrc ! matroskademux name=muxMatroskademux ! matroskamux name=muxMatroskamux ! filesink location=' + str(muxFilepath) + ' name=muxFilesink filesrc location=' + str(wavFilepath) + ' name=muxAudioFilesrc ! wavparse name=muxWavparse ! audioconvert name=muxAudioconvert ! vorbisenc name=muxVorbisenc ! muxMatroskamux.') taglist = self._get_tags(constants.TYPE_VIDEO) vorbis_enc = muxline.get_by_name('muxVorbisenc') vorbis_enc.merge_tags(taglist, gst.TAG_MERGE_REPLACE_ALL) @@ -583,10 +584,10 @@ class Glive: pipe.get_bus().disable_sync_message_emission() wavFilepath = os.path.join(Instance.instancePath, "output.wav") - oggFilepath = os.path.join(Instance.instancePath, "output.ogg") #ogv - muxFilepath = os.path.join(Instance.instancePath, "mux.ogg") #ogv + webmFilepath = os.path.join(Instance.instancePath, "output.webm") #ogv + muxFilepath = os.path.join(Instance.instancePath, "mux.webm") #ogv os.remove( wavFilepath ) - os.remove( oggFilepath ) + os.remove( webmFilepath ) self.model.save_video(muxFilepath, self.thumbBuf) return False @@ -603,9 +604,9 @@ class Glive: pipe.get_bus().disable_sync_message_emission() wavFilepath = os.path.join(Instance.instancePath, "output.wav") - oggFilepath = os.path.join(Instance.instancePath, "output.ogg") + webmFilepath = os.path.join(Instance.instancePath, "output.webm") os.remove( wavFilepath ) - self.model.save_audio(oggFilepath, self._audio_pixbuf) + self.model.save_audio(webmFilepath, self._audio_pixbuf) return False def _bus_message_handler(self, bus, message): @@ -637,10 +638,10 @@ class Glive: wav_path = os.path.join(Instance.instancePath, "output.wav") if os.path.exists(wav_path): os.remove(wav_path) - ogg_path = os.path.join(Instance.instancePath, "output.ogg") #ogv - if os.path.exists(ogg_path): - os.remove(ogg_path) - mux_path = os.path.join(Instance.instancePath, "mux.ogg") #ogv + webm_path = os.path.join(Instance.instancePath, "output.webm") #ogv + if os.path.exists(webm_path): + os.remove(webm_path) + mux_path = os.path.join(Instance.instancePath, "mux.webm") #ogv if os.path.exists(mux_path): os.remove(mux_path) -- 1.7.4.2
_______________________________________________ Devel mailing list [email protected] http://lists.laptop.org/listinfo/devel
