How to record webcam video signal with video4linux2? - linux

I need to record a video from my webcam with ffmpeg.
I tried with this command : ffmpeg -re -f video4linux2 -i /dev/video0 video.avi.
And I received that : The v4l2 frame is 24384 bytes, but 153600 bytes are expected.
When I try the same operation with avconv with this command : avconv -f video4linux2 -i /dev/video0 video.avi I received the same error.
But I can receive the video from my webcam with this command: gstreamer-properties.
How to configure v4l2 to get signal video from my webcam ?

The problem come from virtual box.
It recognize my webcam the first time during my test but after just as a USB device.
I set USB device to webcam and now I can stream or convert videos with ffmpeg.

Related

How to change mjpeg to yuyv422 from a webcam to a v4l2loopback?

Backstory: One livestreaming site I use isn't smart enough to detect the capabilities of my webcam (Logitech Brio, 4k), and instead just uses the default frames per second settings, which is 5fps.
(full solution walk-through in the answer)
The best solution I could think of (besides changing livestream providers) was to create a loopback virtual webcam using v4l2loopback that I could force to have the exact settings I wanted to use on that livestream site.
For the brio, the higher frame rates come with mjpeg, not the default yuyv.
Problem 1:
I could easily read mjpeg, but unfortunately kept banging my head against the wall because v4l2loopback evidently only wanted yuyv.
I tried things like:
ffmpeg -f v4l2 \
-input_format mjpeg \
-framerate 30 \
-video_size 1280x720 \
-i /dev/video0 \
-vcodec copy \
-f v4l2 /dev/video6
and
ffmpeg -f v4l2 \
-input_format mjpeg \
-framerate 30 \
-video_size 1280x720 \
-i /dev/video0 \
-vcodec yuyv422 \ # this line changed (even tried "copy")
-f v4l2 /dev/video6
But they wouldn't work. I got errors like:
Unknown V4L2 pixel format equivalent for yuvj422p
and
...deprecated pixel format used, make sure you did set range correctly...
...V4L2 output device supports only a single raw video stream...
Eventually I got this to work:
ffmpeg -f v4l2 \
-input_format mjpeg \
-framerate 30 \
-video_size 1280x720 \
-i /dev/video0 \
-pix_fmt yuyv422 \ # The winning entry
-f v4l2 /dev/video6
Problem 2
The next problem was getting chrome to see the virtual webcam. It worked correctly with guvcview, and on firefox I could use webcam testing sites and it would pick the virtual camera up without a problem.
Turns out google, in it's overly-protective nature (while it's siphoning off all our data, btw), doesn't want to use webcams that can be read and written to.
So when starting v4l2loopback you have to tell it to announce that it's "read only" to consumers like chrome.
Here's the exact modprobe I use that works:
sudo modprobe v4l2loopback devices=1 exclusive_caps=1
Exact solution.
1. Figure out which webcam is the correct input webcam
Use v4l2-ctl to list all the webcams:
v4l2-ctl --list-devices
My output is this (yours will vary, I'll use mine as an example as I go):
Logitech BRIO (usb-0000:00:14.0-5.2):
/dev/video0
/dev/video1
HP HD Camera: HP HD Camera (usb-0000:00:14.0-9):
/dev/video2
/dev/video3
/dev/video4
/dev/video5
In this case my brio is video0.
2. Start v4l2loopback:
sudo modprobe v4l2loopback devices=1 exclusive_caps=1
3. Confirm your loopback device:
v4l2-ctl --list-devices
Mine now shows this, indicating video6 is the loopback:
Dummy video device (0x0000) (platform:v4l2loopback-000):
/dev/video6
Logitech BRIO (usb-0000:00:14.0-5.2):
/dev/video0
/dev/video1
HP HD Camera: HP HD Camera (usb-0000:00:14.0-9):
/dev/video2
/dev/video3
/dev/video4
/dev/video5
4. Determine your optimal input settings
Use guvcview to figure out which codec gives you the resolution and framerate you're looking for (you may have to use the menu -> Video -> Video Codec -> Raw camera input).
I got 60fps using mjpeg, I only needed 30. The default yuyv gave a miserable 5fps.
Now use ffmpeg to list the capabilities of the camera and get the matching codec:
ffmpeg -f v4l2 -list_formats all -i /dev/video0 #use your camera here from step 2
In the output you'll see something like this:
[video4linux2,v4l2 # 0x55f1a4e989c0] Raw : yuyv422 : YUYV 4:2:2 : 640x480 160x120 176x144 320x180 320x240 352x288 340x340 424x240 440x440 480x270 640x360 800x448 800x600 848x480 960x540 1024x576 1280x720 1600x896 1920x1080
[video4linux2,v4l2 # 0x55f1a4e989c0] Compressed: mjpeg : Motion-JPEG : 640x480 160x120 176x144 320x180 320x240 352x288 424x240 480x270 640x360 800x448 800x600 848x480 960x540 1024x576 1280x720 1600x896 1920x1080
In my case it was the mjpeg that gave the best output in guvcview, and that was the exact name of the codec (as indicated above).
5. Start ffmpeg using that input codec and changing the pixel format to yuyv:
ffmpeg -f v4l2 \
-input_format mjpeg \
-framerate 30 \
-video_size 1280x720 \
-i /dev/video0 \
-pix_fmt yuyv422 \
-f v4l2 /dev/video6
Update the video size to the highest size your livestream/video record will support, as long as your camera also supports it.
Now when you want to livestream, just use the camera labeled "Dummy"

Linux command to display webcam video output in full screen?

I'm using an rpi1 (running raspbian lite and jwm) with a USB webcam hooked to a CRT TV to display its output. Up until now I've been using Camorama which works nicely, but I lose some of the measly 640x480 screen resolution for the title bar of the app, and also some of it below due to the window manager showing buttons etc that I don't need. Is there any way I can simply show up the video output of the device in a full screen window? so I can just add it to the startup of the window manager and run it on top of it. I really don't need any of the features that Camorama has because all I want is to display video ala security camera.
Display webcam output from Linux
Note: Adjust with and height where necessary
mplayer tv:// -tv driver=v4l:width=352:height=288
or
mplayer tv:// -tv driver=v4l2:width=640:height=480:device=/dev/video0:fps=30:outfmt=yuy2
How to Record a Screencast & Convert it to an mpeg
ffmpeg -f x11grab -r 25 -s 640x480 -i :0.0 /tmp/VideoOutput.mpg
Record audio and video from webcam using ffmpeg
Record webcam audio using ALSA, MP3 encoded & video as MPEG-4.
ffmpeg -f alsa -r 16000 -i hw:2,0 -f video4linux2 -s 800x600 -i /dev/video0 -r 30 -f avi -vcodec mpeg4 -vtag xvid -sameq -acodec libmp3lame -ab 96k myVideo.avi
Hope this helps.

Streaming RTP audio over Ethernet with avconv

I have two laptops connected with a Ethernet cable and I'm trying to transmit an audio stream between them.
The IPs are 192.168.137.93 for the sender and 192.168.137.1 for the receiver. The receiver runs the DHCP server and provides Internet connection for the sender, and connectivity works well.
I'm running this command on the sender(Ubuntu Server) to capture audio from internal mic and send it to the receiver through RTP.
avconv -f alsa -ac 1 -i default:0 -acodec mp2 -b 64k -f rtp rtp://192.168.137.1:8000
On the receiver(Windows 10) I open VLC and I try to reproduce
rtp://192.168.137.1:8000
but I get no sound.
If I open the network monitor on the receiver I can see that there's incoming traffic, and if I try to stream and play on the same machine (the sender) with
avconv -f alsa -ac 1 -i default:0 -acodec mp2 -b 64k -f rtp rtp://192.168.137.93:8000
aplay -i rtp://192.168.137.93:8000
it works flawlessly!
I can't really figure out where the problem is.
UPDATE:
Ok, problem solved. Apparently VLC doesn't like mp2. Switched to -acodec libmp3lame and now works!
Next problem: latency. There's something like 1 second of delay between the mic and the receiver's loudspeaker. I think that's a matter of codec, because there's a huge delay even running sender and receiver on the same machine.
What's the lightest codec that fits for low-latency audio transmission?

ffmpeg - Stream webcam - RTP h264 + audio

I am trying to create a rtp stream using ffmpeg. I am taking input from my logitech C920 which has built in h264 encoding support and also has a microphone. I wanted to send both video(h264 either with the built in encoder or ffmpeg's encoder) and audio(any encoding) through RTP and then play the stream using ffplay.
So far I am able to send only the video with the following command:
ffmpeg -i /dev/video0 -r 24 -video_size 320x240 -c:v libx264 -f rtp rtp://127.0.0.1:9999
and also the audio separately using the command:
ffmpeg -f alsa -i plughw:CARD=C920,DEV=0 -acodec libmp3lame -t 20 -f rtp rtp://127.0.0.1:9998
and play the sdp file with:
ffplay -i -protocol_whitelist file,udp,rtp test3.sdp
ffplay -i -protocol_whitelist file,udp,rtp test4.sdp
I'm on Ubuntu 14.04
How can I play the two streams with a single ffplay command as ffplay cannot take two inputs and I can't send two streams using a single RTP stream(or can I?).
Also, how can I use the built in h264 encoder of my webcam?
Thank you!

How to stream on YouTube using a Raspberry Pi?

So I'm trying to stream on YouTube using a raspberry pi. The idea is for one raspberry pi to be used to stream the connected webcam and for another to display the stream, sort of like a surveillance camera. Both raspberry pi's are currently using Raspbian.
So is it possible for me to stream directly to YouTube on a Raspberry Pi.
You can use any Pi supported RTMP/Flash encoder to publish a YouTube live event. One example is ffmpeg which can be compiled on Raspbian.
Create your YouTube live event using the guide. You can find the various encoder settings here.
When everything is ready you can start streaming. For a 640x480#25 700k video stream the command will be something like:
ffmpeg -f v4l2 -framerate 25 -video_size 640x480 -i /dev/video0 -c:v libx264 -b:v 700k -maxrate 700k -bufsize 700k -an -f flv rtmp://<youtube_rtmp_server/<youtube_live_stream_id>
"So is it possible for me to stream directly to YouTube on a Raspberry
Pi?"
Yes. But you're going to need to do a bit of configuring and get different hardware depending on your project needs.
For my project, a day and night doorway "security camera" that streams live to youtube, I chose a Raspberry Pi Zero W running raspbian (headless) and a camera module with auto IR switching capabilities and IR lights.
I have edited the raspbian image so all of the configurations of the wifi and camera module interfaces, code, and dependencies I need are pre-installed, so I can just flash an sd card, slap it in a pi+camera+powersupply setup and it does its thing.
So, for this answer to be helpful at all, you're going to need to do plenty of research on FFMPEG, know what it is, learn what it does, and get it installed on your board... You should be able to run a few tests getting FFMPEG to just spit out maybe a 10-second long video from your camera. I wouldn't bother reading any more of my ramblings if you have not got that far yet, because things are about to get specific.
So, your board is online, you can see it on the network, it's got internet, it's got ffmpeg, it's ready to go.
Here is the ffmpeg "stream command" I use to start the live stream:
raspivid -o - -t 0 -vf -hf -fps 60 -b 12000000 -rot 180 | ffmpeg -re -ar 44100 -ac 2 -acodec pcm_s16le -f s16le -ac 2 -i /dev/zero -i - -vcodec copy -acodec aac -ab 384k -g 17 -strict experimental -f flv rtmp://a.rtmp.youtube.com/live2/SESSION_ID
I arrived at this "stream command" above by tweaking each parameter you see, one by one, and in different combinations and I eventually got a really crisp 1080p stream with no buffering issues at all except for the occasional bit of wifi lag that comes around on my setup. You are going to need to do a ton of research into what every parameter does to get things just right and trust me it's going to be a pain figuring out what does what in the beginning. I would lurk all around StackOverflow and other resources and just plug around and see what you can get to come out of your setup when it comes to these FFMPEG commands.
To test if this "stream command" or any other you find works for you, just change SESSION_ID at the end to your stream key and run it in the console.
After you get an output you are happy with, figure out on your own how you want to trigger your camera to start streaming, if you want it to start recording as soon as the board is ready to start sending data, you accomplish this by putting your "stream command" in /etc/rc.local and it will run that command as soon as it can.
For my project, I use 18650 cells charged by solar panels as the power source so I have to be conscious about the power I use so I wrote some NodeJS program monitor just that.
Alright, that's enough talking into the wind for now. Hopefully, any of this helped someone out there, cheers.
Audio working! This worked for me from a raspberry pi 4 with an rbp v1.3 camera and cheap usb audio interface. Also gets the default audio which you can set in the alsamixer:
raspivid -o - -t 0 -vf -hf -fps 30 -b 6000000 | ffmpeg -f alsa -ac 1 -ar 44100 -i default -acodec pcm_s16le -f s16le -f h264 -i - -vcodec copy -acodec aac -ab 128k -g 60 -strict -2 -f flv rtmp://<destination/streamkey>

Resources