37

I have two computers, a desktop in my office ( with a webcam attached ) and a laptop somewhere else on the network.

Usually I take a look at my office through my webcam by running

ssh Office -Y "mplayer tv://device=/dev/video0"

from my laptop. I don't like Xforwarding mplayer, so why can't I tunnel /dev/video to my pc by running this on my laptop?

sudo mkfifo /dev/video1
ssh Office 'dd if=/dev/video' | sudo dd of=/dev/video1'

and then to watch the webcam ( on my laptop )

mplayer tv://device=/dev/video1

6 Answers 6

27

If you have a low bandwidth I recommend compression of the video stream (still works in 2020).

with ffmpeg and mplayer

ssh USERNAME@REMOTEHOST ffmpeg -an -f video4linux2 -s 640x480 -i /dev/video0 -r 10 -b:v 500k -f matroska - | mplayer - -idle -demuxer matroska

where

  • -an turns off audio encoding. If you want audio, replace -an with -f alsa -ac 1 -i hw:3 (where hw:3 could also be hw:0 or hw:1, … See arecord -l for your device). If you want audio only (no video), use this)
  • -s 640x480 is the size of your video in x and y dimension
  • -r 10 is the framerate you want to receive (lower makes better images at low bitrates, but looks more bumby)
  • -b:v 500k is a bitrate of 500 kilobit/s

You need ffmpeg on the remote host and mplayer on the local machine installed.

with ffmpeg and mpv

ssh USERNAME@REMOTEHOST ffmpeg -an -f video4linux2 -s 640x480 -i /dev/video0 -r 10 -b:v 500k -f matroska - | mpv --demuxer=mkv /dev/stdin

with ffmpeg and ffplay

ssh USERNAME@REMOTEHOST ffmpeg -an -f video4linux2 -s 640x480 -i /dev/video0 -r 10 -b:v 500k -f matroska - | ffplay -f matroska /dev/stdin
5
  • 1
    Thank you for this solution. Trying to tunnel RTSP over SSH using ffmpeg/ffplay or some other solution involving http servers, etc, is so much more complicated than encoding to matroska and using stdout/stdin for the connection! Dec 21, 2021 at 19:43
  • For anyone getting the error message Unable to find a suitable output format for 'pipe:' pipe:: Invalid argument: when outputting to a Unix pipe, ffmpeg requires to have an output format explicitly specified, just as erik does in his answer: ... -f matroska - | ffplay ...
    – Abdull
    Mar 18, 2022 at 13:02
  • This one worked for me, but with a 10-second delay. Both computers are hard wired with cat5e to the same 1G switch.
    – JayRugMan
    Nov 12, 2022 at 21:38
  • @JayRugMan The delay comes from buffers being filled before playing. If you find a solution with smaller or zero buffers that have less delay you can comment here.
    – erik
    Nov 14, 2022 at 7:19
  • The mpv version doesn't work for me but the mplayer version does. mpv will complain about invalid input and exit while mplayer will wait a while and then play something with a huge delay.
    – cheezsteak
    Oct 22 at 23:57
16

Something like:

dd if=/dev/video0 | mplayer tv://device=/dev/stdin

works for me (SOA#1) locally. So does:

ssh localhost dd if=/dev/video0 | mplayer tv://device=/dev/stdin

As well as

mkfifo test
dd if=/dev/video0 of=test &
mplayer tv://device=test

Hence:

  1. Try without named pipe
  2. Check bandwidth

Also - how does in not work (display black screen, complains about unknown device etc.)?

6
  • I think something is wrong with my mplayer. If I run dd if=/dev/video0 | mplayer tv://device=/dev/stdin it tells me the resource is busy. Otherwise it works ( I see video ) even when I run mplayer tv://device=/dev/null
    – Stefan
    Sep 22, 2010 at 8:09
  • 2
    This answer is quite misleading. The "correct" invocation of mplayer would be mplayer tv:// -tv device=/dev/stdin or similar, but this does not work (character devices are more special than dd can handle properly). When you run mplayer tv://device=/dev/stdin it is not seeing a device specification and so falling back to /dev/video0 directly, giving the illusion of "working". But it won't work at all when the webcam and mplayer process are separated by the network. Mar 28, 2017 at 21:59
  • 2
    Yes, this looks like it's working right because you're SSH'ing to localhost, but in reality it's failing and mplayer is falling back to /dev/video0 on localhost. If you try these commands SSHing to a different computer (i.e. not localhost), you'll see your local webcam, not the remote one. Sep 27, 2017 at 11:02
  • You tried in local host but how to run the command ssh localhost dd if=/dev/video0 | mplayer tv://device=/dev/stdin when using two different computers? Nov 15, 2018 at 10:27
  • What is an alternative of mplayer tv://device=/dev/stdin on OSX? Nov 15, 2018 at 10:35
5

The accepted answer does not work for me. dd simply won't read it. nc is bad if you cant spare another port (I didn't get that to work at all either anyway). cat didn't work for me either.

What ended up working for me was this on the receiving end:

ssh user@host "ffmpeg  -r 14 -s 640x480 -f video4linux2 -i /dev/video0 -f matroska -" | mplayer - -idle

This has the benefit of it being encoded, so you save bandwidth as a bonus. Nothing else on any forum/website was working for me on a debian machine.


Combine with tee and you can watch and record at the same time:

ssh user@host "ffmpeg  -r 14 -s 640x480 -f video4linux2 -i /dev/video0 -f matroska -" | tee $(date +%Y-%m-%d_%H-%M-%S)_recording.mkv | mplayer - -idle

This will open mplayer for live streaming and save it to a file containing the current datetime at the same time (example filename: 2018-11-22_01-22-10_recording.mkv).

1
  • Seems like less of a delay than the similar answer above. Good show. Thanks.
    – JayRugMan
    Nov 12, 2022 at 22:15
4

The VideoLAN Project exists in large part to do just what you desire.

I've not used its streaming capabilities but in its single machine use it has shown to be rock solid for me.

2
  • 1
    And so, could you elaborate for this scenario, please ...?
    – MikeW
    Jun 23, 2017 at 9:10
  • -1, the question is about streaming over SSH. VLC's unencrypted stream is useless by itself
    – Navin
    Jun 12, 2021 at 8:09
0

I don't know if there's any reason you can't do it, but one problem I see with your implementation is that the remote system will look for /dev/video1 on its system, but won't be able to find it because you created it on your local system.

What I'd do is something along the following

nc -l 12345 | sudo tee /dev/video > /dev/null &
ssh Office

and then try something by telling it to go to your local system's TCP port 12345.

1
  • 1
    I tried clarifying my question. please see the updated version
    – Stefan
    Sep 21, 2010 at 13:47
0

This isn't the best option as far as quality, but cool, nonetheless. If you have VLC installed on the remote computer and ssh to it from a terminal, you can run the following command and get video streamed from the remote web-cam to your terminal in ascii art. I stumbled across this cool feature when trying to do what the OP is doing with a command that works locally to open the camera with VLC.

Locally, this will open a window with video streaming normally from your web camera:

[me@myComp /some/dir]$ cvlc v4l2:///dev/video0

Remotely, first ssh just for a remote terminal, then run the same comand

[me@myComp /some/dir]$ ssh person@otherComputer
...
[person@otherCompter /some/dir]$ cvlc v4l2:///dev/video0

vuala, ascii video from the remote web cam. If you zoom the terminal out, you get better resolution, but worse frame-rate. There's a happy medium somewhere in there - just fiddle with it some. Anyway, not high-quality, but still awesome!!

Note, to stop the feed, I've had to ssh to the remote machine in another terminal and kill vlc from the command line.

[me@myComp /some/dir]$ ssh person@otherComputer
...
[person@otherCompter /some/dir]$ killall vlc

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .