Go4vl is Go library for working with the Video for Linux API (V4L2) natively, without any C bindings.

go4vl

A Go library for working with the Video for Linux user API (V4L2).


Gov4l hides all the complexities of working with V4L2 and exposes idiomatic Go types, like channels, to consume captured frame.

Features

  • Capture and control video data from your Go programs
  • Idiomatic Go API
Owner
Vladimir Vivien
Software Engineer, VMware
Vladimir Vivien
Comments
  • Cannot retrieve pixel format info from device [Error While Encoding v4l2 command via ioctl]

    Cannot retrieve pixel format info from device [Error While Encoding v4l2 command via ioctl]

    Error

    device.GetPixFormat() always fails with error device: pix format failed: unsupported error if we do a system call trace i get following

    ioctl(3, _IOC(_IOC_READ|_IOC_WRITE, 0x56, 0x4, 0xcc), 0xc000076ca8) = -1 ENOTTY (Inappropriate ioctl for device)
    write(1, "failed to get pix format\n", 25failed to get pix format
    

    It looks like encoded command is not VIDIOC_G_FMT and is not recognized by kernel.

    package main
    
    import (
    	"fmt"
    
    	"github.com/vladimirvivien/go4vl/v4l2"
    )
    
    func main() {
    	device, err := v4l2.Open("/dev/video0")
    	if err != nil {
    		panic(err)
    	}
    
    	_, err = device.GetPixFormat()
    	if err != nil {
    		fmt.Println("failed to get pix format")
    		panic(err)
    	}
    }
    
    

    My kernel is

    Linux endless 5.14.14-arch1-1 #1 SMP PREEMPT Wed, 20 Oct 2021 21:35:18 +0000 x86_64 GNU/Linux
    

    Cause

    I don't think this problem is caused by kernel. I can use <linux/videodev2.h> and it does not cause this error

    With the C API I get

    ioctl(3, VIDIOC_G_FMT, {type=V4L2_BUF_TYPE_VIDEO_CAPTURE, fmt.pix={width=1280, height=720, pixelformat=v4l2_fourcc('M', 'J', 'P', 'G') /* V4L2_PIX_FMT_MJPEG */, field=V4L2_FIELD_NONE, bytesperline=0, sizeimage=1843200, colorspace=V4L2_COLORSPACE_SRGB}}) = 0
    

    It looks like the problem is caused in ioctl encoding functions. I rechecked the ioct.go but could not find the problem

  • Missing constants from linux/videodev2.h

    Missing constants from linux/videodev2.h

    Hi, I'm getting the following errors building the package,

    /home/dev/go/pkg/mod/github.com/vladimirvivien/[email protected]/v4l2/capability.go:48:33: could not determine kind of name for C.V4L2_CAP_IO_MC
    /home/dev/go/pkg/mod/github.com/vladimirvivien/[email protected]/v4l2/format_desc.go:25:55: could not determine kind of name for C.V4L2_FMT_FLAG_CSC_COLORSPACE
    /home/dev/go/pkg/mod/github.com/vladimirvivien/[email protected]/v4l2/format_desc.go:28:55: could not determine kind of name for C.V4L2_FMT_FLAG_CSC_HSV_ENC
    /home/dev/go/pkg/mod/github.com/vladimirvivien/[email protected]/v4l2/format_desc.go:29:55: could not determine kind of name for C.V4L2_FMT_FLAG_CSC_QUANTIZATION
    /home/dev/go/pkg/mod/github.com/vladimirvivien/[email protected]/v4l2/format_desc.go:26:55: could not determine kind of name for C.V4L2_FMT_FLAG_CSC_XFER_FUNC
    /home/dev/go/pkg/mod/github.com/vladimirvivien/[email protected]/v4l2/format_desc.go:27:55: could not determine kind of name for C.V4L2_FMT_FLAG_CSC_YCBCR_ENC
    /home/dev/go/pkg/mod/github.com/vladimirvivien/[email protected]/v4l2/format_desc.go:24:55: could not determine kind of name for C.V4L2_FMT_FLAG_ENC_CAP_FRAME_INTERVAL
    

    When I open /usr/include/linux/videodev2.h I see these constants are not present. This is on ubuntu 20.04.3 with package linux-libc-dev version 5.4.0-94.106 (after update and upgrade). There may be other such constants, it stops showing errors at a certain point.

    On my other popos install I see linux-libc-dev is at version 5.15.5 and looks like the constants are present.

    It looks like some of those constants are relatively new, like V4L2_CAP_IO_MC might just be from 2020.

    Do I need to find a way to get the newer package? or should this library try to accommodate? Thanks

  • Single capture at regular intervals

    Single capture at regular intervals

    What's the best approach to do a single capture at regular intervals. There is an example for snapshot, but that one closes the device once it finishes storing the image.

    In a scenario where we want to regularly capture, sometimes with a couple seconds difference, others with minutes, should the device be closed or kept open?

    If open, what is the best approach to ensure getting the latest frame without causing any issues or large memory footprint?

    Thanks

  • Buffer dequeue error

    Buffer dequeue error

    Hi,

    I'm testing out the mjpeg saving example in the README (making the sole change of width to 1280 and height to 720 - which the camera DOES support) and half of the time the example runs smoothly and then sometimes when I run it I get the following error:

    Done.
    panic: device: capture: buffer dequeue: system error
    
    goroutine 34 [running]:
    github.com/vladimirvivien/go4vl/v4l2.(*Device).Capture.func1(0xd06000, 0x3, 0xcb0850, {0x104658, 0xd02000}, 0x1fca055)
    	/home/pi/go/pkg/mod/github.com/vladimirvivien/[email protected]/v4l2/device.go:245 +0x3c0
    created by github.com/vladimirvivien/go4vl/v4l2.(*Device).Capture
    	/home/pi/go/pkg/mod/github.com/vladimirvivien/[email protected]/v4l2/device.go:230 +0xd0
    exit status 2
    
    

    Have you seen that before or have any idea why it might be happening seemingly randomly?

    Thanks for the library btw!

  • Unable to set any frame size other than the default 640x480

    Unable to set any frame size other than the default 640x480

    Hi, I seem to have a problem setting the image size correctly and it keeps defaulting to the default 640x480, even when using your webcam.go example and changing the with and height to 1280x720 still resolves in a 640x480 picture. the capture card is able to provide an MJPEG of 720p as well as 1080p and this also works via this pkg: https://github.com/blackjack/webcam but I cant get the same to work here, even though I like the rest of the implementation here a bit better.

    Would you mind giving an example of a working webcam.go or capture.go with a different image size just as a reference to look at.

  • v4l2/capability.go:48:33: could not determine kind of name for C.V4L2_CAP_IO_MC

    v4l2/capability.go:48:33: could not determine kind of name for C.V4L2_CAP_IO_MC

    uname -r
    5.11.0-1022-aws
    
    sudo find / -name videodev2.h
    /usr/include/linux/videodev2.h
    
    go version
    go version go1.17.8 linux/amd64
    
    
    
    

    GCC

    gcc -v
    Using built-in specs.
    COLLECT_GCC=gcc
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
    OFFLOAD_TARGET_NAMES=nvptx-none:hsa
    OFFLOAD_TARGET_DEFAULT=1
    Target: x86_64-linux-gnu
    Thread model: posix
    gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04)
    
     make
    CGO_ENABLED=1 GO111MODULE=on go build -ldflags "-X github.com/edgexfoundry/device-usb-camera.Version=0.0.0" -o cmd/device-usb-camera ./cmd
    # github.com/vladimirvivien/go4vl/v4l2
    ../go/pkg/mod/github.com/vladimirvivien/[email protected]/v4l2/capability.go:48:33: could not determine kind of name for C.V4L2_CAP_IO_MC
    make: *** [Makefile:21: cmd/device-usb-camera] Error 2
    
  • Generating camera image

    Generating camera image

    The examples seem to focus on capturing camera images.

    Would this library also be fit to "generate" camera input, to be consumed by e.g. OBS Studio or Zoom? I've been able to output OBS Studio to v4l2 to be consumed by Zoom, so I'd assume v4l2 in general somehow supports it.

    The IsVideoOutputSupported function seems to indicate something like that is possible.

    Are there any pointers you can give, where one would get started on doing so?

    func writeFrame(frame *image.RGBA) {
        // My custom logic to write this frame
    }
    
    func main() {
    	devName := "/dev/video10"
    	device, err := v4l2.Open(devName)
    	if err != nil {
    		log.Fatalln("unable to open virtual webcam:", err)
    	}
    
    	defer device.Close()
    
    	caps, err := device.GetCapability()
    	if err != nil {
    		log.Println("failed to get device capabilities:", err)
    	}
    	log.Printf("device [%s] opened\n", devName)
    	log.Printf("device info: %s", caps.String())
    
    	if !caps.IsVideoOutputSupported() {
    		log.Fatalln("virtual webcam does not support video output")
    	}
    
    	// Something should go here, to prepare everything for "write mode"
    	pxFmt, err := GetPixFormatOutput(device.fd)
    	if err != nil {
    		log.Fatalln("unable to get pix format:", err) // It crashes here due to https://github.com/vladimirvivien/go4vl/issues/7 but that's OK
    	}
    
    	// And at some point, whenever a frame should be written, the `writeFrame` above can be called, and those bytes could
    	// then be written into the buffer allocated for v4l2
    }
    
    func GetPixFormatOutput(fd uintptr) (PixFormat, error) {
    	format := v4l2Format{StreamType: BufTypeVideoOutput}
    	if err := Send(fd, VidiocGetFormat, uintptr(unsafe.Pointer(&format))); err != nil {
    		return PixFormat{}, fmt.Errorf("pix format failed: %w", err)
    	}
    
    	return format.getPixFormat(), nil
    }
    

    I'm using the code for obs-v4l2sink as a guidance, because I know that code works.

  • capture video and audio at same time possible ?

    capture video and audio at same time possible ?

    I wanna capture both video and audio from a HDMI to USB Capture Card , and keep video and audio in sync , is that possible using this library ? if possible , could you show me an example ? Thanks

  • default fps when capture

    default fps when capture

    nice job . i see the default/base fps is set to 10 from here : https://github.com/vladimirvivien/go4vl/blob/40b41ba86c5c8d169bae1bcce5ec16605db44e6f/v4l2/device/device.go#L231, is there any way to detect and set a default fps value(rather than 10) supported by opened device ?
    thanks

  • Code and example updates (new examples, new features, etc)

    Code and example updates (new examples, new features, etc)

    This patch adds many updtes to the code and examples, including

    • New updates to the webcam example GUI
    • Streaming loop code update to copy frames to corruption by device during capture
    • Update webcam to include face detection feature
    • New examples including snapshot and simplecam
    • Updates to the example documentation
    • And much more
  • Refactoring stream capture pipeline

    Refactoring stream capture pipeline

    This patch refactors some capture data plane for go4vl including:

    • Buggy behavior introduced by using Go stdlib's os.OpenFile
    • Add more aggressive ioctl error handling for v4l2 calls
    • Testing using Raspberry Pi's camera modules directly
  • How to build the

    How to build the "webcam" example for raspi os (32bit) on linux amd64 machine?

    When I try to build the example in go4vl/examples/webcam directory on my machine (linux amd64) for ARM architecture I get following error:

    > GOARCH=arm ./build.sh 
    # github.com/vladimirvivien/go4vl/v4l2
    /home/me/go/pkg/mod/github.com/vladimirvivien/[email protected]/v4l2/types.go:11:15: undefined: Capability
    /home/me/go/pkg/mod/github.com/vladimirvivien/[email protected]/v4l2/types.go:12:14: undefined: IOType
    /home/me/go/pkg/mod/github.com/vladimirvivien/[email protected]/v4l2/types.go:23:15: undefined: BufType
    

    What I am doing wrong? What should I do?

  • fix(Camera): goroutine leak

    fix(Camera): goroutine leak

    This fixes two goroutine leaks:

    • in regular streaming mode goroutines kept building up very fast.
    • stopping the camera did not get rid of all goroutines.
  • Add Go test functions

    Add Go test functions

    The code has little test functions included in the source code. It should be possible to use the mock Loopback V4L2 device to create tests that exercise more of the current code. This could be coupled with a containerized environment to allow the code to be reproduced on any platform.

  • Non-blocking device file may be causing invalid captured buffer

    Non-blocking device file may be causing invalid captured buffer

    Currently, the a device is opened as non-blocking and the code uses select to be notified of buffer readiness. This appears to cause incomplete or incorrect buffers to be returned. This could be due to the driver still writing while buffer is being read. The current workaround has been to copy the buffer before making it available for use.

    Explore other approaches including blocking read, DMA, or direct device reads or make them all available at some point and let developer select which work best for device being tested.

  • add timestamp choice and conversion methods ?

    add timestamp choice and conversion methods ?

    i see from ffmpeg v4l2 , it has :

    /**

    • Return timestamps to the user exactly as returned by the kernel / #define V4L_TS_DEFAULT 0 /*
    • Autodetect the kind of timestamps returned by the kernel and convert to
    • absolute (wall clock) timestamps. / #define V4L_TS_ABS 1 /*
    • Assume kernel timestamps are from the monotonic clock and convert to
    • absolute timestamps. */ #define V4L_TS_MONO2ABS 2

    is it implemented in this project , i think it might be a useful feature .

    P.S. this project evolves a lot since my last visit , great job .

  • Exploring ways to integrate/automate C header files in porject

    Exploring ways to integrate/automate C header files in porject

    In #20, @ajcasagrande contributed code changes that copied the Kernel v4l2 header files from a specific commit. This provides for a more stable build experience because the code does not depend on the local machine to provide the header files. This is very useful, however @farshidtz pointed out, in the closed PR, that there could be some unforeseen additional issues.

    I am opening this issue provide a place to continue discussions on this and also propose additional ways of approaching this problem. There are some valid issues brought forth in the discussion above. I am doing some research to see how other Go projects handle this. What I have seen so far

    • Project that includes the headers, as is done here
    • Project that automatically pull a specific version at commit, via submodules

    I think there is a middle ground solutions that can be adopted, while avoiding any additional burden for users of this library.

    Possible solutions

    • Manually update header files and pinned to a specific version (as done now)
    • Creating a simple code gen (Makefile/script) to automates pulling header files for a specified Kernel version.
    • Will add more proposals as I continue to explore
Related tags
Go-video-preview-ffmpeg-wrapper - A simple helper wrapper to generate small webm video previews using ffmpeg, useful for web previews.

Go-video-preview-ffmpeg-wrapper A simple helper wrapper to generate small webm video previews using ffmpeg, useful for web previews. Getting Started u

Jan 5, 2022
A simple library to extract video and audio frames from media containers (based on libav).
A simple library to extract video and audio frames from media containers (based on libav).

Reisen A simple library to extract video and audio frames from media containers (based on libav, i.e. ffmpeg). Dependencies The library requires libav

Jan 2, 2023
lmmp3 is a little golang library that download a video from youtube, and convert it to a mp3 file using ffmpeg

lmmp3 lmmp3 is a function that download a video from youtube, and convert it to a mp3 file using ffmpeg You need to have installed ffmpeg in your syst

Aug 12, 2022
Personal video streaming server.

tube This is a Golang project to build a self hosted "tube"-style video player for watching your own video collection over HTTP or hosting your own ch

Jan 5, 2023
Short video direct link acquisition 短视频直连获取工具
Short video direct link acquisition 短视频直连获取工具

Glink 短视频去水印一键解析应用 Short video direct link acquisition 短视频直连获取工具 Glink是一款基于go语言开发的短视频解析应用,前端使用vue+argon主题,后端使用go-fiber框架,支持web在线模式、客户端模式。

Dec 7, 2022
Quik.do is a video conferencing tool.
Quik.do is a video conferencing tool.

Quik.do is a video conferencing tool.

Jan 3, 2023
Take control over your live stream video by running it yourself. Streaming + chat out of the box.
Take control over your live stream video by running it yourself.  Streaming + chat out of the box.

Take control over your content and stream it yourself. Explore the docs » View Demo · Use Our Server for Testing · FAQ · Report Bug Table of Contents

Jan 1, 2023
live video streaming server in golang
live video streaming server in golang

中文 Simple and efficient live broadcast server: Very simple to install and use; Pure Golang, high performance, and cross-platform; Supports commonly us

Jan 4, 2023
LiveKit - Open source, distributed video/audio rooms over WebRTC

LiveKit is an open source project that provides scalable, multi-user conferencing over WebRTC. It's designed to give you everything you need to build real time video/audio capabilities in your applications.

Jan 9, 2023
Stream video from ffmpeg to webrtc

ffmpeg-to-webrtc demonstrates how to send video from ffmpeg to your browser using pion.

Dec 28, 2022
Project to get Youtube video descriptions and search those videos as required

FamPayProject Project to get Youtube video descriptions and search those videos as required Prerequisities Postgres DB for persisting data Youtube Dat

Nov 5, 2021
Synthetic media is a realistic transformation of audio and video using artificial intelligence.

Synthetic media is a realistic transformation of audio and video using artificial intelligence.

Nov 20, 2021
Video converter with golang

Requirements Debian-like system (ubuntu, mint, etc...) with apt package manager Golang >1.15 Command tool make (use sudo apt install make -y to instal

Sep 10, 2022
golang function that download a video from youtube, and convert it to a mp3 file using ffmpeg

echedwnmp3 echedwnmp3 is a function that download a video from youtube, and convert it to a mp3 file using ffmpeg example package main import(echedwn

Dec 7, 2021
ffcommander - An easy frontend to FFmpeg and Imagemagick to automatically process video and manipulate subtitles.

% FFCOMMANDER(1) ffcommander 2.39 % Mikael Hartzell (C) 2018 % 2021 Name ffcommander - An easy frontend to FFmpeg and Imagemagick to automatically pro

May 9, 2022
A go program that relies on back-end ffmpeg to process video-related content

Video Compress A go program that relies on back-end ffmpeg to process video-related content Installation v-go You can download the corresponding v-go

Dec 22, 2021
👾 Annie is a fast, simple and clean video downloader built with Go.
 👾 Annie is a fast, simple and clean video downloader built with Go.

?? Annie is a fast, simple and clean video downloader built with Go. Installation Prerequisites Install via go install Homebrew (macOS only) Arch Linu

Jun 1, 2022
SlideXtract - A tool to help extract slides from a video file.

SlideXtract A tool to help extract slides from a video file. Slides are output in the out folder. Features I didn't find any other piece of code that

Jul 3, 2022
📽 MovieGo - Video Editing in Golang

?? MovieGo - Video Editing in Golang MovieGo is a Golang library for video editing. The library is designed for fast processing of routine tasks relat

Dec 26, 2022