Mostrando entradas con la etiqueta pygst. Mostrar todas las entradas
Mostrando entradas con la etiqueta pygst. Mostrar todas las entradas

domingo, 19 de septiembre de 2010

Fotografiar con pygst

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Capturador_Gstreamer.py (versión 1)
# por Flavio Danesse (fdanesse@hotmail.com)
# CeibalJAM! - Uruguay


import sys, os
import pygtk, gtk, gobject

import pygst
pygst.require("0.10")
import gst

import time

class Capturador_Gstreamer():
    def __init__(self, frecuencia=2):


        self.frecuencia = frecuencia
        self.hora = time.strftime("%H:%M:%S") # hora de inicio, luego, hora de cada fotografía

        # Declaración elemendos para pipeline de fotografía
        self.pipeline = None
        self.source = None
        self.codec = None
        self.formato = None
        self.filesink = None

        self.start_streaming() # levanta el stream

        self.estado = True # controla el estado general del programa

    def main(self):
        while self.estado:
            time.sleep(self.frecuencia)
            self.get_fotografia()

    def get_fotografia(self):
    # timer para ejecutar tareas programadas
        self.pipeline.set_state(gst.STATE_NULL) # anula el pipeline
        self.hora = time.strftime("%H:%M:%S") # obtiene la hora
        self.filesink.set_property("location", "%s.png" % (self.hora)) # Cambia nombre de archivo
        self.pipeline.set_state(gst.STATE_PLAYING) # Fotografía
        return True

    def construir_pipeline(self):
    # construye el stream de fotografia
        self.pipeline = gst.Pipeline("player")
       
        self.source = gst.element_factory_make("v4l2src", "camara") # origen
        self.codec = gst.element_factory_make("ffmpegcolorspace", "codec") # formato de video
        self.formato = gst.element_factory_make("pngenc", "png") # formato de imagen

        self.filesink = gst.element_factory_make("filesink", "filesink") # salida
        self.filesink.set_property("location", "%s.png" % (self.hora))

        self.pipeline.add(self.source, self.codec, self.formato, self.filesink) # armar el pipeline
        gst.element_link_many(self.source, self.codec, self.formato, self.filesink) # entubar los elementos

     def start_streaming(self):
    # Ejecuta el stream
        self.construir_pipeline() # construye el pipeline

            self.bus = self.pipeline.get_bus() # obtiene el bus de mensajes

            self.bus.add_signal_watch() # escucha las señales en el bus
            self.bus.connect("message", self.on_message) # conecta los mensajes al manejador de señales

    def on_message(self, bus, message):
    # mensajes en el bus
            if message.type == gst.MESSAGE_ERROR:
                    err, debug = message.parse_error()
                    print "ERROR ON_MESSAGE: ", err, debug

    def describe(self):
    # Descripción general del funcionamiento de la clase Capturador_Gstreamer
        descripcion = '''\t\t*** Clase Capturador_Gstreamer *** \n
        Esta clase recibe un parámetro entero que indica cada cuantos segundos debe realizar una fotografía.\n
        Luego, comenzara a fotografiar y guardar esas imágenes con el nombre de archivo igual a la hora de realizada la fotografía.\n
        Mientras la variable estado sea True, continuará realizando esta tarea.'''
        return descripcion

if __name__ == "__main__":
    # frecuencia es cada cuantos segundos debe fotografiar
    capturador = Capturador_Gstreamer(frecuencia=2)
    print capturador.describe()
    capturador.main()

sábado, 18 de septiembre de 2010

Testeo de Audio con pygst

#!/usr/bin/python

import pygst
pygst.require("0.10")
import gst
import pygtk
import gtk

class Main:
    def __init__(self):

        self.pipeline = gst.Pipeline("mypipeline")

        self.audiotestsrc = gst.element_factory_make("audiotestsrc", "audio")
        self.audiotestsrc.set_property ("freq", 500)
        self.pipeline.add(self.audiotestsrc)

        self.sink = gst.element_factory_make("alsasink", "sink")
        self.pipeline.add(self.sink)

        self.audiotestsrc.link(self.sink)

        self.pipeline.set_state(gst.STATE_PLAYING)

start=Main()
gtk.main()

Guia de uso de pygst


Guia de uso de pygst.

El siguiente documento explica la implementación de gstreamer en python sobre gtk, utilizando la interfaz pygst. (El código de ejemplo es CeibalMedia.activity(0.0).xo)

Recepción de video por la red y reproducción en widget gtk:

En terminal (recibir sólo video):

gst-launch udpsrc port=5000 ! smokedec ! autovideosink

En pygst (recibir sólo video):

          def construir_pipeline(self, ip, puerto):
                    self.pipeline = gst.Pipeline("player")
                    # recepcion por UDP
                    udpsrc = gst.element_factory_make("udpsrc", "udpsrc0")
                    udpsrc.set_property('port', puerto)
                    # decodificar
                    smokedec = gst.element_factory_make("smokedec", "codec5")
                    sink = gst.element_factory_make("autovideosink", "SalidadeVideoaWidget")
                    # enlazar
                    self.pipeline.add(udpsrc, smokedec, sink)
                    gst.element_link_many(udpsrc, smokedec, sink)

Detalle:
El procedimiento de trabajo con gstreamer es muy sencillo.
Se crea una tubería de elementos donde la salida de cada uno de ellos, se convierte en la entrada para el siguiente.
De esta forma, establecemos un origen de datos, los procesamos y los mandamos a una salida.
En pygst, la tubería se construye a partir de elementos pygst, estos elemento poseen propiedades cuyos valores pueden
establecerse mediante set_property. En este ejemplo en particular, tenemos sólo 3 elementos:
  •           Origen de datos: udpsrc
  •           Decodificador: smokedec
  •           Salida de Video: autovideosink

Envío de Video por la Red:

En terminal (enviar sólo video):

gst-launch v4l2src ! video/x-raw-yuv,width=320,height=240,framerate=\(fraction\)2/1 ! ffmpegcolorspace ! smokeenc keyframe=8 qmax=40 ! udpsink host=192.168.1.5 port=5000

En pygst (enviar sólo video):

          def construir_pipeline(self):
                    self.pipeline = gst.Pipeline("player")
                    source = gst.element_factory_make("v4l2src", "camara")
                    codec2 = gst.element_factory_make("videorate", "codec2")
                    codec3 = gst.element_factory_make("videoscale", "codec3")
                    codec4 = gst.element_factory_make("ffmpegcolorspace", "codec4")
                    smokeenc = gst.element_factory_make("smokeenc", "codec5")
                    smokeenc.set_property('keyframe', 8)
                    smokeenc.set_property('qmax', 40)
                    udpsink = gst.element_factory_make("udpsink", "udpsalida")
                    udpsink.set_property('host', "192.168.1.5")
                    udpsink.set_property('port', 5000)
                    self.pipeline.add(source, codec2, codec3, codec4, smokeenc, udpsink)
                    gst.element_link_many(source, codec2, codec3, codec4, smokeenc, udpsink)

Detalle:
De acuerdo al código que recibe la señal, vemos que en el código de envío, si bien es más extenso, las diferencias son menores:

En el código que recibe la señal, inmediatamente despues del origen de datos (udpsrc), encontramos un decodificador (smokedec) y luego la salida al widget asignado para mostrar los datos.

En el código de envío, en lugar de un decodificador, necesitamos el codificador por eso antes de enviar los datos, tenemos smokeenc, y en lugar de enviar los datos a un widget gtk, los enviamos a la red (udpsink).

Los elementos videorate, videoscale y ffmpegcolorspace establecen el modo de video utilizado y por lo tanto los datos enviados.

En este ejemplo, hemos utilizado los siguientes elementos de gstreamer:

Origen de datos: v4l2src y udpsrc
Filtros: videorate, videoscale y ffmpegcolorspace
Codificadores: smokeenc
Decodificadores: smokedec
Salida de datos: autovideosink y udpsink

De modo que, siquiendo esta mecánica, es muy sencillo implementar pygst , todo depende de los elementos disponibles y del conocimiento que tengamos de éstos. Siempre puedes consultar sobre los elementos gstreamer para saber cuales son sus propiedades o cuales están disponibles en nuestro sistema.

Si por ejemplo deseas saber sobre el elemento videorate, en terminal escribes:
gst-inspect-0.10 videorate

Para saber sobre los elementos disponibles, simplemente escribes:
gst-inspect-0.10


Ceibal Jam – Uruguay. (Flavio Danesse – fdanesse@hotmail.com)

mp3 player utilizando pygst

#!usr/bin/python
# -*- coding: UTF-8 -*-

import sys, os
import pygtk, gtk, gobject
import pygst
pygst.require("0.10")
import gst

class GTK_Main():
   
    def __init__(self):
        window = gtk.Window(gtk.WINDOW_TOPLEVEL)
        window.set_title("MP3-Player")
        window.set_default_size(400, 200)
        window.connect("destroy", gtk.main_quit, "WM destroy")
        vbox = gtk.VBox()
        window.add(vbox)
        self.entry = gtk.Entry()
        vbox.pack_start(self.entry, False, True)
        self.button = gtk.Button("Start")
        self.button.connect("clicked", self.start_stop)
        vbox.add(self.button)
        window.show_all()
       
        self.player = gst.Pipeline("player") # pipeline

        source = gst.element_factory_make("filesrc", "file-source") # origen
        decoder = gst.element_factory_make("mad", "mp3-decoder") # decoder
        conv = gst.element_factory_make("audioconvert", "converter") # conversor
        sink = gst.element_factory_make("alsasink", "alsa-output") # salida
       
        self.player.add(source, decoder, conv, sink) # armar el pipeline

        gst.element_link_many(source, decoder, conv, sink) # entubar los elementos

        bus = self.player.get_bus() # bus del pipeline para poder manejar los datos internos
        bus.add_signal_watch() # escuchar las señales en el bus del pipeline
        bus.connect("message", self.on_message) # los mensajes son enviados a nuestra funcion "on_message"
       
    def start_stop(self, widget):
    # Se ejecuta al hacer click sobre el boton "start"
        if self.button.get_label() == "Start":
            filepath = self.entry.get_text()
            if os.path.isfile(filepath):
                self.button.set_label("Stop")
                self.player.get_by_name("file-source").set_property("location", filepath)
                self.player.set_state(gst.STATE_PLAYING)
        else:
            self.player.set_state(gst.STATE_NULL)
            self.button.set_label("Start")
                       
    def on_message(self, bus, message):
    # es una retrollamada para los mensajes del bus del pipeline
        t = message.type
        if t == gst.MESSAGE_EOS:
            self.player.set_state(gst.STATE_NULL)
            self.button.set_label("Start")
        elif t == gst.MESSAGE_ERROR:
            self.player.set_state(gst.STATE_NULL)
            self.button.set_label("Start")
            err, debug = message.parse_error()
            print "Error: %s" % err, debug
           
GTK_Main()
gtk.gdk.threads_init()
gtk.main()