Buscar este blog

miércoles, 11 de septiembre de 2013

Audio y video con gstreamer

Una opción para la programación de audio y video en .Net es gstreamer, esta es una librería cross platform que funciona en windows, linux osx y android por lo que con el diseño adecuado tu aplicación puede funcionar en todas estas plataformas.
En cuanto a .Net el soporte se da a través de la librería gstreamer-sharp que es un binding basado en interop para acceder a las dlls nativas.
Esta librería no se encuentra en el sdk oficial pero puedes obtenerla en la pagina de ossbuild que tiene instaladores del sdk que incluyen las dlls para .Net.

Es muy fácil de usar aquí el ejemplo, unas pocas lineas de código que hacen todo:

using Gst;
 
namespace ConsoleApplication1 {
    public class PlayBinTest {
        static Element pipeline = null;
        public static void Main(string[] args) {
            Application.Init();
 
            pipeline = Gst.Parse.Launch("playbin uri=http://localhost:8000/");
            pipeline.SetState(State.Playing);
            Bus bus = pipeline.Bus;
            bus.AddWatch(EventLoop);
 
            Gst.GLib.MainLoop loop = new Gst.GLib.MainLoop();
            loop.Run();
 
            pipeline.SetState(State.Null);
            System.Console.ReadLine();
        }
        static bool EventLoop(Bus bus, Message msg) {
                switch(msg.Type) {
                    case MessageType.Eos: {
                        msg.Dispose();
                        return false;
                    }
                    case MessageType.Error: {
                        System.Console.WriteLine(msg.Structure.ToString());
                            pipeline.SetState(State.Ready);
                            pipeline["uri"] = "http://localhost:8000";
                            pipeline.SetState(State.Playing);
                        return true;
                    }
                }
            return true;
        }
    }
}

viernes, 2 de agosto de 2013

Creando sistemas de archivos con .net

Si quieres desarrollar sistemas de archivos para Linux una buena alternativa es Mono.Fuse un proyecto que usa internamente FUSE, que es la forma mas conocida de crear sistemas de archivos a nivel de usuario en Linux.

Simplemente tienes que implementar las funciones que heredas de un clase incluida en la librería y listo, por ejemplo implementas OnReadSymbolicLink para obtener la dirección a la que apunta un enlace simbólico.

miércoles, 24 de julio de 2013

Visual Studio no depura

A veces cuando queremos depurar un programa en Visual Studio 2010 el entorno no inicia la depuración, el proyecto se compila sin problemas pero el programa no inicia.
Esto puede deberse al que el proceso vshost del programa "se colgó", para solucionar esto hay que abrir el administrador de tareas y matar el proceso, después de esto se debe iniciar la depuración la próxima vez.

domingo, 30 de junio de 2013

Usando Invoke con una expresión Lambda

A veces queremos usar el método Invoke de un control o form de Windows.Forms sin llenarnos de delegados, simplemente escribir el código en el lugar donde se usa, para esto podemos debemos "castear" la expresión a un objeto Action, muy simple:



Invoke((Action)(() => {
    Close();
}));

viernes, 21 de junio de 2013

Menus en click derecho de Gkt sharp

Pues resulta que en gtk los menús no aparecen cuando se da click derecho, afortunadamente Dave Glick ha publicado esta clase para solucionarlo.
Les incluyo el código ligeramente modificado si no quieren navegar a otra pagina:


using System;
using Gdk;
using GLib;
using Gtk;
 
namespace Somedave {
    public class ContextMenuEventArgs: EventArgs {
        private Widget widget;
        public Widget Widget { get { return widget; } }
 
        private bool rightClick;
        public bool RightClick { get { return rightClick; } }
 
        public ContextMenuEventArgs(Widget widget, bool rightClick) {
            this.widget = widget;
            this.rightClick = rightClick;
        }
    }
 
    public class ContextMenuHelper {
        public event EventHandler<ContextMenuEventArgs> ContextMenu;
 
        public ContextMenuHelper() { }
 
        public ContextMenuHelper(Widget widget) {
            AttachToWidget(widget);
        }
 
        public ContextMenuHelper(Widget widget, EventHandler<ContextMenuEventArgs> handler) {
            AttachToWidget(widget);
            ContextMenu += handler;
        }
 
        public void AttachToWidget(Widget widget) {
            widget.PopupMenu += Widget_PopupMenu;
            widget.ButtonPressEvent += Widget_ButtonPressEvent;
        }
 
        public void DetachFromWidget(Widget widget) {
            widget.PopupMenu -= Widget_PopupMenu;
            widget.ButtonPressEvent -= Widget_ButtonPressEvent;
        }
 
        [GLib.ConnectBefore]
        private void Widget_PopupMenu(object o, PopupMenuArgs args) {
            RaiseContextMenuEvent(args, (Widget)o, false);
        }
 
        [GLib.ConnectBefore]
        private void Widget_ButtonPressEvent(object o, ButtonPressEventArgs args) {
            if(args.Event.Button == 3 && args.Event.Type == EventType.ButtonPress) {
                RaiseContextMenuEvent(args, (Widget)o, true);
            }
        }
 
        private bool propagating = false;   //Prevent reentry
 
        private void RaiseContextMenuEvent(SignalArgs signalArgs, Widget widget, bool rightClick) {
            if(!propagating) {
                //Propagate the event
                Event evnt = Gtk.Global.CurrentEvent;
                propagating = true;
                Gtk.Global.PropagateEvent(widget, evnt);
                propagating = false;
                signalArgs.RetVal = true;     //The widget already processed the event in the propagation
 
                //Raise the context menu event
                ContextMenuEventArgs args = new ContextMenuEventArgs(widget, rightClick);
                if(ContextMenu != null) {
                    ContextMenu.Invoke(this, args);
                }
            }
        }
    }
}