Playing Video Files on Your TV with minidlna

Playing Video Files on Your TV with minidlna

One of my presents from Christmas a few years back was a Sony smart blu-ray player. It was marketed as something that easily streams files from your computer. That is absolutely true for anyone that runs Windows, just point and click. With Ubuntu, it’s a bit more complicated. Enter minidlna.


First thing, install minidlna. Open a terminal (Ctrl-Alt-t) and type this in:

sudo apt-get install minidlna

If you’d rather use the package manager, just search for minidlna.


The configuration file is editable by running this in the terminal:

sudo gedit /etc/minidlna.conf

There are 2 settings to note: media_dir and friendly_name. The names used are pretty explanatory. Here’s an example of what to update:

# Path to the directory you want scanned for media files.

# Name that the DLNA server presents to clients.

Save and close the file. On the terminal run this to refresh minidlna:

sudo service minidlna restart

That’s it! minidlna is all setup to server the files and folders in your media_dir.

ssh: Remember each host’s settings

ssh: Remember each host’s settings

When you start using ssh to connect to other linux-based computers, you’re probably only going to a handful of machines. Easy enough to remember the username and hostname, but this won’t do when you’re working on 5 or more servers, especially if some offer ssh on a non-default port.


In this file, you can set all the options for each host, including the username, host or ip, port, even which key to use. Here’s an example:

#Contents of $HOME/.ssh/config
Host dev
User dev-deploy
Port 2222
IdentityFile ~/.ssh/id_rsa.deploy.key

Host prod
User prod555deploy
Port 5899

User admin123
Port 5899

It’s that easy! To use this config information, simply ssh:

ssh prod

Happy Computing!

XFS PVR/DVR maintenance

Last year, I purchased an HDTV tuner card and started using my computer as a Personal Video Recorder, or PVR. Basically, a small program records a tv show to the hard drive. This did quite well until March when it would stop recording after 5 seconds to 15 minutes for no apparent reason.

After about a month of research, I had ruled out just about everything under the sun. Then, it hit me … the file system might need defraging. The file system I am using is XFS, and they can get fragmented over time, especially if you have big files (HD-MPEGs) and little free space.

The command to defrag all mounted (and keeps them read-write) XFS filesystems is:

xfs_fsr -v

After running this, shows started recording better, but still stopped. So, I wanted to see just how fragmented everything was. I found this command:

xfs_db -r /dev/sda3

That starts an interactive XFS debug session for sda3, my XFS partition. Three useful commands are freesp, frag and quit. frag reported over 15% fragmentation and freesp reported a lot of small blocks and very few large blocks.

Finally, I got to the heart of the matter: defrag programs do not operate efficiently with less than a certain amount of free space. My drive had 20GB free out of 250GB total. I deleted a few HD shows to bring it up to 45GB free and ran the defrag command again.

Voila! Less than 6% fragmentation and plenty of free big blocks. My recordings are almost flawless now. At least they don’t stop for no reason. So, if you’ve got an XFS file system:

  • make sure to run the xfs_fsr command regularly
  • if you’re filesystem is still fragmented, burn/remove some junk and repeat

GCC 4.5

Over the last week, I’ve been updating my eeePC’s Gentoo linux to run GCC 4.5 and recompiling every package. The main reason is that now almost all my software is fully optimized for the Intel Atom processor. With only 1 relatively small hack, the rebuild went fairly smooth and my CFLAGS now contain “-march=atom -mtune=atom” !

The one small hack was placing a sed command inside the gcc 4.5 ebuild. It will build the first time without the command, but all subsequent builds will fail with an error that stage 2 and stage 3 are different. Here’s the line added to the src_unpack part of the ebuild: (Note: wrapping added)

[[ ${CFLAGS} == *-march=atom* ]] && sed -i 
    -e 's/(INSN_P/(NONDEBUG_INSN_P/g' 
    -e 's/!INSN_P/!NONDEBUG_INSN_P/g' 

To keep it safe, the line check if you $CFLAGS has -march=atom in it. If so, then it runs the following sed command. Originally issued as a patch for gcc for all of us running an Atom processor(s), I swapped it around to a sed command, as a few forum posts pointed out.

Beyond making the ‘overlay ebuild’, there was only 1 other snag, and that was binutils. Using the new gcc, binutils just wouldn’t compile. The error was about the movbe instruction. Upgrading from 2.18 to 2.19 using the old gcc compiler did the trick. After that it was just a matter of waiting for all the packages to recompile.

If anyone is thinking about upgrading to gcc 4.5 on gentoo, it’s not all that bad. Make sure to read the Gentoo GCC Upgrading Guide before you do anything. Also, run a “cat /proc/cpuinfo” to get the model of atom processor and make sure your CFLAGS are set properly.

HDTV using MPlayer

In my desktop computer, I’ve got an nvidia GeForce 6150 PCI-E video card. It has a built-in mpeg2 decoding helper in it. Using Linux, this is called XvMC, or Xvideo Motion Compensation. I finally got it partially usable.

I’m currently watching the news on WJBF, the only channel I get b/c I haven’t fully setup my antenna. Using xvmc is fairly simple:

mplayer -vc ffmpegmc12 -vo xvmc -framedrop dvb://WJBF-DT

I add -framedrop to keep the video and audio sync’ed.  Mplayer will rant about waiting for retrace. Using OpenGL is actually better, for me at least.

mplayer -vo gl2 -framedrop dvb://WJBF-DT

It dropped 14 frames at the beginning, but hasn’t dropped another in 10 minutes. XvMC would have crapped out by now. A/V sync is still perfect. I’ve even got it full screen and it’s resizing from 1280×720 (720 HD resolution) to 1440×900.

X11 Forwarding

A few days, I moved my desktop computer out into the living room. The computer has a tuner card that can receive digital broadcasts. I don’t own a TV, so this is the closest I’ve got to one. I still have to set up lircd before I can use a remote, but I wanted something a bit easier

Today, I discovered a new trick … SSH X11 Forwarding. Now, I can play video on my desktop right from my netbook. It’s wonderful and very simple!

In the following instructions, the “A” refers to the computer playing the video and “B” refers to any other computer.

  1. Make sure “X11Forwarding Yes” is in your sshd_config file on computer A. Restart sshd if you had to uncomment/add it.
  2. On B, run `ssh -XC A`
  3. In the ssh session, type `DISPLAY=:0.0`.
  4. Now run mplayer or any other video player in the  ssh session and it will play on computer A.

If you want  to have a program run on computer A and use the screen on computer B, the process is very similar:

  1. Make sure “X11Forwarding Yes” is in your sshd_config file on computer A. Restart sshd if you had to uncomment/add it.
  2. On B, run `xhost A`
  3. On B, run `ssh -XC A`
  4. Now run mplayer or any other video player in the  ssh session and it will play on computer A.

Step 2 authorizes use of the current display by computer A and only needs to be run once. Also, note that the display variable doesn’t need to be set when using B‘s screen.

Mplayer works wonderfully when playing on my desktop, plus I control it via the ssh session. It has tons of keyboard shortcuts. The ones I use the most are space for pause and the arrow keys for skipping around.

PVR Update

In anticipation of TV shows coming back on, I’ve been tweaking my PVR scripts. These record shows from the digital airwaves right onto my computer. I’ve separated the script into two parts: recording and encoding. Each is a simple one line shell script that can be called easily from the command line or from a cron. The script is:

/usr/bin/mencoder dvb://$1 -ovc copy -oac copy -o "$2.mpeg" -endpos $3

All this does is copy the video and audio streams directly to the disk. The three parameters are  the station name, as stated in ~/.mplayer/channels.conf, the filename and the end position. This end position can be the number or seconds to record, or a time format of hh:mm:ss. This makes recording fairly simple within the cron.

The script contains:

/usr/bin/mencoder -vf scale=640:-2 -ovc xvid -xvidencopts bitrate=1700:threads=2 \
 -oac copy "$1" -o "$1.avi"

This, slightly more complex use of mencoder, will scale the video to 640 wide, the height calculated to keep the aspect ratio. The video is encoded into xvid at 1700kbps using 2 threads. To speed up the encoding process, the audio is not re-encoded, but copied as is.

You will need to play with the number of xvid threads to find the best fps. I have a dual-core and it encodes the fastest with 2 threads. It does need to be an integer, and most dual-cores will work best at 2.

Then, two lines are required in the cron to record and encode the program:

59 19 * * 1 /dvr/ WAGTNBC /dvr/shows/heroes 01:03:00
05 20 * * 1 /dvr/ /dvr/shows/heroes.mpeg

Mencoder Cheat Sheet

Mencoder is a video encoder for linux. It is part of the mplayer package which also includes a video player. This tool is quite versatile and can do pretty much any kind of video processing all from the console.

As with any linux tool, there a tons of bells and whistles. This makes the learning curve kind of steep, but with a bit of determination anyone can make sense of it. Without further ado, here’s the cheat sheet:

mencoder clip1.avi clip2.avi -ovc copy -oac copy -o new-clip.aviCopies clip1 and clip2 into new-clip.avi
mencoder clip.avi -ovc xvid -xvidencopts bitrate=800  -oac lamemp3 -lameopts cb:br=128 -o new-clip.aviEncodes a clip with the xvid codec at 800Kbps and mp3 audio at 128Kbps.
mencoder clip.avi -ovc xvid -xvidencopts bitrate=800:threads=2  -oac lamemp3 -lameopts cbr:br=128 -o new-clip.aviSame as above, but uses 2 threads for the xvid encoding.
mencoder clip.avi -endpos 00:05:00 -ovc copy -oac copy -o new-clip.aviCopies the first 5 minutes from clip.avi into new-clip.avi
mencoder clip.avi -endpos 00:05:00 -ss 00:01:00 -ovc copy -oac copy -o new-clip.aviCopies 5 minutes from clip.avi into new-clip.avi, skipping the first minute.
mencoder dvb://WJBF-DT -endpos 01:0000 -ovc copy -oac copy -o ugly.betty.mpegTunes to WJBF-DT, records 1 hour of that station to ugly.betty.mpeg
mencoder clip.avi -vf scale=640:-2 -ovc xvid -xvidencopts bitrate=1200:threads=2 -oac copy -o new-clip.aviResizes the video to 640 wide, keeping the aspect ration, then encoding video using xvid at 1200Kbps and copying the audio directly
mencoder tv:// -tv driver=v4l2:width=640:height=480:device=/dev/video0 -ovc lavc -o >(tee webcam-`date +%Y-%m-%d-%H.%M.%S`.avi | mplayer -cache 128)Records the webcam to “”, where that is the date, and display it to the screen while recording.
mencoder -idx clip.avi -ovc copy -oac copy new-clip.aviFixes the AVI index of clip.avi, the output being new-clip.avi
mencoder clip.avi -vf cropdetect -o /dev/nullDetects what cropping is needed
mencoder clip.avi -of mpeg -mpegopts format=dvd -lavcopts vcodec=mpeg2video:vbitrate=5000:acodec=ac3 -o dvd-clip.mpegEncodes clip.avi into a dvd-compatible mpeg at 5000Kbps
mencoder -dvd 2 -ovc lavc -lavcopts vcodec=mpeg4 -oac copy -o dvd.aviRips a DVD to dvd.avi

PVR Cron

For about a year now, I’ve been playing around with my digital tuner card. It wasn’t until I turned off the cable that I have a need to use it. Using some cool linux tools, I’ve made a script to record HDTV broadcasts to my computer. It is a work in progress, but here’s what I’ve got so far.

The Tuner Card
The tuner card is DVB based on a Conextant chipset, so the first step was to get my kernel to make the card usable. A quick check will show if the driver is loaded:

dmesg | grep dvb

The Tools Required

  • dvb-atsc-tools
  • azap
  • ffmpeg

Channel Scan
Scan for channels using:

dvbscan /usr/share/dvb/atsc/us-ATSC-center-frequencies-8VSB > ~/.azap/channels.conf

Edit the file ~/.azap/channels.conf to make sure the channel names are correct. Your base frequencies file may be in a different location, but it is usually under /usr/share.

Iteration 1: Crontab Recording
At first, I used only the crontab to record. Here’s an example:

24 12 * * * /usr/bin/azap -c /home/dvr/.azap/channels.conf -r WRDW-HD
25 12 * * * /bin/cat /dev/dvb/adapter0/dvr0 > /data/dvr/young-restless.mpeg
35 13 * * * /usr/bin/pkill cat
36 13 * * * /usr/bin/pkill azap
37 13 * * * /usr/bin/ffmpeg -i /data/dvr/young-restless.mpeg -s 1024x476 -vcodec libxvid -b 1600000 -acodec copy /data/dvr/y-r-friday.avi

This is a very ugly solution with lots of cracks. For instance, if I were running cat from a console when /usr/bin/pkill cat were running, it would die. Heaven forbid another processes is using cat when that runs. Also, I had to change the name of the ffmpeg output file every day.

Iteration 2: Cronable Perl Script
This script does pretty much the same thing as the above 4 lines in the crontab does. This means you don’t have to write 4 lines in the crontab for each recording, just 1 line. Also, the file name is appended with the date in yyyy-mm-dd format.


#Does someone need a reminder?
if ( $#ARGV != 2 ) {
print “Usage:\n”;
print “ \n”;

#Creates a random 16 character (a-z) string
sub randstr {
my @chars=(‘a’..’z’);
my $res = “”;
for(my $i=0;$i<16;$i++) {
$res .= $chars[rand($#chars)];
return $res;

#Grab the command line args
my ( $channel, $length, $finalFileName ) = @ARGV;

#Temporary mpeg filename
my $tempFileName = randstr();

#Add date to final filename
$finalFileName .= “-“.`date +%Y-%m-%d`;
$finalFileName =~ s/\n//;

#Start Azap in the background
print “Starting azap\n”;
system( “/usr/bin/azap -c /home/barry/.azap/channels.conf -r $channel >/dev/null 2>/dev/null &” );
sleep 5;

#Start cat in the background
print “Starting cat\n”;
system( “/bin/cat /dev/dvb/adapter0/dvr0 > /data/dvr/$tempFileName.mpeg &” );

#Sleep the required seconds for the show to record
print “Recording for “.(60*$length).” seconds…\n”;
sleep 60*$length;

#TODO: Remove pkill, as it may cause problems
print “Killing cat and azap.\n”;
`pkill cat`;
`pkill azap`;

#Resize & Encode to XVID using ffmpeg
#ffmpeg sometimes stops working b/c of bad mpeg data
#TODO: Replace with mencoder
print “Encoding…\n”;
`/usr/bin/ffmpeg -i /data/dvr/$tempFileName.mpeg -s 1024×476 -vcodec libxvid -b 1600000 -acodec copy /data/dvr/$finalFileName.avi`;

#Remove the temporary mpeg file
`rm $tempFileName.mpeg`;

print “Done!\n”;

I know it’s not the most elegant of perl scripts, but it gets the job done. Here’s a sample cron:

25 12 * * * /home/dvr/ WRDW-HD 70 young-restless

As you can see from the TODO comments, I continue to tinker with the script. When I make a good development, I’ll post it. If you have any suggestions, feel free to post a comment or contact me.