How to use a remote firewire port and transcode DV video locally with ffmpeg
I recently moved into another appartment and found some old VHS tapes I recorded years ago. As luck would have it, I got my hands on a VCR and a MiniDV camcorder with builtin ADC, so I can get analog video signals into the MiniDV camcorder. So all I needed was a computer with firewire or IEEE1394 port. The only computer I have that still has a firewire port is my server, so I hooked the VCR to the MiniDV and the MiniDV to my server.
Since the server is running without a desktop environment and without an X Server I needed command line tools to access the firewire port. After a little search on the internet I came across a tool called dvgrab. With dvgrab you can dump DV video from a firewire device to a file or to stdout. In order to use dvgrab as a normal user, the firewire device (in my case /dev/fw0) needs to belong to a group the user is part of, e.g. video. You can find out the device name with
$ dmesg | grep -i -E "fw|firewire|1394"
With a simple
$ dvgrab test.dv
I was able to record the camera signal to the file test.dv. Since DV video takes a lot of diskspace, I wanted to transcode it to h264 video with aac audio, but I didn’t have ffmpeg installed on my server and didn’t want to install it, so I needed a way to get the video to my laptop and transcode it there. The first thing that came to my mind was netcat, so I looked up funkym0nk3y’s post An introduction to netcat and did the following:
On the client side (my laptop):
$ nc -lv 1234 | ffmpeg -y -i pipe: -c:v libx264 -preset slow -b:v 500k -r:v 25 -bufsize 1000k -threads 0 -strict -2 -c:a aac -b:a 192k dvgrab.mp4
On the server side:
$ dvgrab - | nc -vw10 <IP.of.my.laptop> 1234
I waited a few seconds, pressed play on the VCR, transcoded the video in realtime and when it was done I pressed
Ctrl+c on the client side to terminate the recording. And voila… I have a crystal clear h264 with aac version of my old VHS tape on the harddrive of my laptop.
If you don’t want to use two terminals, you can also run both commands from the client and execute the server command through SSH like such:
$ nc -lv 1234 | ffmpeg -y -i pipe: -c:v libx264 -preset slow -b:v 500k -r:v 25 -bufsize 1000k -threads 0 -strict -2 -c:a aac -b:a 192k dvgrab.mp4 & ssh <username>@<IP.of.my.server> "dvgrab - | nc -vw10 <IP.of.my.laptop> 1234"
After the recording was done, I used ffmpeg to trim the beginning and the end of the recorded video. I noted down the timecodes of the first and last frame I wanted to have in the recording and did
$ ffmpeg -i dvgrab.mp4 -c copy -ss 0:00:05.12 -to 1:37:42.56 my_old_vhs_tape.mp4
and finally removed the recorded raw file with
$ rm -f dvgrab.mp4
In a similar manner you can use netcat to stream all other sorts of media to another computer. For instance, I used this method to get the audio signal from my TV to my laptop so I didn’t have to use a long cable to listen to the TV with headphones. The simplest and fastest way I found was using the alsa tools
arecord on the server side and
aplay on the client. I kept the buffer size parameterized to experiment with different sizes and thus latencies. I managed to keep the overall latency under one frame, so you don’t realize any delays (except when you also turn on the TV’s speakers). With
$ aplay -l I found the IDs of the audio devices I needed to use and with
alsamixer I set up the audio channel to “record” on the server side. To finally get the audio signal to my laptop I ran
$ BS=360; nc -lv 1234 | aplay -Dhw:1,0 --buffer-size $BS & ssh <username>@<IP.of.my.server> "arecord -Dhw:2,0 -f dat --buffer-size $BS | nc -vw10 <IP.of.my.laptop> 1234"
Posted on November 14, 2014, in Audio / Video, Command-Line, Network and tagged alsa, dv, ffmpeg, firewire, h264, linux command line, Linux M0nk3ys, Linux Monkeys, linuxmonkeys, mini-dv, netcat, ssh. Bookmark the permalink. Leave a comment.