I think that gstreamer is more intended for video/audio decoding an processing. It is something that I tried long ago (I have to revisit it).
I made bindings for openpnp which enables reading a webcam and it is multiplatform. I'd like to show the video. They have a gtk example using GtkImage and GdkPixBuf, but don't find those in gintro. he exampel is here.
proc gdk_pixbuf_get_type*(): GType {.importc, libprag.}
proc gtk_image_get_type*(): GType {.importc, libprag.}
searched
$ grep -A8 "gtk_image_get_pixbuf" ~/.nimble/pkgs/gintro-#head/gintro/gtk4.nim
$ grep -A8 "gtk_image_get_pixbuf" ~/.nimble/pkgs/gintro-#head/gintro/gtk.nim
proc gtk_image_get_pixbuf(self: ptr Image00): ptr gdkpixbuf.Pixbuf00 {.
importc, libprag.}
proc getPixbuf*(self: Image | LockButtonAccessible | RadioButtonAccessible | LinkButtonAccessible | ImageCellAccessible | MenuButtonAccessible | ToggleButtonAccessible | ArrowAccessible | ScaleButtonAccessible | ButtonAccessible | ImageAccessible | SpinnerAccessible): gdkpixbuf.Pixbuf =
let gobj = gtk_image_get_pixbuf(cast[ptr Image00](self.impl))
if gobj.isNil:
return nil
let qdata = g_object_get_qdata(gobj, Quark)
if qdata != nil:
result = cast[type(result)](qdata)
assert(result.impl == gobj)
else:
fnew(result, gdkpixbuf.finalizeGObject)
So yes, seems that gtk_image_get_pixbuf is available only for old GTK3. I don't know what does replace it for GTK4, and I can currently NOT write a working GTK4 example for you. Another one just asked for a libadwaita example (https://github.com/StefanSalewski/gintro/issues/120), so maybe I should do that first?
Clearly I need to improve the way I search in gintro.
I am trying first nimx (it looks a bit simpler). I have some code ocnimx not working.
Can somebody orient me on what I am doing wrong?
Clearly I need to improve the way I search in gintro.
I explained how I do it in the GTK4 book:
http://ssalewski.de/gtkprogramming.html#_nim_api_docs
But I would recommend you not using gstreamer, as GTK is not easy, and gstreamer is one of the more difficult parts. I myself know nearly nothing about gstreamer.
I got it working with nimx. The following code shows the webcam in he window:
# nim c -r --threads:on ocnimx
import openpnp_capture, os
import nimx/window
import nimx / [ animation, view, image, context, render_to_image]
type FrameView = ref object of View
image: Image
animation: Animation
ctx:CapContext
streamID:CapStream
width:uint32
height:uint32
data:seq[uint8]
method init*(v: FrameView, r: Rect) =
procCall v.View.init(r)
v.animation = newAnimation()
v.animation.resume()
# Webcam code
v.ctx = Cap_createContext()
var deviceCount = Cap_getDeviceCount(v.ctx)
let
deviceID = 0'u32
deviceFormatID = 0'u32
v.streamID = v.ctx.Cap_openStream( deviceID, deviceFormatID )
var info = v.ctx.getFormatInfo(deviceID, deviceFormatID)
#echo info
v.width = info.width
v.height = info.height
# Read every frame and update the image
v.animation.onAnimate = proc(p: float) =
if v.ctx.Cap_hasNewFrame(v.streamID) == 1:
var n = (v.width * v.height * 3).uint32
v.data = newSeq[uint8](n)
var err = v.ctx.Cap_captureFrame(v.streamID, v.data[0].unsafeAddr, n)
v.image = imageWithBitmap( v.data[0].addr, v.width.int, v.height.int, 3) #cast[ptr uint8](g[0].addr)
echo repr v.image
method draw(v: FrameView, r: Rect) =
let c = currentContext()
if not v.image.isNil:
var imageSize = v.image.size
var imageRect = newRect(zeroPoint, imageSize)
c.drawImage(v.image, imageRect)
proc startApp() =
# Create window
var mainWindow = newWindow(newRect(40, 40, 800, 600))
var fv = FrameView()
var imageRect = newRect(0,0,640,480)
fv.init(imageRect)
mainWindow.addSubview(fv)
mainWindow.addAnimation(fv.animation)
# Run the app
runApplication:
startApp()
I still need to clean it and I will try gintro, but at least now I have some working code.