diff options
author | Ariel Calzada <ariel@activitycentral.com> | 2012-10-01 11:49:38 (GMT) |
---|---|---|
committer | Ariel Calzada <ariel@activitycentral.com> | 2012-10-01 11:49:38 (GMT) |
commit | 09fd878f7712eb6163e7e75a9aadc14aaa76695f (patch) | |
tree | 002bd6b14cce5a6b184eaab53435553236c045da | |
parent | 3f5f9fcc0d201b51a9562e0f253519bafb85d8d1 (diff) |
Initial import
-rw-r--r-- | DesktopGrab.py | 320 | ||||
-rwxr-xr-x | recordmydesktop | bin | 92532 -> 0 bytes | |||
-rw-r--r-- | screencast_activity.py | 70 |
3 files changed, 365 insertions, 25 deletions
diff --git a/DesktopGrab.py b/DesktopGrab.py new file mode 100644 index 0000000..6bf4f81 --- /dev/null +++ b/DesktopGrab.py @@ -0,0 +1,320 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +''' +Model: + gst-launch-0.10 ximagesrc startx=0 endx=1200 starty=0 endy=900 ! \ + ffmpegcolorspace ! \ + videoscale ! \ + video/x-raw-yuv,width=320,height=240 ! \ + theoraenc ! \ + queue max-size-buffers=10000 max-size-bytes=0 max-size-time=0 ! \ + mux. oggmux name=mux \ + alsasrc ! \ + audio/x-raw-int,width=16,depth=16,rate=8000,channels=1 ! \ + audioconvert ! \ + vorbisenc ! \ + queue max-size-buffers=10000 max-size-bytes=0 max-size-time=0 ! \ + mux. mux. ! \ + filesink location=file.ogg +''' + +import sys +import os +import gtk +import gobject +import gst +import pygst +import time +import datetime + +gobject.threads_init() +gtk.gdk.threads_init() + +class DesktopGrab(gtk.Widget): + """Simple Grabador de Escritorio, Versión 2.0 + + def set_audio_enabled(self, valor) + Habilita/deshabilita el audio en la grabación. + + set_video_quality(self, resolucion) + Configura calidad de video final. + + def record(self, location_path) + Graba. + + def stop(self) + Detiene la grabación.""" + + __gsignals__ = { + "update":(gobject.SIGNAL_RUN_FIRST, + gobject.TYPE_NONE, (gobject.TYPE_STRING,))} + + def __init__(self): + + gtk.Widget.__init__(self) + + self.resolution = "video/x-raw-yuv,width=640,height=480" # 800x600 640x480 320x240 + + self.pipeline = None + self.update = None + self.file_path = None + self.enabled_sound = True + self.info = None + + # Video + self.ximagesrc = None + self.ffmpegcolorspace = None + self.videoscale = None + self.video_filter = None + self.theoraenc = None + self.queue_video = None + + # Sound + self.alsasrc = None + self.sound_filter = None + self.audioconvert = None + self.vorbisenc = None + self.queue_sound = None + self.oggmux = None + self.file = None + self.bus = None + + self.x = 0 + self.y = 0 + self.width = int(gtk.gdk.screen_width()) + self.height = int(gtk.gdk.screen_height()) + + def set_pipeline(self): + """Crea el pipe para grabar desde x y autoaudio.""" + + if self.pipeline: + del(self.pipeline) + self.pipeline = None + + self.pipeline = gst.Pipeline("player") + + # Video + self.ximagesrc = gst.element_factory_make('ximagesrc', "x11") + self.ximagesrc.set_property('startx', self.x) + self.ximagesrc.set_property('endx', self.width) + self.ximagesrc.set_property('starty', self.y) + self.ximagesrc.set_property('endy', self.height) + self.ffmpegcolorspace = gst.element_factory_make('ffmpegcolorspace', "ffmpegcolorspace") + self.videoscale = gst.element_factory_make("videoscale", "videoscale") + self.video_filter = gst.element_factory_make("capsfilter", "video_filter") + video_caps = gst.Caps(self.resolution) + self.video_filter.set_property("caps", video_caps) + self.theoraenc = gst.element_factory_make('theoraenc', 'theoraenc') + self.queue_video = gst.element_factory_make('queue', "queue_video") + self.queue_video.set_property('max-size-buffers', 10000) + self.queue_video.set_property('max-size-bytes', 0) + self.queue_video.set_property('max-size-time', 0) + + # Sound + self.alsasrc = gst.element_factory_make('alsasrc', "alsasrc") + sound_caps = gst.Caps("audio/x-raw-int,width=16,depth=16,rate=8000,channels=1") + self.sound_filter = gst.element_factory_make("capsfilter", "sound_filter") + self.sound_filter.set_property("caps", sound_caps) + self.audioconvert = gst.element_factory_make('audioconvert', "audioconvert") + self.vorbisenc = gst.element_factory_make('vorbisenc', "vorbisenc") + self.queue_sound = gst.element_factory_make('queue', "queue_sound") + self.queue_sound.set_property('max-size-buffers', 10000) + self.queue_sound.set_property('max-size-bytes', 0) + self.queue_sound.set_property('max-size-time', 0) + + self.oggmux = gst.element_factory_make('oggmux', "oggmux") + + self.file = gst.element_factory_make('filesink', "file") + self.file.set_property("location", self.file_path) + + if self.enabled_sound: + self.add_todos() + self.link_todos() + else: + self.add_solo_video() + self.link_solo_video() + + self.bus = self.pipeline.get_bus() + self.bus.enable_sync_message_emission() + self.bus.add_signal_watch() + self.bus.connect("sync-message::element", self.on_sync_message) + self.bus.connect("message", self.on_message) + + def link_solo_video(self): + """Linkea solo los elementos de video y archivo, no de audio.""" + + gst.element_link_many( + self.ximagesrc, + self.ffmpegcolorspace, + self.videoscale, + self.video_filter, + self.theoraenc, + self.queue_video, + self.oggmux, + self.file) + + def link_todos(self): + """Linkea todos los elementos del pipe, de audio, video y archivo.""" + + gst.element_link_many( + self.ximagesrc, + self.ffmpegcolorspace, + self.videoscale, + self.video_filter, + self.theoraenc, + self.queue_video, + self.oggmux) + + gst.element_link_many( + self.alsasrc, + self.sound_filter, + self.audioconvert, + self.vorbisenc, + self.queue_sound, + self.oggmux) + + gst.element_link_many( + self.oggmux, + self.file) + + def add_todos(self): + """Agrega al pipe todos los elementos, de audio y video.""" + + self.pipeline.add( + self.ximagesrc, + self.ffmpegcolorspace, + self.videoscale, + self.video_filter, + self.theoraenc, + self.queue_video, + self.alsasrc, + self.sound_filter, + self.audioconvert, + self.vorbisenc, + self.queue_sound, + self.oggmux, + self.file) + + def add_solo_video(self): + """Agrega al pipe solo los elementos de video pero no de adio.""" + + self.pipeline.add( + self.ximagesrc, + self.ffmpegcolorspace, + self.videoscale, + self.video_filter, + self.theoraenc, + self.queue_video, + self.oggmux, + self.file) + + def set_audio_enabled(self, valor): + """Habilita y desabilita el audio en la grabación.""" + + self.stop() + self.enabled_sound = valor + + def set_video_quality(self, resolution): + """Configura la calidad de grabación de video.""" + + self.stop() + + w, h = resolution + self.resolution = "video/x-raw-yuv,width=%i,height=%i" % (w,h) + + def on_sync_message(self, bus, message): + """Captura mensajes en el bus.""" + + if message.structure is None: return + + def on_message(self, bus, message): + """Captura mensajes en el bus.""" + + if message.type == gst.MESSAGE_ERROR: + err, debug = message.parse_error() + # "ERROR ON_MESSAGE: ", err, debug + self.pipeline.set_state(gst.STATE_NULL) + + def record(self, location_path): + """Comienza a Grabar.""" + + self.new_handle(False) + + if self.pipeline: + self.pipeline.set_state(gst.STATE_PAUSED) + self.pipeline.set_state(gst.STATE_NULL) + + """ + dat = datetime.date.today() + tim = time.strftime("%H-%M-%S") + self.file_path = os.path.join(location_path,"%s-%s.ogg" % (dat, tim)) + """ + self.file_path = location_path + + self.set_pipeline() + + self.pipeline.set_state(gst.STATE_PLAYING) + + self.new_handle(True) + + def stop(self): + """Detiene la grabación.""" + + self.new_handle(False) + + if self.pipeline: + self.pipeline.set_state(gst.STATE_PAUSED) + self.pipeline.set_state(gst.STATE_NULL) + + self.estado = None + + def new_handle(self, reset): + """Reinicia o mata el actualizador.""" + + if self.update: + gobject.source_remove(self.update) + self.update = None + + if reset: + self.update = gobject.timeout_add(1000, self.handle) + + def handle(self): + """Envía información periódicamente.""" + + if os.path.exists(self.file_path): + tamanio = int(os.path.getsize(self.file_path)/1024) + info = "Record: %s - %s Kb." % (str(self.file_path), str(tamanio)) + + if self.info != info: + self.info = info + self.emit('update', self.info) + #print self.info + + return True + +if __name__=="__main__": + + #default_location = os.path.dirname(__file__) + grabador = DesktopGrab() + grabador.set_audio_enabled(True) + if os.path.exists('/home/flavio'): + path = '/home/flavio' + else: + path = '/home/olpc' + grabador.record(path) + gtk.main() diff --git a/recordmydesktop b/recordmydesktop Binary files differdeleted file mode 100755 index f930c61..0000000 --- a/recordmydesktop +++ /dev/null diff --git a/screencast_activity.py b/screencast_activity.py index e87383f..4680c6d 100644 --- a/screencast_activity.py +++ b/screencast_activity.py @@ -37,7 +37,8 @@ import gtk import screencast_ui # Process -import screencast_process +#import screencast_process +import DesktopGrab # GObject import gobject @@ -54,7 +55,7 @@ class ScreencastActivity(activity.Activity): # Attributes _ui = None - _process = None + #_process = None _outfile = None _state = None @@ -79,10 +80,12 @@ class ScreencastActivity(activity.Activity): self._ui.showGUI() # Process - self._process = screencast_process.ScreencastProcess() - self._process.connect('encode-start', self.startEncode) - self._process.connect('encode-finished', self.finishEncode) - self._process.connect('update-statusbar', self.updateStatusbar) + self._process = DesktopGrab.DesktopGrab() + self._process.connect('update', self.updateStatusbar) + #self._process = screencast_process.ScreencastProcess() + #self._process.connect('encode-start', self.startEncode) + #self._process.connect('encode-finished', self.finishEncode) + #self._process.connect('update-statusbar', self.updateStatusbar) # Connect UI signals self._ui.connect('record-button-clicked-signal', self.recordButtonClicked) @@ -92,36 +95,53 @@ class ScreencastActivity(activity.Activity): """ Record button clicked event """ self._ui.changeButtonsState("record") - self._process.runProcess(self._ui.getCurrentQuality(), self._ui.isSoundCheckActive(), self._outfile) + if self._ui.isSoundCheckActive(): + self._process.set_audio_enabled(True) + else: + self._process.set_audio_enabled(False) + + #self._process.runProcess(self._ui.getCurrentQuality(), self._ui.isSoundCheckActive(), self._outfile) + self._process.set_audio_enabled(True) + self._process.set_video_quality((800,600)) + + self._process.record(self._outfile) self._state = "record" def stopButtonClicked(self, widget): """ Stop button clicked event """ - self._ui.changeButtonsState("encode") - self._process.stopProcess() - - def startEncode(self,widget): - """ Start encoding - """ - self._ui.showProgressbar() - self._state = "encode" - - def finishEncode(self,widget): - """ Finish encoding - """ + #self._ui.changeButtonsState("encode") self._ui.changeButtonsState("stop") - self._ui.hideProgressbar() + #self._process.stopProcess() + self._process.stop() self._state = "stop" - self._ui.alert("Encode finished") - - def updateStatusbar(self, widget, text, percentage): + def updateStatusbar(self, widget, text): """ Update status bar """ - text = "Status: Encoding" self._ui.changeStatusbarText(text) - self._ui.updateProgressbar(percentage) + + #def startEncode(self,widget): + # """ Start encoding + # """ + # self._ui.showProgressbar() + # self._state = "encode" + # + #def finishEncode(self,widget): + # """ Finish encoding + # """ + # self._ui.changeButtonsState("stop") + # self._ui.hideProgressbar() + # self._state = "stop" + # self._ui.alert("Encode finished") + # + # + #def updateStatusbar(self, widget, text, percentage): + # """ Update status bar + # """ + # text = "Status: Encoding" + # self._ui.changeStatusbarText(text) + # self._ui.updateProgressbar(percentage) def write_file(self, filePath): """ Journal write file method |