diff --git a/examples/device_monitor/main.go b/examples/device_monitor/main.go new file mode 100644 index 0000000..f06767e --- /dev/null +++ b/examples/device_monitor/main.go @@ -0,0 +1,81 @@ +// This example uses gstreamer's discoverer api. +// +// https://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/GstDiscoverer.html +// To detect as much information from a given URI. +// The amount of time that the discoverer is allowed to use is limited by a timeout. +// This allows to handle e.g. network problems gracefully. When the timeout hits before +// discoverer was able to detect anything, discoverer will report an error. +// In this example, we catch this error and stop the application. +// Discovered information could for example contain the stream's duration or whether it is +// seekable (filesystem) or not (some http servers). +package main + +import ( + "fmt" + + "github.com/tinyzimmer/go-glib/glib" + "github.com/tinyzimmer/go-gst/examples" + "github.com/tinyzimmer/go-gst/gst" +) + +func runPipeline(loop *glib.MainLoop) error { + + gst.Init(nil) + fmt.Println("Running device monitor") + // if len(os.Args) < 2 { + // fmt.Printf("USAGE: %s \n", os.Args[0]) + // os.Exit(1) + // } + + // uri := os.Args[1] + fmt.Println("Creating device monitor") + + monitor := gst.NewDeviceMonitor() + fmt.Println("Created device monitor", monitor) + + // if err != nil { + // fmt.Println("ERROR:", err) + // os.Exit(2) + // } + caps := gst.NewCapsFromString("video/x-raw") + + monitor.AddFilter("Video/Source", caps) + + fmt.Println("Getting device monitor bus") + bus := monitor.GetBus() + fmt.Println("Got device monitor bus", bus) + + bus.AddWatch(func(msg *gst.Message) bool { + switch msg.Type() { + case gst.MessageDeviceAdded: + message := msg.ParseDeviceAdded().GetDisplayName() + fmt.Println("Added: ", message) + case gst.MessageDeviceRemoved: + message := msg.ParseDeviceRemoved().GetDisplayName() + fmt.Println("Removed: ", message) + default: + // All messages implement a Stringer. However, this is + // typically an expensive thing to do and should be avoided. + fmt.Println("Type: ", msg.Type()) + fmt.Println("Message: ", msg) + } + return true + }) + + monitor.Start() + fmt.Println("Started device monitor") + devices := monitor.GetDevices() + for i, v := range devices { + fmt.Printf("Device: %d %s\n", i, v.GetDisplayName()) + } + + loop.Run() + + return nil +} + +func main() { + examples.RunLoop(func(loop *glib.MainLoop) error { + return runPipeline(loop) + }) +} diff --git a/gst/gst_device_monitor.go b/gst/gst_device_monitor.go new file mode 100644 index 0000000..b11624d --- /dev/null +++ b/gst/gst_device_monitor.go @@ -0,0 +1,77 @@ +package gst + +// #include "gst.go.h" +import "C" + +import ( + "unsafe" + + "github.com/tinyzimmer/go-glib/glib" +) + +// DeviceMonitor is a Go representation of a GstDeviceMonitor. +type DeviceMonitor struct { + ptr *C.GstDeviceMonitor + bus *Bus +} + +func NewDeviceMonitor() *DeviceMonitor { + monitor := C.gst_device_monitor_new() + if monitor == nil { + return nil + } + return &DeviceMonitor{ptr: monitor} +} + +func (d *DeviceMonitor) AddFilter(classes string, caps *Caps) { + var cClasses *C.gchar + if classes != "" { + cClasses = C.CString(classes) + defer C.free(unsafe.Pointer(cClasses)) + } + + C.gst_device_monitor_add_filter(d.ptr, cClasses, caps.Instance()) + // if caps == nil { + // return nil + // } + //should return if we were able to add the filter +} + +// GetPipelineBus returns the message bus for this pipeline. +func (d *DeviceMonitor) GetBus() *Bus { + if d.bus == nil { + cBus := C.gst_device_monitor_get_bus(d.ptr) + d.bus = FromGstBusUnsafeFull(unsafe.Pointer(cBus)) + } + return d.bus +} + +func (d *DeviceMonitor) Start() bool { + return gobool(C.gst_device_monitor_start(d.ptr)) + //should return if we were able to add the filter +} + +func (d *DeviceMonitor) Stop() { + C.gst_device_monitor_stop(d.ptr) + //should return if we were able to add the filter +} + +func (d *DeviceMonitor) GetDevices() []*Device { + glist := C.gst_device_monitor_get_devices(d.ptr) + if glist == nil { + return nil + } + goList := glib.WrapList(uintptr(unsafe.Pointer(glist))) + out := make([]*Device, 0) + goList.Foreach(func(item interface{}) { + pt := item.(unsafe.Pointer) + out = append(out, FromGstDeviceUnsafeFull(pt)) + }) + return out +} + +//https://gstreamer.freedesktop.org/documentation/gstreamer/gstdevicemonitor.html?gi-language=c +//gst_device_monitor_get_providers +//gst_device_monitor_get_show_all_devices +//gst_device_monitor_remove_filter +//gst_device_monitor_set_show_all_devices