Install Notes for MythTV and Mythbuntu

These notes describe how to set up a Mythbuntu-based MythTV system for recording of television programs, via both over the air and cable, viewing of movies from a video server, viewing of streams, etc. They also describe setup of various auxilliary processes such as email and UPS monitoring, and system maintenance functions. Installation of various pieces of hardware, such as encoders and IR recievers/blasters, is also covered.

BIOS Configuration

Before you even begin the Mythbuntu installation, there are a few things that you might want to configure on your system through the BIOS setup program. Boot the system into the BIOS setup screen by pressing the proper key on the keyboard (e.g. "Del") at bootup. Here are some option settings to consider:

Usually on the Main screen:

     Legacy Diskettes:             Disabled
     HDD SMART Monitoring:         Enabled

If you are using a motherboard with a built-in display adapter, you can usually find its configuration on the Advanced Configuration screen. Look around -- sometimes its on the Southbridge configuration page:

     Shared or Stolen Memory:      32M (or whatever the lowest number is above
                                   32M)
     Mythbuntu composes frames and loads them into the frame buffer as the
     become available.  As such, the CPU does all the work and there is no need
     to provide the GPU with a large frame buffer.  However, if you are using
     VDPAU, that's a whole 'nother story.

If you have an AMD processor and a motherboard that supports it, you can usually find the AMD-specific options on the Advanced Configuration screen:

     AMD Virtualization:           Disabled
     AMD Live!:                    Enabled
     AMD Cool 'n' Quite Function:  Auto (or Enabled)

Usually on the Power/APM Configuration screen:

     Restore on AC Power Loss:     Enabled

Usually on the Power/APM Configuration or Hardware Monitor screen:

     Q-Fan Controller:             Enabled

On the Boot/Boot Device Priority screen:

     1st Boot Device:              CDROM (this allows you to attach a CDROM as
                                   a diagnostic tool at any time)
     2nd Boot Device:              Hard Disk
     3rd Boot Device:              Disabled
     4th Boot Device:              Disabled

On the Boot/Boot Settings Configuration screen:

     Case Open Warning:            Disabled
     Quick Boot:                   Enabled
     Bootup Num-Lock:              Off
     Full Screen Logo:             Disabled
     Halt On:                      All, But Keyboard

You might want to take a quick look through all of the other BIOS settings to see if there are any that make sense for a TV watching application (e.g. quiet is good, unattended is good, always on is good). Don't forget to save the settings when you're all done.

Running The Mythbuntu Install CD

First of all, don't think because you've got an operating system install disk, in your hot little hands, that was built specifically for MythTV, that your install will be easy. Any way you slice it, installing Mythbuntu and getting MythTV to work is going to be a goat rope. If you don't want to spend days dicking around with hardware, drivers and screwy software, go buy a TiVoHD and pay those lovely people their monthly fee. Get used to the fact that they're logging what you watch plus every click of the remote, all the while forcing you to see advertising from their sponsors.

OK, still want to proceed? The goat roping begins with the install disk. We're going to start by building a combo backend/frontend machine (i.e. one that records TV and lets you view it [what a concept]).

Possibly, you were being clever and got a smallish hard drive for the OS and MythTV software and then one or more mondo huge drives for recording storage. For example, your system might look like this:

     sda - 80G SATA
     sdb - 620G SATA
     sdc - 620G SATA

During setup, you'll have to partition these drives. You could do it manually or you could allow Mythbuntu's automatic partitioning to do it. So far, We've never seen an automatic partitioner that does any kind of a decent job so we're all for manual partitioning. We like to set the partitions up this way:

     sda1    512M    ext3    /boot
     sda2      4G    swap
     sda3     max    ext3    /
     sdb1     max    xfs     /mnt/sdb1
     sdc1     max    xfs     /mnt/sdc1

Or something to that effect. The partitioner may round the sizes up down a bit to make them fit within cylinder boundaries. That's OK, since 512M is way more than you'll ever need for /boot and a 4G swap partition is plenty. All of the other partitions should be set to the maximum size remaining.

Make sure to choose the option to format all of the partitions. And, for any partition that will be storing video data, always choose the "xfs" file system, since it works best with big files.

The alternative is to go for the bleeding edge and purchase one ginormous hard drive to hold everything, a configuration which we've also had success with. For example, your system might look like this:

     sda - 2.0T SATA

Once again, during setup, you'll have to partition the drive, which you could do manually or allow Mythbuntu's automatic partitioning to do it. As we said above, we're no fans of automatic partitioning so we're still all for manual partitioning. Set the partitions up this way:

     sda1    512M    ext3    /boot
     sda2      2G    swap
     sda3     max    xfs     /

After you've partitioned the drives, the remainder of setup is straightforward. Just follow the steps. However, there is one other thing to watch out for when you're setting Mythbuntu up. If you have an Ira IR device (from Home Electronics) plugged into the serial port, do not set this device up during install. Make sure to pick "No Remote" when you do the install. If you do not, the install will hang and any subsequent reboots of the partially-installed Mythbuntu will die with the error message "No resume image".

We don't know if there are other remote controls that have this effect but the Ira is definitely one of them, especially under Mythbuntu 8.04LTS. If your system hangs during install or when it is subsequently rebooted, you should try going back to the beginning of the install and doing it over (we tried 5 times before getting it just right). Make sure to leave off any kind of remote control (you can set it up later) as the install program does not deal well with those that it doesn't understand (the Ira being one of them).

Mr. Wizard

For some reason, the Ubuntu guys decided that the owner of the system should not have root priviledges and that they should be forced to use sudo to do everything. To this end, they set the root password to some randomly generated value and don't tell us about it. Then, they set up the first user created as a sudo user and proceed with the system install. To be able to do anything, you must type sudo in front of every command and enter passwords constantly.

If you're like us and think this is b.s., you can do the following:

     sudo passwd root
       root's new password
       root's new password

Now, you're in business. From here on, you can just do su and enter root's password to get on with your life.

For the MySQL database, the initial installation should set the root password to nothing. If you'd like to change it to something, do this:

     mysql -u root
     set password for 'root'@'localhost' = password('newpwd');
     set password for 'root'@'host_name' = password('newpwd');
     set password for 'root'@'127.0.0.1' = password('newpwd');
     flush privileges;

For older Mythbuntu systems, that don't use upstart, if you forget the MySQL root password or if some clever install software sets it to something you don't know, you can reset it as follows:

     cd /etc/init.d
     sudo ./mythtv-backend stop
     sudo ./mysql stop
     sudo mv mysql mysql.orig
     sudo cp mysql.orig mysql
     sudo emacs mysql &

Change the line in the startup section that reads:

     /usr/bin/mysqld_safe > /dev/null 2>&1 &

To read:

     /usr/bin/mysqld_safe --skip-grant-tables > /dev/null 2>&1 &

Save the file, exit the editor, and restart the mysql server:

     sudo ./mysql start

Run the MySQL client from the command prompt:

     mysql

Issue the following statements in the mysql client. Replace the MyNewPass with the password that you want to use:

     update mysql.user set Password=password('MyNewPass') where User='root';
     flush privileges;
     quit

Stop the mysql server and restore the original startup script:

     sudo ./mysql stop
     sudo rm -f mysql
     sudo mv mysql.orig mysql

Restart the mysql server:

     sudo ./mysql start

You should now be able to login to mysql using the root password:

     mysql -uroot -pMyNewPass

If all is well, restart the MythTV backend:

     ./mythtv-backend start

On the newer systems that use upstart, you can carry out what are essentially the same steps to reset it, if you forget the MySQL root password or if some clever install software sets it to something you don't know:

     cd /etc/init
     sudo stop mythtv-backend
     sudo stop mysql
     sudo mv mysql.conf mysql.conf.orig
     sudo cp mysql.conf.orig mysql.conf
     sudo emacs mysql.conf &

Change the line in the upstart scritp that reads:

     exec /usr/sbin/mysqld

To read:

     exec /usr/bin/mysqld --skip-grant-tables

Save the file, exit the editor, and restart the mysql server:

     sudo start mysql

Run the MySQL client from the command prompt:

     mysql

Issue the following statements in the mysql client. Replace the MyNewPass with the password that you want to use:

     update mysql.user set Password=password('MyNewPass') where User='root';
     flush privileges;
     quit

Stop the mysql server and restore the original startup script:

     sudo stop mysql
     sudo rm -f mysql.conf
     sudo mv mysql.conf.orig mysql.conf

Restart the mysql server:

     sudo start mysql

You should now be able to login to mysql using the root password:

     mysql -uroot -pMyNewPass

If all is well, restart the MythTV backend:

     start mythtv-backend

NIC Drivers

If you happen to be lucky enough to get a motherboard that has an unsupported NIC chipset, you will need to build the driver and install it.

For example, the Realtek RTL8111C chip is supported by a special Realtek r8168 driver, although Mythbuntu thinks it is supported by the generic r8169 driver. If you do not install the special r8168 driver, the NIC will appear to be up and running, when you do ifconfig, but it will not work. Only the special r8168 driver works. Furthermore, the people who build the kernel periodically seem to think they've got this problem licked with their fabulous, new code in the r8169 driver but it never proves to be the case. So, this chipset (which is quite popular, apparently) is bound to be a problem for years to come.

Another Ethernet chipset that is showing up on a lot of motherboards, and which doesn't have support built in to some kernels (although it does appear to be included in Mythbuntu 12.04), is the Atheros 8151 (and its brethren). If your motherboard includes this chipset, you may need to build the driver for it.

Yet another example of a newer chipset that may cause trouble under older kernel versions is the family of Intel gigabit NICs which are supported by the e1000e driver. Some of the later chipsets (e.g. I219-V) do not work with the stock e1000e driver found in earlier versions of Ubuntu (e.g. 12.04). If you're trying to run an older version of Mythbuntu on a newer motherboard, you may need to update this driver so that it supports the newer chipset.

Here's how to replace the driver for any of these chipsets specifically, and other NIC drivers in general.

The first problem, of course, is that the install probably won't fly without a working NIC in the system (the classic, "You can't get there from here"). The easiest way around this problem is to plug a working NIC into one of the PCI slots. A board with the r8169 chipset on it should work well. Any of the older 100 Mbps NICs should work too. Then, you can install Mythbuntu and apply all of the recent patches.

You should probably get rid of the Network Manager (its a real piece of scrap) and set the network up by hand (see Networking Your Way, below). In this case, you'll be setting up the temporary NIC first and then setting up the on-board NIC later on.

For Mythbuntu, building and installing a new driver can be problematic, since the build environment is not included in the distro. To build the driver, start by obtaining and installing a duplicate copy of Ubuntu (on another machine -- you can never have too many) to match your copy of Mythbuntu. Since Mythbuntu is built off of the standard Ubuntu distro, this shouldn't be a problem.

Make sure you have the driver build environment (this is not necessarily the full kernel build environment). To verify that you do have the driver build environment, try:

     ls -l /lib/modules/`uname -r`/build

If you have this directory installed, you're good to go (Ubuntu usually provides it in a typical installation). Otherwise, you'll need to first get the build environment, either using the Package Manager or by doing:

     sudo apt-get install build-essential

Then, you should make sure to install the latest headers for your kernel. When you enter the following command, be sure to use back-quotes:

     sudo apt-get install linux-headers-`uname -r`

Finally, if the link doesn't already exist, link the headers to the build folder in the proper place. This should get you compiling:

     sudo ln -s /usr/src/linux-headers-`uname -r` /lib/modules/`uname -r`/build

After you've got the build environment set up, either on your duplicate system or on you new system with a temporary NIC in it, download the latest version of the NIC driver from the manufacturer's Web site and place it in a convenient directory (you can build it under your home directory).

The download for the latest r8168 driver, for example, is at:

     http://www.realtek.com.tw/downloads/downloadsView.aspx?Langid=1&PNid=13&;
          PFid=5&Level=5&Conn=4&DownTypeID=3&GetDown=false#2

The r8168-8.012.00.tar.bz2 release seems to work on Mythbuntu 8.10 and 9.04. However, if you are using a version of Mythbuntu that is built on 8.04LTS, you may have to get r8168-8.005.00.tar.bz2 (because the later versions blow up during compile on 8.04LTS). You can get r8168-8.005.00.tar.bz2 and then apply the patch that is found at:

     http://ubuntuforums.org/attachment.php?s=f4cb4535bb95f2d96d4aa4d7530f78b1&;
          attachmentid=66030&d=1208224861

We are getting ahead of ourselves but, to apply the patch after you've unpacked the tar file (below), change to the src directory and do:

     patch ../../r8168-8.005.00.hardy.diff.txt

We unzipped the downloaded file and unpacked it in two steps:

     bunzip2 r8168-8.005.00.tar.bz2
     tar -xvf r8168-8.005.00.tar

However, you should be able to get away with:

     tar -xvjf r8168-8.005.00.tar.bz2

There are probably build instructions for the driver in a readme file. You might want to read them before proceeding with the build.

Apparently, it isn't necessary to place the driver in the system source tree any more, in order to build it (i.e. the way it used to be). Of course, you may opt to do this, if you wish, but we build it in our own directory. To do so, try the following:

     cd r8168-8.005.00
     sudo make clean modules

If this blows up with a message about not knowing how to make Makefile in /src, you should change the following line in the Makefile in the src directory:

     #       $(MAKE) -C $(KDIR) SUBDIRS=$(PWD)/src modules
             $(MAKE) -C $(KDIR) SUBDIRS=$(shell pwd) modules

Apparently, somebody has scrod the PWD command in the 8.04LTS version of Ubuntu.

If you choose the build-it-in-the-source-tree option, you should do the following instead:

     sudo mv r8168-8.004.00 /usr/src
     cd /usr/src/r8168-8.004.00
     sudo make clean modules

Once you've successfully done a clean build of the driver, you'll need to get it from the Ubuntu machine to Mythbuntu. Since it may be the NIC that doesn't work (if you aren't using a second NIC), you quite possibly won't be persuing the copy-the-files-over-the-network option. Rather, the requisite driver files may need to be written to a CD or floppy disc. Here is a list of the files for the r8168 driver that should included on the CD or disc (only the ".ko" module is really important):

     -rw-r--r-- 1 eric eric      0 2008-04-02 22:08 Module.symvers
     -rw-r--r-- 1 eric eric  37828 2008-04-02 22:08 r8168.ko
     -rw-r--r-- 1 eric eric  31024 2008-04-02 22:08 r8168.mod.o
     -rw-r--r-- 1 eric eric 242056 2008-04-02 22:08 r8168_n.o
     -rw-r--r-- 1 eric eric 242083 2008-04-02 22:08 r8168.o

Later versions of the driver may include these files:

     -rw-r--r-- 1 eric eric      0 2009-09-05 15:26 Module.markers
     -rw-r--r-- 1 eric eric     54 2009-09-05 15:26 modules.order
     -rw-r--r-- 1 eric eric      0 2009-09-05 15:26 Module.symvers
     -rw-r--r-- 1 eric eric   6144 2009-09-05 15:26 r8168_asf.o
     -rw-r--r-- 1 eric eric  88040 2009-09-05 15:26 r8168.ko
     -rw-r--r-- 1 eric eric  15452 2009-09-05 15:26 r8168.mod.o
     -rw-r--r-- 1 eric eric  66416 2009-09-05 15:26 r8168_n.o
     -rw-r--r-- 1 eric eric  73329 2009-09-05 15:26 r8168.o
     -rw-r--r-- 1 eric eric   2240 2009-09-05 15:26 rtl_eeprom.o

Now, proceed to the Mythbuntu machine, with your CD or floppy disc (or FTP them from the build machine, if the 2nd NIC is working). Load the appropriate driver modules into the local directory where you usually put all of your system modifications. Once that's done, install them onto the system:

     cd r8168-8.005.00/src
     sudo install -m 744 -c r8168.ko /lib/modules/`uname -r`/kernel/drivers/net

There could be an older version of the module that you are replacing or one that conflicts with the new module (typically the r8169 driver tries to take control of the NIC but does not work). You can check, for example, if the r8169 module is installed as follows:

     lsmod | grep r8169

If r8169 is installed then you should remove it:

     sudo rmmod r8169

Now, complete the install of the new module on the Mythbuntu machine:

     cd ..
     sudo depmod -a
     sudo insmod ./src/r8168.ko

By doing these steps, you are essentially duplicating what the module's makefile would have done. But, since the build tools and source code are not available on the system, you cannot run the makefile so you must do it by hand. You can check whether the install is successful by doing:

     lsmod | grep r8168

Now, we need to get rid of the conflicting module, if it's there. If you are just adding a brand new module, you don't need to do this step. Otherwise, build a blacklist file for the old module. In older versions of Mythbuntu, this file should be named "blacklist-network" but in newer versions (e.g. Mythbuntu > 9.04) all blacklist files must end in the suffix ".conf". Examine the existing files in /etc/modprobe.d and see how they are named to determine how to proceed. Then, either do:

     cd /etc/modprobe.d
     sudo touch blacklist-network
     sudoedit blacklist-network

or, for later versions do:

     cd /etc/modprobe.d
     sudo touch blacklist-network.conf
     sudoedit blacklist-network.conf

Regardless of whether the blacklist file is new or if it already exists, add the following lines to it:

     # Don't load the r8169 driver. It is replaced by the r8168 driver.
     blacklist r1869

Once you've completed all of the above, you must make the changes permanent. Mythbuntu boots from a RAM image of the kernel which will still have the old driver (if any) installed and the new driver missing. You need to update this image or the conflicting driver will still get loaded and take over the show. To do so, update the RAM image:

     sudo update-initramfs -u

Reboot the machine to see if the changes are permanent and that the NIC now works:

     sudo reboot

You can use ethtool to see if the new driver is assigned:

     ethtool -i eth0

If all is working, you should be able to remove the second NIC, if you went that route, and replace it with the now-working built-in NIC.

By way of a further example of how to build and install a NIC driver, here's how to build a driver for the Atheros 8151 (and its brethren) chipset.

The first step is to see whether the Atheros drivers are already included among the kernel modules:

     find /lib -name \atl\

If you see a list that includes:

     atl1.ko
     atl1c.ko
     atl1e.ko

You've probably got the latest drivers for this chip. But, if you don't see these kernel drivers, you need to build them. As above, we'll go the second NIC route to allow us to download the needed files and get the Atheros drivers working, so see the notes above about how to do that.

Probably the biggest problem you'll face with this chip is to find the correct source needed to build the driver. Originally, the source was offered on the Atheros Web site but they have since been bought out and the Web site has disappeared. Fortunately, the Linux Wireless Web site has accumulated a lot of useful drivers for wireless chips and they have also includes drivers for a number of wired network chips like the Atheros 8151.

All of the network drivers that the Linux Wireless Web site accumulates are rolled up into a single archive file which is updated on a regular basis. You can download the latest version of this archive from the Web page:

     http://linuxwireless.org/download/compat-wireless-2.6/

There are three archives to choose from. The "-pc" version seems to be the one to choose (because it includes all of the new Atheros drivers, specifically the alx driver) so download the one that looks like this:

     compat-wireless-2012-07-03-pc.tar.bz2

Change to the directory where you downloaded the archive file and unpack it like this:

     tar-xjvf compat-wireless-2012-07-03-pc.tar.bz2

As with the r8168 above, make sure you have the driver build environment available on your system. Once you have it installed, you can build and install the Atheros drivers like this:

     cd compat-wireless*
     scripts/driver-select atl1
     make
     sudo make install
     scripts/driver-select atl1c
     make
     sudo make install
     scripts/driver-select atl1e
     make
     sudo make install
     scripts/driver-select alx
     make
     sudo make install

The install steps in the build process update the kernel RAM image so all that you need to do is reboot the machine to see that the changes are permanent and that the NIC now works:

     sudo reboot

You can use ethtool to see if the new driver is assigned:

     ethtool -i eth0

If all is working, you should be able to remove the second NIC, if you went that route, and replace it with the now-working built-in NIC.

One wrinkle though, may be that the incorrect Atheros driver is automatically chosen for the 8151 chip at boot time. There have been reports that the atl1c.ko driver works poorly with some versions of the 8151 chip (e.g. R2.0) and that the new alx.ko driver (which is meant specifically for the 8161 chip) works better. If that's the case, you will probably have to blacklist the atl1c driver.

The notes for the r8168 above describe how to edit the blacklist file so see those notes about how to add the following lines to it:

     # Don't load the atl1c driver. It is replaced by the alx driver.
     blacklist atl1c

When you reboot, the alx driver should automatically come up in place of the atl1c driver.

If you are, instead, building the latest e1000e driver, you will, as above, need to set up a build environment (i.e. second build system or second temporary NIC in the target system) and make sure that the proper kernel build environment is installed.

Once that is done, the the download location for the e1000e driver is:

     https://downloadcenter.intel.com/download/15817

Select the latest version of the e1000e driver (or the one that works for your kernel version) and download it to a local directory. Change to that directory and unpack it:

     cd .../e1000e
     tar -xvzf e1000e-3.4.2.1.tar.gz

Change to the driver source directory and build it:

     cd e1000e-3.4.2.1/src
     make

If you added a second NIC to your system and built the driver in place, you don't have to do anything else. Otherwise, you'll need to move the driver files to your target system by hook or by crook. Options include a CD, a USB stick, or booting Knoppix and using it to copy the files onto the systems disk. The files that should be included (only the ".ko" module is really important) are:

     -rw-r--r-- 1 eric eric 291295 Feb 12 16:39 e1000e.ko
     -rw-r--r-- 1 eric eric 273665 Feb 12 16:39 e1000e.o
     -rw-r--r-- 1 eric eric     56 Feb 12 16:39 modules.order
     -rw-r--r-- 1 eric eric      0 Feb 12 16:39 Module.symvers

However, if you copy the whole build tree, you can simply do what you would do if you'd built the driver on the target machine. So, whether you used a second NIC to carry out the build in place, or you've just copied the files over, switch to the source directory in the build tree and complete the install as root:

     cd .../e1000e/e1000e-3.4.2.1/src
     sudo make install

This will install the newly-built driver in:

     /lib/modules/`uname -r`/updates/drivers/net/ethernet/intel/e1000e

Apparently, Intel was at a sale on subdirectories. If you want, you can move the driver to the more conventional:

     /lib/modules/`uname -r`/kernel/drivers/net/e1000e

Or not.

If there is an existing e1000e driver, that doesn't work, loaded into memory, you should remove it. Then, you can load the new driver:

     lsmod | grep e1000e
     sudo rmmod e1000e;  (if the old driver is loaded)
     sudo modprobe e1000e

You'll probably need the information about the built-in NIC to continue with your system's set up. As soon as you do the modprobe, you can look in dmesg to get the NIC's information:

     dmesg | tail -20

Look in there for the MAC address and to see what device name udev assigned to the NIC (if you are replacing a motherboard, for example, udev will probably reassign the NIC to eth1, until you can edit its configuration and map the new NIC to eth0). You'll need these if you're going to be changing /etc/network/interfaces to use the new NIC.

Reboot the machine to see if the changes are permanent and that the NIC now works:

     sudo reboot

You can use ethtool to see if the new driver is assigned:

     ethtool -i eth0

Finally, be aware that you will need to rebuild any drivers that you build and install manually each time there is a kernel update. This may require you to get all of your ducks in a row before you do the kernel update, because the network is going to stop working again. Unless, of course the new kernel finally has the drivers installed in it, in which case, all your troubles are over.

Networking Your Way

You may not want to bother with all of the b.s. inherent in setting up static IP addresses via the Network Manager. While this gem may be good idea for someone's laptop (where the network address is acquired automagically by DHCP, and/or networking is done via multiple connections), its probably going to be a real pain in the butt if you want your machine to have a single, static IP address (i.e. so the frontend can talk to the master backend, etc.).

Fire up your favorite text editor and take a look at the "/var/log/messages" file (or, for later versions of Mythbuntu, "/var/log/syslog"). Do a forward search for "eth". You should see the place in the boot sequence where the network driver brings up your network interface. This will list the MAC address of the card and the ethernet device name (e.g. "eth0"). Remember these two pieces of information.

If you can't find the MAC address in "/var/log/messages" or "/var/log/syslog", you can try looking through dmesg to find where the device driver started it. The MAC address should be listed there:

     dmesg | grep eth

If none of those work, there are several other options available to find it. You can try:

     /sbin/ifconfig -a

This more or less assumes that the interface was configured one way or another, perhaps by the Network Manager and DHCP, (although the "-a" option indicates that it need not be up). If that's not the case, you can try:

     /usr/bin/lshw -C network

This should give you the MAC address and maybe the ethernet device name for all of the configured NICs on your system. The MAC address will be listed as "serial".

Alternately, if you know what the NIC's device name is (e.g. eth3), you can use ethtool to dump the first part of the NIC's eeprom to get the MAC address:

     sudo ethtool -e eth3 offset 0 length 6

Note that, if the NIC doesn't get configured because it is not supported by any of the drivers, none of these methods may work. You will need to begin by searching for the NIC on the PCI bus:

     sudo lspci

Once you have the adapter's PCI bus address, you can dump all of the info about the adapter:

     sudo lspci -s nnnn:nn:nn.n -vvv

If worst comes to worst, you will need to look up the PCI ID on the Internet to find out what kind of chipset the NIC uses. For example, looking up 8086:15B8 indicates that the chipset is an Intel I219-V (a late-model Intel gigabit chipset).

Again turning to the Internet, you can figure out which device driver is supposed to work with this chipset. You may have to update or build the driver (see NIC Drivers, above) before your NIC will appear.

Once you have a device driver that talks to your NIC, and it starts the NIC at boot time, you can continue searching forward from that point in dmesg, "/var/log/messages" or "/var/log/syslog" where you found its MAC address, or from the beginning, if you had to resort to other means to get the MAC address.

You may see where udev is remapping your NIC to some other device name (e.g. "udev: renamed network interface eth0 to eth1"). If you don't want this to happen (quite often, the clever little install programs add every NIC they've ever encountered, at some time in the past, to udev's rules so that you end up with "eth0", "eth1", "eth2", etc., even though you only have one NIC now), you should find where udev compares the NIC's MAC address in its rules and maps the NIC to something else. For example:

/etc/udev/rules.d/70-persistent-net.rules:

.

       .

# The line will look something like this SUBSYSTEM=="net", ACTION=="add", DRIVERS="?", \ ATTR{address}=="00:19:66:17:ea:ff", ATTR{type}=="1", KERNEL=="eth", \ NAME="eth1"

       .
       .
       .

Comment out all of the lines that map the former NICs and change the line that maps the current NIC, to map it to "eth0" (or whatever name you really want). In this case, we'd change "eth1" to "eth0". Or, take all of the mapping lines out altogether, if you think the network driver will always assign things in the proper order.

Once you know the name of the NIC, edit the "/etc/network/interfaces" file. If you want a static IP address, your file should look something like this:

/etc/network/interfaces:

     auto lo
     iface lo inet loopback
     auto eth0
     iface eth0 inet static
         address 192.168.1.8
         netmask 255.255.255.0
         gateway 192.168.1.1

You can force the issue by including the actual MAC address in the "/etc/network/interfaces" file, in which case you'll get an error in the log, when you try to bring up networking, if the MAC address ever changes. This may be preferrable to udev just remapping your NIC to eth5 (or whatever), when you install a new one, and having DHCP take over. In that case, networking will appear to be working but when you try to reach the system with its supposed static IP address, you'll get a huge surprise. To force the MAC address to be checked, do this:

     auto eth0
     iface eth0 inet static
         hwaddress ether 00:19:66:17:ea:ff
         address 192.168.1.8
         netmask 255.255.255.0
         gateway 192.168.1.1

For earlier versions of Mythbuntu, you can put your DNS servers directly in "/etc/resolv.conf", optionally along with your domain name search string. This should look something like this:

     search mysite.com
     nameserver 151.203.0.84
     nameserver 151.203.0.85
     nameserver 204.122.16.8
     nameserver 216.231.41.2

However, for later versions of Mythbuntu the resolvconf command is used by the networking scripts to set the DNS servers dynamically, as interfaces are brought up/down. This means that any changes made to "/etc/resolv.conf" will be wiped out in short order. For those systems, the proper way to set the list of DNS servers is with the "dns-nameservers" and "dns-search" commands in the "/etc/network/interfaces" file, like this:

     auto eth0
     iface eth0 inet static
         hwaddress ether 00:19:66:17:ea:ff
         address 192.168.1.8
         netmask 255.255.255.0
         gateway 192.168.1.1
         dns-nameservers 151.203.0.84 151.203.0.85 204.122.16.8 216.231.41.2
         dns-search mysite.com

However, if you want a dynamic IP address that is obtained from DHCP, there is no need to put anything in "/etc/resolv.conf" or "/etc/network/interfaces". Merely change "/etc/network/interfaces" to look like this:

     auto lo
     iface lo inet loopback
     auto eth0
     iface eth0 inet dhcp

Now, we can uninstall the Network Manager using the Package Manager (in later versions of Mythbuntu, the Package Manager has been replaced with a video game called Ubuntu Software Center, whose aim in life appears to be to sell you magazine subscriptions. If you hate this application, like we do, see the "Useful Software" section for notes on how to install the Synaptic Package Manager and the "Useless and Annoying Software" section for notes on how to remove the Ubuntu Software Center). Using one of the GUI package managers (or apt-get, for that matter) is by far and away the easiest way to disable the Network Manager. Search for "network-manager". You should see the network-manager package, and possibly the network-manager-gnome package at the head of the list. Uninstall it (them) and any dependencies too.

Once you're done, you can yo-yo the network down/up. On earlier versions of Mythbuntu, this is accomplished like so, from the console:

     sudo /etc/init.d/networking stop
     sudo /etc/init.d/networking start

On later versions of Mythbuntu, that use upstart, this might be accomplished with, from the console:

     sudo stop networking
     sudo start networking

Although, under Mythbuntu 12.04LTS, this method doesn't work and seems to leave networking sort of in limbo (nice work, guys -- that upstart thingy is a real winner). Of course, the ultimate test is to reboot the system, which works even when upstart doesn't. Either way, a ping to another system should prove that everything is working OK. If you'd like to admire your handiwork, you can try:

     /sbin/ifconfig

File System Table

The latest system install processes all seem to want to use that "cool" new feature, the UUID, to mount partitions from the file system table. If you look in /etc/fstab you'll see something like this:

     # /boot was on /dev/sda1 at boot time
     UUID=ABC123...

This is another fabulous idea whose time has "come". With this method, you may notice one day that your swap space is missing. Or you may not be able to mount partitions after copying a disk or doing something else to the partitions (because the UUID has changed). Whatever the reason, the good old reliable way of mounting partitions by device name is the best. You should check your fstab to see that it looks something like this:

/etc/fstab:

     # /etc/fstab: static file system information.
     #
     # <file system> <mount point>   <type>  <options>       <dump>  <pass>
     proc            /proc           proc    defaults        0       0
     /dev/sda1       /boot           ext3    defaults        0       2
     /dev/sda2       none            swap    swap            0       0
     /dev/sda3       /               ext3    defaults,errors=remount-ro 0       1
     /dev/sdb1       /mnt/sdb1       xfs     defaults        0       2
     /dev/sdc1       /mnt/sdc1       xfs     defaults        0       2
     /dev/scd0       /media/cdrom0   udf,iso9660 user,noauto,exec 0       0

Use absolute partition names (e.g. "/dev/sda1"), under normal circumstances, and you shouldn't experience any problems with partition mounting.

Unfortunately, it has now become a case of the inmates truely being in charge of the asylum.

If you are using an HBA to attach disks (e.g. for recording volumes), as well as the ATA ports on the system's motherboard, this can lead to the the names that are assigned to the disks being inconsistent from one boot to the next. This makes it particularly fun when it comes to mounting the disks. And, better yet, there's no way to fix this stupidity. You just have to take what they give you.

So, in spite of what we just said above about using actual device names in fstab, the fstab instead needs to mount the disks by UUID. The UUID in question is assigned when the partitions are built so you need to get the UUID after the disk is partitioned and formatted. You can do this with:

     su
     /sbin/blkid /dev/sdxx1
     /sbin/blkid /dev/sdxx2
     /sbin/blkid /dev/sdxx3
          .
          .
          .

But, before you do this, you might want make sure that the disk you are asking for the UUID for is really the disk you mean to mount. You should copy down the physical serial number from the disk's external label, when you install the disk, and then look at the disk information for the device that you suspect is the disk in question. If the serial number you copied down is the same, you can proceed. Get the disk info this way:

     su
     /usr/bin/udisks --show-info /dev/sdxx

It may be of assistance to you to note that the disks plugged into HBA ports are assigned disk names first (e.g. /dev/sda, /dev/sdb, etc.), before the disks plugged into the motherboard ATA ports. Also, it appears that for most HBAs (which implement SAS/SATA ports with a 4-port controller chip), the disk names are assigned in ascending order, to the disks plugged into Port 3, Port 2, Port 1, Port 0, then Port 7, Port 6, Port 5, and Port 4, etc. So, Port 3 gets the name /dev/sda, Port 2 gets /dev/sdb, ..., Port 7 gets /dev/sde, Port 6 gets /dev/sdf, etc. But, only if there is something actually plugged into the port.

Once you have the UUIDs for all of the disks/partitions that you want to mount, you can update /etc/fstab, which should now look something like this:

     # /etc/fstab: static file system information.
     #
     # <file system> <mount point>   <type>  <options>       <dump>  <pass>
     proc            /proc           proc    defaults           0       0
     UUID=820d621e-f14e-4c4c-b9ae-24d225b8a952 /boot    ext3 defaults 0 2
     UUID=f0ec04cc-cc3a-4038-a03d-9a67dbc8d803 swap     swap defaults 0 0
     UUID=4dbc04b2-ff1a-4161-bbcc-8a0587b5ccc3 /        ext3 defaults 0 1
     UUID=19c03f99-9017-7730-f44e-710bf87c7671 /mnt/sdb1 xfs defaults 0 2
     UUID=39f7c43c-e620-49b8-8cb4-e4b7e1a622a0 /mnt/sdc1 xfs defaults 0 2
     /dev/scd0       /media/cdrom0 udf,iso9660 user,noauto,exec 0       0

If you add a new disk or replace an existing disk with a different one, you will need to go through all of the steps described above to find the UUID of the disk and update /etc/fstab with it.

Once fstab is updated, you can either reboot the system or, we prefer, try auto-mounting everything first (this way, if fstab is broken, your system will still be up and running and you'll have a chance to fix things):

     su
     mount -a -v

Incidentally, while we're talking about the partition table, if you are mounting any XFS partitions, you need to make sure that the xfsprogs package is installed on the system, or the XFS partitions will fail to mount upon startup with a disconcerting message about "a serious error". You can choose to skip the error and then mount the drives later on, with no problems, like this:

     mount /mnt/sdb1

So, what's going on? Failing to install the xfsprogs package, omits the fsck.xfs program which is needed to check XFS drives. Since it is missing, when fsck tries to invoke it to check the XFS drives at startup, the check fails and fsck decides that there is a serious error. However, there's nothing really wrong with the drives, which is why you can mount them later on. The solution is to reinstall the xfsprogs package, like this:

     apt-get install xfsprogs

Mythfilldatabase

Many of the steps that follow ask you to run mythfilldatabase after they are completed. Never run it except on the master backend. Also, you may need to recycle the master backend and run mythfilldatabase when you are done with some of the changes, below, for them to take effect.

General Configuration Options

Here are some general configuration options you need to consider when you run the MythTV backend configuration:

     Local Backend
       IP Address: your-ip-addr-here       (This is required)
       Security PIN (Required): 0000       (This is required)
     Master Backend
       IP Address: your-ip-addr-here       (This is required)
     VBI format: NTSC Closed Caption
     Channel frequency table: us-cable
     HD Ringbuffer size (KB): 65800
     Save original files after transcoding (check)
     Maximum Simultaneous Jobs: 2

Note that you can run MythTV on a machine that obtains its IP address dynamically but good luck making it work as a backend. Essentially, all of the frontends need to know what the backend's IP address is and this ain't happenin' if its assigned with DHCP. So, using a static IP is A Good Thing (tm).

Furthermore, if you are running a master backend and one or more a secondary backends, every backend has to know the IP address of the master and the master must know the IP address of the secondary. This means that you must fill in a real IP address for the Local Backend and Master Backend on every machine. If you don't all sorts of stuff will stop working. And, don't even think of using an IP address like 127.0.0.1 for the Local Backend. This address is stored in the database and when any of the other machines reference it, it will confuse the heck out of them.

Also note that, if you do things like define capture cards (below) you may have to have a valid Master Backend address filled in or your capture card will not appear.

Recovering From General Configuration Errors

MythTV being what it is, recovery from configuration errors is not high on its list of things to do. This being the case, it is possible to set some of the General Configuration options so that the frontend and/or backend may not run. Since editing of these parameters is generally done via the frontend, you may find yourself in a "you can't get there from here" situation.

To recover from such a situation, you can edit the General Configuration options directly in the text file where they are stored (these options control access to the database, hence cannot be stored in the database). They are found in the text file /etc/mythtv/mysql.txt. A typical set of options is:

     #
     # Host name or IP address for master backend (where the database
     # lives).
     #
     DBHostName=192.168.1.13
     #
     # By default, Myth tries to ping the DB host to see if it exists.
     # If your DB host or network doesn't accept pings, set this to no:
     #
     DBHostPing=no
     #
     # Used to connect to the MySQL database.
     #
     DBUserName=mythtv
     DBPassword=asecret
     DBName=mythconverg
     DBType=QMYSQL3
     #
     # Set the following if you want to use something other than this
     # machine's real hostname for identifying settings in the database.
     # This is useful if your hostname changes often, as otherwise you
     # will need to reconfigure mythtv (or futz with the DB) every time.
     # TWO HOSTS MUST NOT USE THE SAME VALUE
     #
     #LocalHostName=my-unique-identifier-goes-here
     #
     # If you want your frontend to be able to wake your MySQL server
     # using WakeOnLan, have a look at the following settings:
     #
     # The time the frontend waits (in seconds) between reconnect tries.
     # This should be the rough time your MySQL server needs for startup
     #
     #WOLsqlReconnectWaitTime=0
     #
     # This is the number of retries to wake the MySQL server
     # until the frontend gives up
     #
     #WOLsqlConnectRetry=5
     #
     # This is the command executed to wake your MySQL server.
     #
     #WOLsqlCommand=echo 'WOLsqlServerCommand not set'

Incidentally, if you ever forget the password to the database, it can be found in the /etc/mythtv/mysql.txt on the master backend.

Capture Cards

Set up the capture cards that you have installed in your system through the MythTV backend configuration. We have set up systems using the Hauppauge PVR-150 cards (for analog recording), the pcHDTV 5500 cards (for HDTV recording), the AVerMedia A180 cards (for HDTV recording), the Hauppauge PCTV HD 800i cards (which are really Pinnacle cards, for HDTV recording), and the Hauppauge HVR-2250 dual tuner cards (for HDTV recording only). All of these cards work well and have been, in some cases, running on our systems for 3-4 years.

Each of these cards is detailed in a separate section that follows. Analog TV is pretty much old news, so most of the cards that we use are for HDTV recording only. However, should you need to record analog signals, the PVR-150 cards, with their onboard MPEG encoders, are the best, in our opinion, to use. Many are available on the various auction sites for quite reasonable prices.

Once your capture cards are set up, define your video sources (i.e. channel lineups) as described in the Video Sources section (below) and then associate them with the capture cards, as described in the Input Connections section (also below).

Hauppauge PVR-150 Capture Card

The Hauppauge capture cards such as the PVR-x50 cards (this includes the PVR-150 and PVR-250 cards), which have MPEG2 encoders, should be set up using the "MPEG-2" encoder option, not the Analog V4l capture card option. The setup is pretty simple, since all you have to do is select the "MPEG-2" option from the Capture Card Setup page. Earlier versions of MythTV may have an "IVTV" option but this should be eschewed in favor of the "MPEG-2" option. That's about all there is to it.

However, if you have both a PVR-x50 card and a pcHDTV card (or one of the other HDTV cards like the HD 800i) in the same box (because the analog recording with the pcHDTV card kludge doesn't work worth a darn), you may experience a collision between the two cards. Depending on the order in which they are plugged into the PCI bus, one or the other of the cards may disappear when it comes time to configure them. This can be corrected by changing /etc/modprobe.d/options (outside of backend configuration):

     sudo touch /etc/modprobe.d/options
     sudoedit /etc/modprobe.d/options

Add the following line (or one similar to it):

     # Fix collision between pcHDTV/HD 800i and PVR-150.
     options cx8800 video_nr=2 radio_nr=2

Once you've made all of your changes, you may want to reboot the system a few times to be sure that what you've done is working. One can never be too sure when the clever, little PCI bus is involved.

If you wish to test that the card is working, before you let MythTV have at it, you first need to ensure that the v4l and ivtv utilities are installed:

     su
     apt-get install v4l-utils
     apt-get install ivtv-utils

Once you've done that, you can try the following (assuming that you're debugging the first card in the system, on /dev/video0) from a console on the primary display:

     v4l2-ctl -i0 -d /dev/video0
     ivtv-tune -c3 -d /dev/video0
     mplayer -vf pp=lb /dev/video0

You should see a mplayer window that shows the analog program that is currently playing on channel 3, on tuner 1. If, for example, the card is cabled to the output of a cable company DTA, this should show you whatever is playing on the channel selected on the DTA.

pcHDTV HD-5500 Capture Card

This card is designed specifically to work with Linux and, as such, it works very well with MythTV. The drivers for the card are the DVB drivers, which are built in to all of the later releases of the kernel, that are used for Mythbuntu. Setup is quite simple. You should always set up the capture cards from pcHDTV as DVB cards (although, if you wish, see Recording HDTV And Analog TV Using The pcHDTV Cards, below). The choice, listed on the setup page, should be the one that says "DVB" (it may also specifically mention the pcHDTV card -- since it is so popular, it is often included as an example of a typical DVB card).

For the pcHDTV HD-5500 cards, a couple of options that you will probably want to use are:

     Recording Options
     Max Recordings: 1
     Open DVB Card on demand: (check)

If you are getting your guide data via EIT, you might want to enable it on the pcHDTV encoder. To do so, check the EIT box:

     Use DVB card for active EIT scan: (check)

If you have multiple pcHDTV cards, you could have a problem with the audio on these cards. Each card provides sound through its own Conexant CX8801 audio chip (cx88_alsa module). When multiple tuners are present the order of the sound devices as listed in /proc/asound/cards may change from one boot to the next, causing an apparent loss of sound. This can be corrected by changing (also outside of backend configuration) either /etc/modprobe.d/alsa-base or for later versions of Mythbuntu, /etc/modprobe.d/alsa-base.conf:

     comment out:
       # options cx88_alsa index=-2
     add the following (example for two cards):
       # Force the order of the audio chips in pcHDTV cards.
       options cx88_alsa index=1,2

To edit /etc/modprobe.d/alsa-base, use:

     sudoedit /etc/modprobe.d/alsa-base

While, to edit /etc/modprobe.d/alsa-base.conf, use:

     sudoedit /etc/modprobe.d/alsa-base.conf

And, while we're talking about monkeying with the modules in modprobe.d, you may want to add the following line to /etc/modprobe.d/options:

     options dvb_core dvb_shutdown_timeout=0

You can edit this file as described above. This change will make switching between HDTV and analog TV work much better on the pcHDTV HD-5500 card.

After you've made all of your changes, you may want to reboot the system a few times to be sure that what you've done is working. One can never be too sure when the clever, little PCI bus is involved.

Hauppauge PCTV HD 800i Capture Card

This card is a low-profile card that can readily be used in place of the pcHDTV card (wherever that card is deployed). And, the good news is that its about $40 cheaper.

The drivers for the card are the DVB drivers, which are built in to all later releases of the kernel that are used for Mythbuntu. Setup is quite simple. You should always set up the HD 800i capture cards as DVB cards. The choices listed on the setup page will include one that says "DVB", and that's the one you should choose.

For the HD 800i cards, a couple of options that you will probably want to use are:

     Recording Options
     Max Recordings: 1
     Open DVB Card on demand: (check)

If you are getting your guide data via EIT, you might want to enable it for the HD 800i encoder. To do so, check the EIT box:

     Use DVB card for active EIT scan: (check)

AVerMedia A180 Capture Card

This card is billed as a much better card than the pcHDTV HD-5500 card by those who use it. It is not a low profile card so, if you need that feature, you're out of luck. But, if you have room in your system for a full-height card, you might want to give it a spin (its cheaper too). Unfortunately, as with most things Mythbuntu, plug and play is not going to happen. Let the goat rope begin.

First, under Mythbuntu 8.04LTS, support for the card is not built-in (despite the fact that there is a saa7134 driver included). However, later versions support it (possibly through the saa7133 driver), in which case you'll be able to skip the driver installation step.

Despite which driver is used, in all cases so far, to get support for this card, you do need to download some firmware. Downloading the firmware is accomplished through a simple, little, 500-line script that is included in the kernel documentation. You can download the entire set of kernel documentation, for example:

     sudo apt-get install linux-doc-2.6.24
     cd /usr/share/doc/linux-doc-2.6.24/Documentation/dvb
     sudo gzip -d get_dvb_firmware.gz
     sudo chmod +x get_dvb_firmware

Or, if you simply want to get the script (sure seems easier to us), you can find it at:

     http://www.mjmwired.net/kernel/Documentation/dvb/get_dvb_firmware

Click the link that says "Remove Line Numbers" and then copy the script and paste it into a file. Make sure you include a newline on the last line and remove any <CR>s if you used Windoze to create it. Then:

     chmod ugo+x get_dvb_firmware

Before you run the script, you must have the unzip command installed. You can do this with:

     sudo apt-get install unzip

Create a directory for downloaded firmware and change to it. Then, download the firmware using the script:

     get_dvb_firmware nxt2004

Copy the firmware to your kernel's firmware directory:

     sudo cp dvb-fe-nxt2004.fw /lib/firmware/`uname -r`

For later versions of Mythbuntu, the kernel version is left off of the firmware directory so the copy looks like this:

     sudo cp dvb-fe-nxt2004.fw /lib/firmware

On earlier versions of Mythbuntu, the next step is to blacklist the old saa7134 driver (so that it won't try to screw things up):

     sudoedit /etc/modprobe.d/blacklist

After a certain point in the Mythbuntu version sequence, all blacklist files must end with ".conf". If you see such files in "/etc/modprobe.d", you should instead do:

     sudoedit /etc/modprobe.d/blacklist.conf

Add the following lines to the blacklist file:

     # Get rid of the old saa7134 driver. We have a newer one from AVerMedia.
     blacklist saa7134

Then, we need to load the new, DVB saa7134 driver. To do so, hack "/etc/modules":

     sudoedit /etc/modules

Add the following lines to the modules file:

     # Load the newer saa7134 DVB driver.
     saa7134-dvb

With the later versions of Mythbuntu (e.g. 12.04) that support this card through the saa7133, you simply need to tell the system which driver should be used for the card. To do this, we add a few lines to the "/etc/modprobe.d/options" file (which you may have to create). Using the editor, add the following (for two cards):

     # The AverMedia A180 cards are autodetected as saa7133 cards.  We need
     # to force them to use the saa7134 driver.
     options saa7134 card=75,75

There is no need to blacklist the 7134 driver. In fact, if you do, the cards won't operate properly. Just add the lines above to the "options" file. Confused by all this? You can find further help at:

     http://linuxtv.org/wiki/index.php/AVerMedia_AVerTVHD_MCE_A180

As noted for the other capture cards, above, once you've made all of your changes, you should reboot the system a few times to be sure that what you've done works.

You can now set up the A180 capture cards that you have installed in your system through the MythTV backend configuration. Note that you should always set up the capture cards from AVerMedia as DVB cards. The proper choice is "DVB DTV capture card (v3.x)".

As with the pcHDTV cards, for these cards, a couple of options that you will probably want to use are:

     Recording Options
     Max Recordings: 1
     Open DVB Card on demand: (check)

The HowTo for this card can by found in the MythTV wiki:

     http://www.mythtv.org/wiki/index.php/AVerTV_HD_A180

Also, this card is quite similar to the ATI HDTV Wonder card so these installation instructions might be useful for it too.

Hauppauge HVR-2250 Capture Card

This low profile card has dual tuners in it but, as of now, only supports digital TV. If that's all you need, you might consider using one of these cards. The MythTV wiki has more information here:

     http://www.mythtv.org/wiki/Hauppauge_HVR-2250

The drivers for this card were developed by Stephen Toth and can be found on the Kernel Labs site:

     http://www.kernellabs.com/blog/?page_id=17

Eventually, the drivers should show up in the latest version of Mythbuntu because they were merged into the LinuxTV sources in February of 2010 (e.g. Mythbuntu 11.04 has them included). In the meantime, you can either build the latest V4L-DVB source, available from:

     http://linuxtv.org/repo/

Or, if you want to build the latest stable SAA7164 driver source, you can get the latest version from:

     http://kernellabs.com/hg/saa7164-stable/

Either way, you will first need to get the firmware for the HVR-2250. Make a directory to hold the firmware and download it:

     cd ~/SAA7164/HVR22xx
     lftp
     mget http://steventoth.net/linux/hvr22xx/*
     quit
     chmod ugo+x extract.sh

Before you run the extract script, you must have the unzip command installed. You can do this with:

     sudo apt-get install unzip

Now, extract the firmware:

     ./extract.sh

Copy the extracted firmware (originally meant for Windows but works equally well under Linux) to the firmware directory for your distribution:

     sudo cp *.fw /lib/firmware/`uname -r`

Or, if you'd like the firmware to hang around, even after you install the next distribution, copy it to the top level firmware directory:

     sudo cp *.fw /lib/firmware

Note that, for later versions of the the drivers that are included in the OS (e.g. Mythbuntu 11.04, 11.10, 12.04), you will probably also need to get later versions of the firmware. These can be found at:

     http://www.steventoth.net/linux/hvr22xx/firmwares/

The firmware modules can be downloaded directly (without the benefit of unzip). Mythbuntu 11.04, 11.10 and 12.04 appear to want:

     NXP7164-2010-03-10.1.fw
     v4l-saa7164-1.0.2-3.fw
     v4l-saa7164-1.0.3-3.fw

If you browse around the top level directory you should be able to find the required modules. Hints on what the driver is looking for can be found in /var/log/kern.log. You can copy the firmware to either the /lib/firmware/`uname -r` or /lib/firmware directory, as noted above.

If you aren't running a version of Mythbuntu that has the driver built-in you should continue with these steps to build it. Otherwise, if you're using a version of Mythbuntu that already has the driver in it, installing the firmware is all you need to do.

In order to obtain the driver source code and build it, you'll need to install mercurial and build essential for the next steps:

     sudo apt-get install mercurial build-essential

Assuming that we're going to build using the SAA7164 stable version (the steps to build using the latest DVB drivers are outlined at http://linuxtv.org), fetch the source from the Kernel Labs site:

     cd ~/SAA7164
     hg clone http://kernellabs.com/hg/saa7164-stable/

Build the driver as follows:

     cd saa7164-stable
     make

Once the build is successful, install it with:

     sudo make install

Note that, if you install another kernel version (i.e. as a result of upgrading to a new release), you will have to rebuild the driver again (unless, of course, the driver is now supported by your release [e.g. Mythbuntu 11.04, 11.10 or 12.04]):

     cd ~/SAA7164/saa7164-stable
     make distclean
     make
     sudo make install

Some Internet notes about how to set up the HVR-2250 capture cards say that you need to add the following lines to the /etc/modprobe.d/options file:

     # Make the HVR-2250 work.
     options saa7164 card=4

We have not found this to be the case but your mileage may vary. If you think this option will help you, now is the time to add it, before you reboot your system with the new driver.

You will have to reboot your system for the new driver to take effect:

     sudo /sbin/shutdown -r now

You can now set up the HVR-2250 capture card through the MythTV backend configuration. Note that you should always set up the HVR-2250 capture cards as DVB cards (the card itself will be listed as a Samsung S5H1411). The proper choice is "DVB DTV capture card (v3.x)".

You will be able to set up the first encoder on the card when you add it the first time. Once you've done that, add a second encoder and you will then be able to set up the second encoder.

As with the pcHDTV cards, for the HVR-2250, a couple of options that you will probably want to use are:

     Recording Options
     Max Recordings: 1
     Open DVB Card on demand: (check)

If you are getting your guide data via EIT, you will probably only want to enable it on one of the encoders. Pick either the first or the second encoder and check the EIT box:

     Use DVB card for active EIT scan: (check one only)

We have also found that you may need to change the signal tuning timeout from the default of 500 to a more forgiving 3000. You can try going with the default and see where that gets you but we have noticed that some channels (with perfectly strong signals, by the way) do not tune in the allotted time. Since MythTV just silently gives up on recordings without any word of warning, if anything goes wrong, getting this number right is important.

After all this is done, you should be able to see both HVR-2250 encoders. The acid test is if they show up when you Watch Live TV and switch the source. You should be able to switch to both the encoders. If they are not visible in Live TV, we have found that recycling the mythtv-backend task on the master backend system (if your configuration has multiple systems) may be required for them to show up. Not until they show up in Live TV, will the system begin using them for recordings.

NOTA BENE! The HVR-2250 encoders each have an analog encoder defined for them too. Depending on which order you have the cards inserted in your PCI slots, the analog encoders on the HVR-2250 can usurp the positions normally taken up by regular analog encoders. Therefore, if you are also using an analog encoder (e.g. in a system that has a PVR-150 installed along with the HVR-2250), you may find that the HVR-2250 defines its analog encoders as /dev/video0 and /dev/video1, and that the true analog encoder is /dev/video2. In this case, aiming the MythTV analog encoder at /dev/video0 will not only cause the analog encoder to not be recognized but it will also break both digital encoders on the HVR-2250. So, if your system is configured thusly and none of your encoders shows up, try aiming MythTV at /dev/video2 instead.

Ceton InfiniTV-4

The Ceton InfiniTV-4 provides four CableCARD tuners on a single PCIe 1x card which can simultaneously tune up to four cable channels using a single M-type CableCARD, obtained from your cable company. Depending on which cable company and service you are subscribed to, the exact channels that Mythbuntu will receive can vary. However, the card is also capable of being used without a CableCARD to tune Clear QAM channels.

For the first part of the installation, install the InfiniTV-4 into your system but do not install the cable card yet. There is a bug (or is it a feature) in the card's code that prevents a clear QAM channel's program number from being selected unless the cable card is not installed, and we will be doing basic tests on clear QAM channels first, as part of the installation verification process.

To set up this card on Mythbuntu, you first need to make sure that your version of MythTV is version 0.25 or greater. If you have installed Mythbuntu 12.04 or greater, you will have the requisite version of MythTV.

Next, obtain the latest InfiniTV-4 Linux driver source from:

     http://cetoncorp.com/infinitv_support/linux_drivers/

We downloaded the following files:

     ceton_infinitv_fw_20120313_1_1_7_2.IMAGE   (latest firmware)
     ceton_infinitv_linux_driver_1_7.tar.gz     (device driver)
     infinitv_client_1_2.tar.gz                 (client program)
     reset_network.py                           (Python program to reset card)

To build the driver, make sure you have the driver build environment (this is not necessarily the full kernel build environment). To verify that you do have the driver build environment, try:

     ls -l /lib/modules/`uname -r`/build

If you have this directory installed, you're good to go (Ubuntu usually provides it in a typical installation). Otherwise, you'll need to first get the build environment, either using the Package Manager or by doing:

     sudo apt-get install build-essential

Then, you should make sure to install the latest headers for your kernel. When you enter the following command, be sure to use back-quotes:

     sudo apt-get install linux-headers-`uname -r`

Finally, if the link doesn't already exist, link the headers to the build folder in the proper place. This should get you compiling:

     sudo ln -s /usr/src/linux-headers-`uname -r` /lib/modules/`uname -r`/build

Extract the InfiniTV-4 source from the tar file, build then install it:

     make
     sudo make install

The install will do a depmod and install a udev config file so that the device driver will start up properly at the next boot up. If you don't want to reboot, you can load the driver manually like this:

     sudo modprobe ctn91xx

You should now see a pseudo network device with an address of ctn0, which can be observed by typing:

     /sbin/ifconfig

In all probability, the ctn0 device will have an IPV6 address but will not be given an IPV4 address. It will usually be given a MAC address that is of the form 00:22:2c:ff:ff:ff. You should make a note of this MAC address.

The interface to the InfiniTV-4 is via the network. The local network, on the machine where the InfiniTV-4 is installed, is kludged to connect to a device with an IP address of 192.168.200.1 which is actually the control interface of the card (if there are multiple InfiniTV-4 cards installed on the machine, the second card will be given an IP address of 192.168.200.3, the third 192.168.200.5, etc.). In order for the system to talk to the InfiniTV-4, there must be a network device configured on the machine itself which is on the same subnet as the InfiniTV-4 (i.e. 192.168.200.x). This is where the ctn0 device comes in.

The ctn0 device must be given an IPV4 address which is on the 192.168.200.x subnet. Usually, the address 192.168.200.2 is chosen. Note that, only a single address must be assigned to the ctn0 device even if there are multiple InfiniTV-4 cards installed. There is never a ctn1, ctn2, etc. device, since the ctn0 device will suffice to talk to all of the cards.

The InfiniTV-4 card runs a DHCP server on the 192.168.200.1 IP address. If you have an installation of Mythbuntu that doesn't use a static IP address (i.e. that uses DHCP), the DHCP client that runs on your system should obtain a 192.168.200.x IP address from the card at boot time and assign it to the ctn0 device. If you are using static IP addresses or DHCP is disabled for any other reason or you just wish to assign the same static address every time, you will have to add the ctn0 device to your network configuration by editing /etc/network/interfaces:

/etc/network/interfaces:

.

       .

auto ctn0
iface ctn0 inet static

      hwaddress ether 00:22:2c:ff:ff:ff
      address 192.168.200.2
      netmask 255.255.255.0
       .
       .
       .

At this point, you should reboot the system. After the reboot, the ctn91xx driver should come up and a 192.168.200.x IP address should be assigned to the ctn0 device. You can check this again with:

     /sbin/ifconfig

You can also check to see that all of the Ceton devices are created properly by listing them like this:

     ls -l /dev/ceton

You should see devices like:

     crw-rw-rw-  1  root root  231,  0  Aug 10  14:50  ctn91xx_ct10
     crw-rw-rw-  1  root root  231,  7  Aug 10  14:50  ctn91xx_filter0_0
     crw-rw-rw-  1  root root  231,  8  Aug 10  14:50  ctn91xx_filter0_1
     crw-rw-rw-  1  root root  231,  9  Aug 10  14:50  ctn91xx_filter0_2
     crw-rw-rw-  1  root root  231, 10  Aug 10  14:50  ctn91xx_filter0_3
     crw-rw-rw-  1  root root  231, 11  Aug 10  14:50  ctn91xx_filter0_4
     crw-rw-rw-  1  root root  231, 12  Aug 10  14:50  ctn91xx_filter0_5
     crw-rw-rw-  1  root root  231,  1  Aug 10  14:50  ctn91xx_mpeg0_0
     crw-rw-rw-  1  root root  231,  2  Aug 10  14:50  ctn91xx_mpeg0_1
     crw-rw-rw-  1  root root  231,  3  Aug 10  14:50  ctn91xx_mpeg0_2
     crw-rw-rw-  1  root root  231,  4  Aug 10  14:50  ctn91xx_mpeg0_3
     crw-rw-rw-  1  root root  231,  5  Aug 10  14:50  ctn91xx_mpeg0_4
     crw-rw-rw-  1  root root  231,  6  Aug 10  14:50  ctn91xx_mpeg0_5

Another good test is to try pinging the 192.168.200.1 device:

     ping 192.168.200.1

If you get a response, you are in business. Using the Web browser on the machine where the InfiniTV-4 is installed (you must be on the machine where the card is installed because the 192.168.200.x subnet is not visible anywhere else on your local network), you can view the device Web page at http://192.168.200.1. The best way to view this page is to exit out of MythTV and launch the browser from the desktop.

Note that, if you can't get a response or see the InfiniTV-4 at the 192.168.200.1 IP address (or 192.168.200.3, or 192.168.200.5, etc., if you have multiple cards installed), you may need to adjust your firewall settings. If you have a firewall that is local to the system where the device is installed (and only if it is local to that system), you need to permit all traffic on the 192.168.200.* subnet. Since this subnet exists only on the local machine, there is no harm in not firewalling this traffic. Otherwise, if you have a normal network where the firewall is external to the system where the InfiniTV-4 is installed, there's no need to do anything.

Also note that, if you still can't get a response or see the InfiniTV-4, you might want to try the "reset the IP address program", reset_network.py. Download this file and run the code using the Python interpreter. Hopefully, it will reset the card to the proper IP address but you may have to hack the code to get it to do the right thing when multiple cards are installed.

The latest firmware should be loaded into the InfiniTV-4 card before you proceed much further. One of the cards that we received in 2012 had two-year old firmware. Because newer is always better, we got the latest firmware revision from the Ceton Web site (noted above). Loading new firmware into the card is very easy. From the "System" tab of the device Web page, the new firmware file can be browsed for from the "Browse" button at the bottom of the page. Once you find the file, it is uploaded to the device by clicking the "Upload" button. The process takes about 5 minutes. When the upload is done, you should reboot the machine. That's all there is to upgrading the new firmware.

Once again, surf over to the device Web page at http://192.168.200.1. This time, pick the first tuner and then select the "Tuner" tab. You will see a spot where you can enter a frequency. If you know the frequency and program number of any of the clear QAM channels that your cable provider is "required" to broadcast, you can enter the frequency in the "Frequency" box and click the "Tune" button (leave the "Modulation" box set to QAM256). Note that the frequency is in KHz so don't enter something like 525000000. Instead, for example for channel 74, enter 525000. If you don't know what the clear QAM channel frequencies are for your cable provider, you may be able to find them here:

     http://www.silicondust.com/support/channels/

As an example, to use this Web page to find a test channel that one could tune to, one could look up KTLA-DT under Time Warner Cable for the zip code 90210 where one would find:

     89-543   (channel 89, program 543)

Channel 89 has a center frequency of 615000 KHz so one would enter that number before hitting the "Tune" button. At that point, you should see the number 543 listed among the programs carried on that channel, whereupon you can pick that program from the dropdown list and then click the "Set Program" button. Again, as we noted above, setting the program will not work if the cable card is installed so we hope you heeded our advice about leaving it out for now.

Another way to find out what programs are broadcast in the clear by your cable provider, if you have a regular HDTV encoder installed in your system, is to look at the list of channels that were scanned by MythTV when you set that encoder up. You can do a select from the database, like this:

     select callsign, channum, channel.mplexid, channel.serviceid,
         dtv_multiplex.frequency
       from channel join dtv_multiplex on channel.mplexid = dtv_multiplex.mplexid
       where callsign like 'KTLA%';

A third way is to look at the channel map that is created by your television set, if it provides such a map.

Once you have picked a channel frequency and program number for a clear QAM channel that is broadcast by your cable provider, from the device Web page, you can check that the card has tuned to that channel correctly and that you can view the selected program. The device driver creates special devices for each of the four tuners on the card and one of them (named like ctn91xx_mpeg0_0, as shown in the listing above) carries the stream for the selected channel/program on the first tuner. You can view it with this command, entered into a command window that is open on the desktop:

     cat /dev/ceton/ctn91xx_mpeg0_0 | mplayer -cache 8192 -

If you see the correct TV program for the selected channel/program, you have installed the card correctly.

It is now time to proceed to pairing the cable card with the InfiniTV-4. Shut down the system and insert the cable card into the InfiniTV-4. Once that is done, start the system back up.

To pair the cable card with the InfiniTV-4, you will need to surf over to the device Web page again and pick the "CableCARD" tab. Under this tab, you will will see a link that says something like "CableCARD(tm) Pairing". When you click this link, a new page will appear that shows a phone number to call and the following information:

     CableCARD ID: nnn-nnn-nnn-nnn-n
     Host ID: nnn-nnn-nnn-nnn-n
     Data: nnn-nnn-nnn-nn
     UnitAddress: nnn-nnnnn-nnnnn-nn
     Card S/N: ccnnnnccnnnn
     eCM MAC: Unknown
     Host MAC: hh:hh:hh:hh:hh:hh
     Host Type: One-way

You'll need some or all of this information to pair the cable card with the InfiniTV-4.

If you are lucky enough to be a Verizon FIOS customer, you can pair them by surfing over to this link:

     http://www.verizon.com/fiostv/selfinstall

You will need the activation code that came on the Customer Receipt that was shipped with the cable card. Follow the instructions on the Web site to pair the cable card. For us, it took about two minutes after we completed entering the pairing information for Verizon to send the activation message to the cable card and activate it. After that, the channel map showed up in about 10 or 15 minutes.

Otherwise, you should call the phone number that was shown on the "CableCARD(tm) Pairing" page. Good luck with the cable company. You may find yourself, unable to speak to a human, in a IVR menu loop that doesn't do you any good. If that's the case, you can try saying the word "operator" to get to a real human. This works, for example, on the Verizon activation line.

Once the CableCARD is paired with the InfiniTV-4, you should be able to verify this fact by going to the "CableCARD" tab of the device's Web page. There you will see a message that says something like, "Activated, activation message received, authenticated ...". If you see that, there is a good chance that the pairing has been successful. If you don't see it, the pairing was unquestionably unsuccessful.

After the channel map arrives, you can view it from the same "CableCARD" tab of the device's Web page. Further down the page, you'll see the "Number of Channels" field. Intuitively, if you click on the "Number of Channels" field tag (i.e. click on the string "Number of Channels" itself), you will be shown the channel map. This will give you an idea of the channel numbers that you can use to tune the InfiniTV-4's tuners.

Pick a channel number that is obviously an encrypted channel (e.g. USA, TNT, A&E). Go to the "One" tab of the device's Web page and then click the "Tuner" therein. You will see a "Channel" where you can enter your chosen channel's number. Click the "Set Channel". This will cause the channel map to be used to look up the actual channel frequency and program number, for the virtual channel that you entered, and tune the first tuner to them. You should now be able to view the chosen channel with this command, entered into a command window that is open on the desktop:

     cat /dev/ceton/ctn91xx_mpeg0_0 | mplayer -cache 8192 -

If you see the correct TV program for the selected virtual channel, you have paired the CableCARD correctly and it is initialized with the correct rights, etc. If not, you've got some troubleshooting to do.

Go to the "Log" tab of the device's Web page and scroll down to bottom of the log. If you see something that looks like this:

     [0] Sending ca_pmt to CableCARD for program number 108 index 0
     WARNING: [0] Timed out waiting for CCI (recvd 0)

That is to say, the CableCARD timed out and didn't send a CCI. If you see such a log entry, your CableCARD has not been set up properly, regardless of whether it is paired properly and what it says on the CableCARD tab.

You need to get on the phone with your cable provider's Tech Support. If you can't get your point across to the Tier 1 support people and convince them to do what you ask (i.e. reset the CableCARD), try to get them to connect you to the Tier 2 support people.

What you need to do is convince Tech Support to send your CableCARD a master reset, which is sometimes called a grandslam hit, or a cold hit, or a DAC Init hit. This will cause it to be reinitialized with the correct rights (i.e. the ability to decrypt the content you've paid for). Despite the fact that the card is paired and authorized correctly, channel decryption may not work correctly until you do this.

On the other hand, if you see a log entry that says something like this:

     [0] CCI 01 arrived for program 108

You are never going to see this channel (or at least the current content on this channel) because DRM will not permit it. Choose another channel. If they all have the same problem, you are probably out of luck, but its a good bet that you will only experience this problem on the premium channels that your cable provider broadcasts (e.g. even if you are subscribed to HBO, you are probably not going to be able to see it).

Incidentally, just for reference sake, here's a list of the CCIs and what they mean:

     0x00 - Copy Freely.
     0x01 - Copy No More.
     0x02 - Copy Once (the content can be recorded).
     0x03 - Copy Never (the content can be recorded but only viewed in the
              next 90 minutes, whereupon it is deleted).

By the way, if you are still experiencing problems with encrypted channels, you may be tempted to try the Python client program that is provided by Ceton. Our advice is to eschew this turkey. We extracted it, fixed the bugs in it so that it would run, and then tried it out. It did let us set the channel number on a tuner but then it just sat there looking stupid. When we cancelled it, it left a process hanging around that locked the tuner. Even as root, we couldn't kill the process. Thus, after using it a few times, we had to reboot the sytem to get the tuners back. Swell behavior for a program that does essentially nothing (you can tune to any channel from the Web UI as many times as you like).

Anyway, until you can see at least one encrypted channel with mplayer, using the device's Web page to tune to the channel, there's no point in proceeding to set up MythTV (unless all you want is unencrypted channels -- in which case, why did you get the CableCARD in the first place).

When you are ready to set up your InfiniTV-4 under MythTV (remember you need Myth 0.25 or greater), you may find that some preparatory work is beneficial. Certainly, you can use a listings source such as Schedules Direct, along with mythfilldatabase, to get a channel lineup, and then select it when you connect the card to the input source.

To do this, you should create a video source normally, from the Backend Setup screens. If you are using a listings source (such as Schedules Direct), select it from the dropdown list. When you set up the four tuners on the InfiniTV-4, you will connect the video source to the input of each recorder. There is no need to do a channel scan if you are using a CableCARD. Simply click the "Fetch channels from listings source" button when making the the input connection. If, on the other hand, you aren't using a CableCARD with the InfiniTV-4, then you will need to click "Scan for channels" just as if it were a conventional Clear QAM card.

We, however, prefer to build our channel lineups ourselves, manually. To do this, we begin with the virtual channel map that is sent by the cable provider to the InfiniTV-4. If your cable provider is like ours, you'll see about 700 channels in the virtual channel map. Probably 40 or 50 of them are all that you really care about. If there are only a few of them, you can write them down by hand by proceeding to the "CableCARD" tab of the device's Web page. Near the bottom of the page, you'll see the "Number of Channels" field. As we said above, intuitively, if you click on the "Number of Channels" field tag (i.e. click on the string "Number of Channels" itself), you will be shown the channel map.

If there are a lot of channels that you are interested in, you can try to download the channel map to a file. Unfortunately, the channel map is displayed by a routine on the Web page that uses Ajax (i.e. there is nothing to save, if you save the page itself). To figure out where the channel map is being loaded from, you need to look at the page source. The last time we did this, the channel map's pages were being loaded from:

     http://192.168.200.1/view_channel_map.cgi?page=1

You can view subsequent channel map pages by using page numbers 2, 3, etc. The pages will be shipped to your Web browser as basic HTML pages, which can be saved, one at a time, to flat files. You can then combine and edit them to get a complete channel list. For us, the channel list looks something like this:

.

       .

550 USA Network HD
551 TNT HD
552 TBS HD
553 FX HD

       .
       .
       .

We prefer to manually check all of the channels in the channel map, that we want to include in our MythTV lineup, before we build the lineup. That way, we know what will work beforehand, without needing to account for any MythTV strangeness. However, this process is quite laborious and you may wish to skip it. It is certainly not required.

To create a lineup by hand, we construct an SQL file that cleans out any pre-existing lineup, from the channel table, and then builds a new lineup from the SQL statements that we supply.

The first step is to determine which source ID to use. This can be extrapolated from the existing source IDs, which can be listed from the database like this:

     select sourceid from channel group by sourceid;

Pick a source ID that isn't already in the channel table and start by adding it (you only need to do this once) to the database like this (here we're assuming a source ID of 5):

     insert into videosource values(5, 'Fiber-CC', '/bin/true', '', 'us-cable',
       NULL, NULL, 0, NULL, -1);

You can also add the new video source from the backend setup GUI but we find that this approach involves too much screwing around. A simple SQL insert command is so much easier. Your mileage may vary.

The next step is to begin constructing the SQL file that will create the lineup by starting with a line that deletes any preexisting lineup:

FIOS-Mytown_CCardLineup.sql:

     -- WARNING: The following line clears out the Fiber-CableCard channels in
     --          the channel table
     delete from channel where sourceid=5;
          .
          .
          .

Now, we add an entry for each channel that we care about, that is found in the virtual channel table sent by the cable provider. These entries should include the channel number and frequency to tune to (the same number), the chosen source ID, the call sign, the name and an XMLTV ID. You can also set the visible attribute to either show the channel in the channel list or not. All the rest of the fields can probably take the defaults. A typical entry will look like:

FIOS-Mytown_CCardLineup.sql:

.

       .

-- Add the HD virtual channels supported by the CableCARD insert into channel set chanid=5550, channum='550', freqid=550, sourceid=5, callsign='USA-CCFi', name='USA Network HD', icon='', finetune=NULL, videofilters='', xmltvid='5550', recpriority=0, contrast=32768, brightness=32768, colour=32768, hue=32768, tvformat='Default', visible=1, outputfilters='', useonairguide=0, mplexid=NULL, serviceid=NULL, tmoffset=0, atsc_major_chan=0, atsc_minor_chan=0, last_record='0000-00-00 00:00:00', default_authority='', commmethod=-1;

       .
       .
       .

Proceed through all of the virtual channels that you wish to see, from the channel table that was obtained by the InfiniTV-4.

Pay particular attention, if you will be loading your own guide data (see Making Up Guide Data) or using one of the XMLTV grabbers to obtain guide data. Ensure that you set the xmltvid field to the channel identifier that matches the second display-name that the XMLTV data uses for each channel. Typically, this is the channel number or call sign but you may want to inspect the XMLTV data first to determine what to use.

A complete set of updates should look something like this:

FIOS-Mytown_CCardLineup.sql:

     -- WARNING: The following line clears out the Fiber-CableCard channels in
     --          the channel table
     delete from channel where sourceid=5;
     -- Add the HD virtual channels supported by the CableCARD
     insert into channel set chanid=5550, channum='550', freqid=550, sourceid=5,
       callsign='USA-CCFi', name='USA Network HD',
       icon='', finetune=NULL, videofilters='', xmltvid='5550', recpriority=0,
       contrast=32768, brightness=32768, colour=32768, hue=32768,
       tvformat='Default', visible=1, outputfilters='', useonairguide=0,
       mplexid=NULL, serviceid=NULL, tmoffset=0,
       atsc_major_chan=0, atsc_minor_chan=0, last_record='0000-00-00 00:00:00',
       default_authority='', commmethod=-1;
     insert into channel set chanid=5551, channum='551', freqid=551, sourceid=5,
       callsign='TNT-CCFi', name='TNT HD',
       icon='', finetune=NULL, videofilters='', xmltvid='5551', recpriority=0,
       contrast=32768, brightness=32768, colour=32768, hue=32768,
       tvformat='Default', visible=1, outputfilters='', useonairguide=0,
       mplexid=NULL, serviceid=NULL, tmoffset=0,
       atsc_major_chan=0, atsc_minor_chan=0, last_record='0000-00-00 00:00:00',
       default_authority='', commmethod=-1;
          .
          .
          .

Be aware that you can have two channels with the same number (especially if one is analog and one is digital) but you probably won't be happy with the consequences. For example, despite the fact that you're viewing TV using a digitial encoder, and you've defined a digital channel 12, entering 12 on your remote, to change to that digital channel, may result in MythTV switching to an analog encoder and showing you analog channel 12 instead. Worse yet, recordings may end up on the wrong encoder (see How MythTV Chooses Which Input To Record).

Consequently, for virtual channels that mirror analog channels, it is much better to move them to a higher range (such as 5nn), thereby keeping them unique. The channel number given by "channum" is the displayed channel number. The virtual channel that is tuned by the InfiniTV-4 is the number given by "freqid". The two numbers are usually kept the same but they need not be. Note that you can use anything you like for "channum" but, if you don't use numerics and you don't use the proper separator character, MythTV will sort your channels in odd order.

Once you've built your channel definitions file, you can feed it in to MySQL with this command:

     source /path/to/file/FIOS-Mytown_CCardLineup.sql

Setting up the four tuners on the InfiniTV-4 is anticlimatic. Once you've completed all of the above steps, you know that the device is working and you have what should be a good lineup already built. All that is left is to run the MythTV Backend Setup program from the System menu on the desktop. Before it comes up, you'll be asked to shut down the backend, for which your password is required.

From the first menu, pick "Capture Cards". The screen that comes up lists all of the currently defined cards (if any) and has a selection for adding new cards. Pick "New capture card."

On the first capture card page, you need to pick "Ceton Cablecard Tuner" from the dropdown list under "Card type:". You will then fill in the IP address that you assigned to the first (or only) InfiniTV-4 under the "IP Address:" field. Despite the fact that the help text says the default is 192.168.200.1, you must actually fill this IP address in. If you have more than one InfiniTV-4, the next IP address will probably be 192.168.200.3, and so on.

For some reason, you must fill in the card number under the "Card Number:" field, although the IP address should be sufficient to actually identify the device. For the purposes of this field, the first card is numbered 0, the second is numbered 1, and so on.

The last field to be filled in is the "Tuner:" field, which identifies the tuner on the device that is being set up. Note that, in the case of the InfiniTV-4, the device has four tuners. You must define each one individually, repeating all of these steps as each is set up. The first tuner is numbered 0, the second is numbered 1, and so on up to 3.

When you have correctly entered all of the information, a device ID will be made up that looks like "192.168.200.1-0.0". This device ID will be used to refer to the tuner from henceforth. You can click the "Finish" button and the new capture card will be defined.

After you've set up all of the InfiniTV-4 tuners/capture cards, you should exit the "Capture Cards" screen and select "Input Connections" from the main menu. It is here that you will associate the new tuners/capture cards with your previously created lineup. Select each new tuner/capture card from the list and set it up on the ensuing two pages.

On the first page, pick a unique display name that can be used to reference the card and fill it in under the "Display Name:" field. Under the "Video Source:" field, pick your newly-created lineup. The "Use quick tuning:" field should be set to "Never".

As discussed above, there is no need to click either the "Scan for channels" or "Fetch channels from listings source" buttons. Hopefully, you have already built a channel lineup.

The "Starting Channel:" field's value should default to the first channel number defined in your lineup. If you'd rather start on a different channel, you can enter it here but this number is changed every time someone watches Live TV on this tuner so there's no need to stress out over it. It does need to be a valid channel number, though, or the tuner may hang when someone tries to watch Live TV.

When you click the "Next" button, you'll see the second capture card setup page. All of the default values there are acceptable so you just need to click "Finish" to set up the new tuner/capture card. Don't forget to set up all four tuners/capture cards.

When you've set up all four tuners, you can exit the Backend Setup program and restart the backend. You'll need to reenter your secret password for this. We never bother to run mythfilldatabase. You should now be able to record or watch Live TV on all four (or 8, or 12) tuners at once.

A Personal CableCARD Story

If your cable provider is Verizon, you might enjoy this personal CableCARD activation story.

Verizon makes obtaining a CableCARD pretty easy, compared to some of the stories that we've heard about the other cable providers. You can either order one off the Web site or phone customer service and order it that way. When we did it, the card showed up a couple of days later.

The instructions say to just pop the cable card into your STB or DVR and follow the activation steps on the printed sheet that they send you. You have two options. Call the activation hotline or use the activation Web page.

We opted to try the Web site. You need to obtain the Host ID and Data strings from your STB or DVR, or in our case, your PCIe or USB device. We got this information from our adapter card's Web UI and filled it in on the Web site.

Within two minutes, the CableCARD was paired and activated. The activation message had been received, etc., etc. Within 10 minutes, the channel map had shown up. Things were looking good. But, there was no decryption. Only the unencrypted channels were available.

Parenthetically, the people at the adapter card's Tech Support were absolutely no help. They tried to tell us that it was a DRM issue and that only Windoze would work. Apparently, they, like the rest of the world, see the word Linux and can only respond with the W word. The fact that the problem had nothing to do with the OS, in any way, shape or form, was irrelevent. So, bear this in mind when you think about contacting your hardware vendor first. You'll probably be wasting your time. More likely than not, you're on your own in that respect.

Fortunately, the guys who wrote the firmware for the card we were using included some pretty good logging capabilities so we were able to figure out what was really going on. Reading the logs also lead us to find the vendor's position on Linux more than a little bit comical since, unless we miss our guess, the adapter card runs a version of Linux itself. Not sure the guys in Tech Support see that irony, though.

But, we digress. While it is true that Verizon is no longer the Wild West (as of July 31, 2012 their CableCARDs will no longer work with any device, without pairing), and the premium content channels are no longer sent with no CCI set, there is still a lot of content which is available on Linux, without DRM. Typically, depending on your subscription plan, this includes all of the standard cable channels like USA, TBS and A&E, in both SD and HD. So, the fact that there were no encrypted channels available implied that something else was wrong, not DRM.

Thinking that the Web site might not have set the card up the same way that the activation hotline would (there was precedence on the Internet to this effect), we called the phone number.

After taking the initial steps and waiting 20 minutes, we called back (since there was no STB/DVR setup menu that we could use to complete activation). At this point, we got the IVR menu loop: "We see that you have partially completed activation. Go to your STB/DVR and follow the instructions. Call back if you experience problems. Press 8 to rehear these instructions; 9 to end this call; or just hang up."

Since Verizon is doing voice recognition, at this point we spoke the word "operator" (not one of the listed options, by the way). The system said it would transfer us to an agent. We spent 25 or 30 minutes on hold (reading Brucie's blog and listening to the same 32 bars of mindless hold music in an endless loop), waiting for the agent.

When we got the Tech Support person on the line, they had no idea what to do. They asked us where the cable card was installed, and, when we said it was a computer, they asked us if it could connect to the Internet. Eventually, after explaining things a few times (Verizon, by the way, does not care what your cable card is plugged into but you sort of have to get them to accept the fact that it ain't a STB/DVR), we convinced them to do a grandslam hit/cold hit/DAC Init hit/master reset (or whatever it is called). The tech had to have two conversations with the supe befoe they got him the right proceedure to do the reset. The reset worked right away.

Total time for the call about 1 hour.

Incidentally, the problem apparently was caused by the fact that we ordered the CableCARD before July 31, 2012 and it shipped with the wrong rights enabled. By doing the reset, it reloaded the card with the correct rights. Had we ordered the card now, it might have worked right away.

The moral of this story is that, even if your CableCARD says it is paired and activated, it may not work properly. If that's the case, convincing your cable provider to reset it may get things moving along smartly.

Figuring Out Which Card Is Which

Let's say that you have a Mythbuntu system that has a Hauppauge PVR-150, a HD 800i and a HVR-2250 installed in it (All Hauppauge, All The Way). Now, it comes time to configure each one and all you see is:

     Probed Info: Probe failed

Which card is which? You need to know because you have several different inputs attached to each one (e.g. cable company DTA on the PVR-150; the cable as a direct input on the HVR-2250; and a terrestrial antenna on the HD 800i). Without setting them up correctly, MythTV will be trying to record the wrong programs on each encoder.

You can start with a listing of all of the devices on the PCI bus:

     sudo lspci -v

This should give you a (partial) listing that looks something like this:

     01:08.0 Multimedia video controller: Internext Compression Inc iTVC16
         (CX23416) Video Decoder (rev 01)
       Subsystem: Hauppauge computer works Inc. WinTV PVR 150
       Flags: bus master, medium devsel, latency 64, IRQ 17
       Memory at f0000000 (32-bit, prefetchable) [size=64M]
       Capabilities: [44] Power Management version 2
       Kernel driver in use: ivtv
       Kernel modules: ivtv
     01:0a.0 Multimedia video controller: Conexant Systems, Inc.
         CX23880/1/2/3 PCI Video and Audio Decoder (rev 05)
       Subsystem: Pinnacle Systems Inc. Device 0051
       Flags: bus master, medium devsel, latency 32, IRQ 18
       Memory at fc000000 (32-bit, non-prefetchable) [size=16M]
       Capabilities: [44] Vital Product Data
       Capabilities: [4c] Power Management version 2
       Kernel driver in use: cx8800
       Kernel modules: cx8800
     01:0a.1 Multimedia controller: Conexant Systems, Inc.
         CX23880/1/2/3 PCI Video and Audio Decoder [Audio Port] (rev 05)
       Subsystem: Pinnacle Systems Inc. Device 0051
       Flags: bus master, medium devsel, latency 32, IRQ 18
       Memory at fb000000 (32-bit, non-prefetchable) [size=16M]
       Capabilities: [4c] Power Management version 2
       Kernel driver in use: cx88_audio
       Kernel modules: cx88-alsa
     01:0a.2 Multimedia controller: Conexant Systems, Inc. CX23880/1/2/3
         PCI Video and Audio Decoder [MPEG Port] (rev 05)
       Subsystem: Pinnacle Systems Inc. Device 0051
       Flags: bus master, medium devsel, latency 32, IRQ 18
       Memory at fa000000 (32-bit, non-prefetchable) [size=16M]
       Capabilities: [4c] Power Management version 2
       Kernel driver in use: cx88-mpeg driver manager
       Kernel modules: cx8802
     02:00.0 Multimedia controller: Philips Semiconductors SAA7164 (rev 81)
       Subsystem: Hauppauge computer works Inc. WinTV HVR-2250
       Flags: bus master, fast devsel, latency 0, IRQ 19
       Memory at fd400000 (64-bit, non-prefetchable) [size=4M]
       Memory at fd000000 (64-bit, non-prefetchable) [size=4M]
       Capabilities: [40] MSI: Enable- Count=1/16 Maskable- 64bit+
       Capabilities: [50] Express Endpoint, MSI 00
       Capabilities: [74] Power Management version 3
       Capabilities: [7c] Vendor Specific Information: Len=84 <?>
       Capabilities: [100] Vendor Specific Information: ID=0000 Rev=0 Len=060 <?>
       Capabilities: [160] Virtual Channel
       Kernel driver in use: saa7164
       Kernel modules: saa7164

The first entry is for the PVR-150. From it we can see that the decoder is the Conexant CX23416. The next three entries are for the HD 800i. The first of those three entries shows that the decoder is the Conexant CX23880 (the second and third entries are probably for the FM receiver and the S-video input). The last entry is for the HVR-2250. From it we can see that the decoder is the Philips SAA7164.

In another instance, the Mythbuntu system may have a earlier Hauppauge PVR-150 card, a pcHDTV HD-5500 card, and an AverMedia A180 card installed. Its (partial) PCI bus listing might look like this:

     01:06.0 Multimedia video controller: Conexant Systems, Inc.
         CX23880/1/2/3 PCI Video and Audio Decoder (rev 05)
       Subsystem: pcHDTV Device 5500
       Flags: bus master, medium devsel, latency 64, IRQ 18
       Memory at df000000 (32-bit, non-prefetchable) [size=16M]
       Capabilities: [44] Vital Product Data <?>
       Capabilities: [4c] Power Management version 2
       Kernel driver in use: cx8800
       Kernel modules: cx8800
     01:06.1 Multimedia controller: Conexant Systems, Inc. CX23880/1/2/3
         PCI Video and Audio Decoder [Audio Port] (rev 05)
       Subsystem: pcHDTV Device 5500
       Flags: bus master, medium devsel, latency 64, IRQ 18
       Memory at de000000 (32-bit, non-prefetchable) [size=16M]
       Capabilities: [4c] Power Management version 2
       Kernel driver in use: cx88_audio
       Kernel modules: cx88-alsa
     01:06.2 Multimedia controller: Conexant Systems, Inc. CX23880/1/2/3
         PCI Video and Audio Decoder [MPEG Port] (rev 05)
       Subsystem: pcHDTV Device 5500
       Flags: bus master, medium devsel, latency 64, IRQ 18
       Memory at dd000000 (32-bit, non-prefetchable) [size=16M]
       Capabilities: [4c] Power Management version 2
       Kernel driver in use: cx88-mpeg driver manager
       Kernel modules: cx8802
     01:06.4 Multimedia controller: Conexant Systems, Inc. CX23880/1/2/3
         PCI Video and Audio Decoder [IR Port] (rev 05)
       Subsystem: pcHDTV Device 5500
       Flags: bus master, medium devsel, latency 64, IRQ 10
       Memory at dc000000 (32-bit, non-prefetchable) [size=16M]
       Capabilities: [4c] Power Management version 2
     01:07.0 Multimedia video controller: Internext Compression Inc iTVC16
         (CX23416) MPEG-2 Encoder (rev 01)
       Subsystem: Hauppauge computer works Inc. Device c801
       Flags: bus master, medium devsel, latency 64, IRQ 19
       Memory at d4000000 (32-bit, prefetchable) [size=64M]
       Capabilities: [44] Power Management version 2
       Kernel driver in use: ivtv
       Kernel modules: ivtv
     01:08.0 Multimedia controller: Philips Semiconductors
         SAA7131/SAA7133/SAA7135 Video Broadcast Decoder (rev d1)
       Subsystem: Avermedia Technologies Inc Device 1044
       Flags: bus master, medium devsel, latency 32, IRQ 19
       Memory at e4101000 (32-bit, non-prefetchable) [size=2K]
       Capabilities: [40] Power Management version 2
       Kernel driver in use: saa7134
       Kernel modules: saa7134

The first four entries are for the pcHDTV HD-5500. From it we can see that the decoder is the Conexant CX23880. The next entry is for the PVR-150 but, in this case, the kernel does not recognize its device number. From it we can see that the decoder is the Conexant CX23416. The next entry is for the Avermedia A180, although its device number is unknown too. Its entry shows that the decoder is the Philips SAA7134.

Now that we're armed with this information, we can try setting up the multiple capture cards from the Mythbuntu Capture Card Setup page. Even if the probe fails to return any information about the card, you can still use the decoder information to figure out which card is which.

Capture Card Database Entries

If you need to add or move capture cards, in order to set them up using a rational organization scheme (instead of the last added scheme that MythTV uses), these database entries may come in useful. Here we list the results of a database dump for various types of capture cards:

                           AverMedia A180           pcHDTV 5500
  cardid                   <x>                      <x>
  videodevice              /dev/dvb/adapter0/frontend0 (adapter1 for 2nd dev,
                             frontend1 for 2nd encoder, etc.)
  audiodevice              NULL                     NULL
  vbidevice                NULL                     NULL
  cardtype                 DVB                      DVB
  defaultinput             DVBInput                 DVBInput
  audioratelimit           NULL                     NULL
  hostname                 <hostname>               <hostname>
  dvb_swfilter             0                        0
  dvb_sat_type             0                        0
  dvb_wait_for_seqstart    1                        1
  skipbtaudio              0                        0
  dvb_on_demand            1                        1
  dvb_diseqc_type          NULL                     NULL
  firewire_speed           0                        0
  firewire_model           NULL                     NULL
  firewire_connection      0                        0
  signal_timeout           3000                     3000
  channel_timeout          5500                     5500
  dvb_tuning_delay         0                        0
  contrast                 0                        0
  brightness               0                        0
  colour                   0                        0
  hue                      0                        0
  diseqcid                 0                        0
  dvb_eitscan              <1|0> (set to 1 for EIT scan wanted on this dev)
                           HVR-2250
  cardid                   <x>
  videodevice              /dev/dvb/adapter0/frontend0 (adapter1 for 2nd
                             dev -- card appears as two devices)
  audiodevice              NULL
  vbidevice                NULL
  cardtype                 DVB
  defaultinput             DVBInput
  audioratelimit           NULL
  hostname                 <hostname>
  dvb_swfilter             0
  dvb_sat_type             0
  dvb_wait_for_seqstart    1
  skipbtaudio              0
  dvb_on_demand            1
  dvb_diseqc_type          NULL
  firewire_speed           0
  firewire_model           NULL
  firewire_connection      0
  signal_timeout           3000
  channel_timeout          3000
  dvb_tuning_delay         0
  contrast                 0
  brightness               0
  colour                   0
  hue                      0
  diseqcid                 0
  dvb_eitscan              <1|0> (set to 1 for EIT scan wanted on this dev;
                             we usually only do the scan on the 2nd adapter)
                           PVR-150
  cardid                   <x>
  videodevice              /dev/video0 (video1 for 2nd dev, etc.)
  audiodevice              NULL
  vbidevice                NULL
  cardtype                 MPEG
  defaultinput             Tuner 1
  audioratelimit           NULL
  hostname                 <hostname>
  dvb_swfilter             0
  dvb_sat_type             0
  dvb_wait_for_seqstart    1
  skipbtaudio              0
  dvb_on_demand            0
  dvb_diseqc_type          NULL
  firewire_speed           0
  firewire_model           NULL
  firewire_connection      0
  signal_timeout           1000
  channel_timeout          3000
  dvb_tuning_delay         0
  contrast                 0
  brightness               0
  colour                   0
  hue                      0
  diseqcid                 0
  dvb_eitscan              1 (don't ask why, it just is)
                           InfiniTV-4
  cardid                   <x>
  videodevice              192.168.200.1-0.0 (-0.1, -0.2, -0.3)
  audiodevice              NULL
  vbidevice                NULL
  cardtype                 CETON
  defaultinput             Television
  audioratelimit           NULL
  hostname                 <hostname>
  dvb_swfilter             0
  dvb_sat_type             0
  dvb_wait_for_seqstart    1
  skipbtaudio              0
  dvb_on_demand            0
  dvb_diseqc_type          NULL
  firewire_speed           0
  firewire_model           NULL
  firewire_connection      0
  signal_timeout           1000
  channel_timeout          3000
  dvb_tuning_delay         0
  contrast                 0
  brightness               0
  colour                   0
  hue                      0
  diseqcid                 0
  dvb_eitscan              1 (don't ask why, it just is)

Recording HDTV And Analog TV Using The pcHDTV Cards

The pcHDTV series cards, especially the HD-5500, can be used to record both HDTV (ATSC, QAM-256, etc.) as well as NTSC, analog TV. Mind you, all of the work of converting the analog signal into an MP2 stream suitable for recording is done by your system's processor, not on the card (there's no MPEG encoder on the card), so it will use quite a few processor cycles while you're recording an analog program. And, there's a good chance that the picture will look bad and the sound will be messed up. But, if you're still game to try it, here's how to set a pcHDTV card up.

Begin in MythTV backend setup, Capture Cards, by selecting "New capture card" to add a new capture card and then define the pcHDTV card as a DVB card, not as a pcHDTV card (now, that's intuitive). Also, unless you're into crazy, experimental stuff, pick Recording Options and then on the page that pops up, set Max Recordings to 1. After you're finished, save the card's definition.

Next, select "New Capture Card" again and define a second capture card, this time as an "Analog V4L capture card". Set the device parameters like this (example shows 'x' for the device number):

     Video device:  /dev/videox
     VBI device:    /dev/vbix
     Audio device:  /dev/dspx+1

Note that the correct DSP device for sound input is the device number plus 1. Then, in the device options fields, be sure to set the Audio sampling Rate Limit to 48000. When you're done, save the card's definition.

If you have more than one capture card, you should perform the same two steps over for each additional card. You'll end up with something that looks like this:

     DVB: 0
     V4L: /dev/video0
     DVB: 1
     V4L: /dev/video1

We prefer to define two video sources, one for the HDTV recordings and one for the Analog recordings. That way, we can have channel numbers that overlap and we can easily switch between analog/HDTV recording, simply by selecting the source. We suppose, if you wished, you could just define one source and use it for both types of recording. However, another consideration is that the pcHDTV cards don't seem to switch between ATSC/QAM-256 and NTSC very well and having two sources allows you to break things out better.

Let's proceed as if we were going to define two sources. From the Video Source page, select "New Video Source". Let's say it is a cable source. Call it "Cable-HD". If you're using Schedule's Direct or XMLTV, set that part up. Otherwise, you can select "Transmitted guide only" or nothing for Listings Grabber.

Now, define a second video source by selecting "New Video Source" again. Call it "Cable-An". Again, set up the schedule puller or nothing, as appropriate.

Its time to associate the video sources with the capture cards so that MythTV knows which cards to use to record programs from each of the sources. Do this from the Input Connections page. Begin by selecting "[DVB:x]".

Set the display name to "Card x". Select the Video Source (in this case, "Cable-HD"). If this is the first card that you're associating with the video source, you can click Scan For Channels to fill in the list of channels available from that source. Scanning will take quite a while so be patient. Then, if you have a listings grabber defined, you can click Fetch Channels From Listings Source to fill in the channel information (if it hasn't already been filled in from the HDTV channel definitions).

On the second page, set the recording grouping to a unique value, instead of "Generic". The input groups for the DVB card or cards are usually predefined by MythTV when you add them so its simply a matter of choosing the obvious one. If that's not the case, click on Create A New Input Group and define one. For the DVB cards, this should be something like "DVB0". Then, set Input Group 1 to new group. You can leave Input Group 2 as "Generic".

After saving the DVB input source's options, select: "[V4L: /dev/videox](Television)"; "[V4L: /dev/videox](Composite1)"; or "[V4L: /dev/videox](S-Video)", depending on which input is connected on the pcHDTV card.

Set the display name to "Card x - Analog". Select the Video Source (in this case, "Cable-An"). Again, if this is the first card that you're associating with the video source, you can click Scan For Channels to fill in the list of channels available from that source. Scanning will, again, take quite a while so be patient. Then, if you have a listings grabber defined, you can click Fetch Channels From Listings Source to fill in the channel information.

On the second page, set the recording grouping to the same unique value, instead of "Generic", that you chose for the DVB card (e.g. "DVBx"). The reason for doing this here (and above) is so that MythTV doesn't try to do HDTV and analog recording on the same pcHDTV card at the same time (since it sees it as two devices). By grouping the devices this way, it will only try to start a single recording on the card at any time. To do this, set Input Group 1 to appropriate group. You can leave Input Group 2 as "Generic".

The channel scan may not identify all of the channels that it finds. The analog channels are especially unlikely to have any identifying information associated with them. If you do not have a listings source and don't fetch the channels from said source, you'll have to edit the channel information by hand using the Channel Editor.

Identify the channels from your cable TV lineup or by watching each one for a few minutes (if you live in beautiful, sunny Norwood, see Unnamed Analog Channels Mapped To HDTV, below). Using the channel editor, fill in each unidentified channel with its channel number, call sign and description. Note that channel numbers must be unique within each of the video sources (e.g. there can only be one channel 2 in Cable-HD and Cable-An). However, you can have an analog channel and digital channel in the same video source with the same channel number, if you use the underscore notation for the HD channels (e.g. channel 2 and channel 2_1).

Actually, the channel numbers don't have to be unique within the same video source. But, the capture card will only tune to the first one that it finds with the non-unique channel number so you may never be able to get to the second one.

Incidentally, you should set the "Use on air guide" flag in each of the HDTV channel's entries so that they will attempt to use the on-air guide for late schedule updates. While you're tweaking this flag in channel entries, you can set the flag to not display the channel in the guide and when channel surfing in LiveTV.

If you wish to avoid confusion while you're editing the channels, you can choose either Cable-HD or Cable-An in the channel editor's Video Source selection field and it will only show those channels, instead of all the channels. Then, keep the channel numbers unique within the viewed channels.

Capture Card Numbering

If you are monkeying around with the capture cards on you system, you will soon discover that the numbering of the cards is not to your liking. When cards are added, the table that contains their information (capturecard) uses an autoincrement column to number each card.

Normally, this would be irrelevant except that the card number is shown in certain user displays (e.g. the upcoming recordings display shows which encoder will record each program). If you would like to know which encoder is doing each recording but have no clue which one is 11, or 4, or 7, you can reset the auto increment value in the capturecard table so that the encoders are numbered sequentially from 1.

Begin by deleting all of the capture cards, using the MythTV Backend Setup program and selecting the Capture Cards section. The Delete All Capture Cards choice will get rid of all the capture cards. Then, do the following from the command prompt:

     mysql -umrwizard -psecretpassword mythconverg
     alter table capturecard auto_increment=1;
     quit

This will reset the auto increment value to 1. You can then re-add all of the capture cards in the order that you like (note that you must do this on each individual machine in the system), making sure to choose the correct options for each one. The cards will be numbered sequentially, from 1, in the order that they are added. Incidentally, if you are going to be using MythWeb, you can also give them more meaningful names (e.g. "HDTV 1" or "Analog 1") for it to use.

Incidentally, if you have any recording rules that are set to use a preferred input, they may not work after you move any of the capture cards around. You can check which recording specified a preferred input. From the database command prompt (see above), you can use this command:

     select recordid, title, prefinput from record
       where prefinput != 0 order by prefinput asc, title asc;

You should be able to figure out which recording rules need to be reset to a different preferred input.

Video Sources

It is here that you define your video signal sources. Typical sources might be Antenna (for an over-the-air signal captured by an antenna), Cable (for regular cable), or Cable-HD (for a high-definition cable signal).

Essentially, the sources defined herein describe all of the channels received on this source and the listings associated with them. If you are using a listings grabber (e.g. Schedules Direct or XMLTV), you can fill its information in here and pull the first block of listings from it. This will also set up the channels.

Otherwise, if you're not using a listings grabber or have other plans, you can just give your input source a name (e.g. Cable-HD). The channels can be set up in several other ways (see below).

Regardless of how you define your video sources, once you've done them once, you're pretty much set for life and can use the same sources over and over again for each video capture card that you define.

Input Connections

The Input Connections section allow you to associate a Video Source with a Capture Card. Essentially, this is where you tell Mythbuntu to look for a particular show on a certain channel on a given card.

For example, if Mythbuntu is going to record a Buffy The Vampire Slayer rerun (or you could just watch whatever episode you like from the video server) and it knows Buffy is on Cable, channel 38, it will look to see which capture cards are connected to the Cable Video Source and then pick one. It will tune the card to channel 38 and its in business.

You can only associate one Video Source with each Capture Card, although some Capture Cards can have multiple tuners and/or can record multiple video streams at one time.

     Display Name: (must supply a name - used to name source when viewing)
     Video source: (Cable, Cable-HD, Antenna, Satellite, etc.)
     Starting channel: (pick one that makes sense)

The second page of this section can be left pretty much at the defaults unless you are setting up a connection that can record multiple sources (see Recording HDTV And Analog TV Using The pcHDTV Cards, below, for example).

If this is your first time through and you haven't set up channels on the Video Source (e.g. you didn't pick a listings source), you can have setup scan the associated capture card to see what's out there. This works for both NTSC and HDTV inputs but the amount of information filled in for NTSC inputs is minimal. You'll probably want to use the Channel Editor (see below) to fill in additional info, disallow bogus channels, etc., once you've done this scan. This option is invoked by clicking "Scan for channels".

Channel Editor

What can I say. This editor lists all of the channels defined for a Video Source, lets you add more, hack the ones that are there and delete those that you don't like. You can also disable channels without deleting them. There are more notes below about how to use it in specific cases. If you are using a bonafide listings source (e.g. Schedules Direct or XMLTV) you probably won't need this feature.

Storage Groups

If you are using one or more separate drives for video recordings storage, you will need to adjust the storage groups to reflect this fact (for later versions of MythTV, you will simply need to add the drives to one or more storage groups, since the pre-defined storage directory is no longer set up).

First, make sure the drives are mounted somewhere (e.g. /mnt/sdb1). If you do not set them up at install time or wish to add them later on, you can hack /etc/fstab to mount them. For example:

.

       .

/dev/sdb1 /mnt/sdb1 xfs defaults 0 2
/dev/sdc1 /mnt/sdc1 xfs defaults 0 2

       .
       .
       .

Or, if you wish to mount the drives by volume identifier, do something along these lines:

.

       .

# /dev/sdb1
UUID=1113935f-a8b6-4f25-a57d-a6e73c69a136 /mnt/sdb1 xfs defaults 0 2 # /dev/sdc1
UUID=adf4297c-75d8-470e-9eda-802986c0d70d /mnt/sdc1 xfs defaults 0 2

       .
       .
       .

After rebooting, For each of the mount points that mount a drive partition you should do the following:

     sudo chown mythtv:mythtv /mnt/sdb1
     sudo chmod g+ws /mnt/sdb1

This will allow MythTV to use the mounted drive partitions as storage space for recordings.

Optionally, if you wish to store several types of media on the new partitions, you should do this instead:

     sudo mkdir /mnt/sdb1/music
     sudo mkdir /mnt/sdb1/recordings
     sudo mkdir /mnt/sdb1/videos
     sudo chown mythtv:mythtv -R /mnt/sdb1
     sudo chmod g+ws -R /mnt/sdb1

On the other hand, if you have a single, integrated drive that holds the OS, the /boot partition, the swap space and all of the recordings, you should define a new subdirectory in the root where MythTV can store recordings. For example:

     sudo mkdir /MythTV
     sudo chown mythtv:mythtv /MythTV
     sudo chmod g+ws /MythTV

Or, once again, if you wish to store several types of media on the new partitions, you should do this instead:

     sudo mkdir /MythTV
     sudo mkdir /MythTV/music
     sudo mkdir /MythTV/recordings
     sudo mkdir /MythTV/videos
     sudo chown mythtv:mythtv -R /MythTV
     sudo chmod g+ws -R /MythTV

Now, you need to run mythtv-setup and add the additional storage to the storage groups so that MythTV can record to them. Probably the smartest way to go about it is to add the new paths to the Default storage group. That way, MythTV will use the new space by default. If you are using an older version of MythTV and want to prevent it from using any of the space on the system partition (or just the inaptly-named directory on the system partition), overwrite the predefined path, /var/lib/mythtv, with the first partition's mount point or the new MythTV subdirectory off the root. If you have more than one additional partition, add another path to the storage group.

Note that MythTV allows you to create new, named storage groups but then, if you do, you'll have to specify which storage group to use when you make a recording. The Default group, on the other hand, is chosen by default so it is probably the best place to attach your recordings storage.

If you want, you can add storage groups directly to the database. We prefer this approach if we're duplicating a current storage group. To figure out what to add, list the existing storage groups:

     mysql -uroot -p mythconverg
       select * from storagegroup;

At the very least, you should see default storage groups for each of your systems:

     +----+-----------+----------+------------+
     | id | groupname | hostname | dirname    |
     +----+-----------+----------+------------+
     |  7 | Default   | mainguy  | /MythTV/   |
     |  8 | Default   | mainguy  | /mnt/sdb1/ |
     |  9 | Default   | mainguy  | /mnt/sdc1/ |
     | 10 | Default   | otherguy | /MythTV/   |
     +----+-----------+----------+------------+
     4 rows in set (0.00 sec)

Using the information from above, you could add a new Default storage group for otherguy:

     mysql -uroot -p mythconverg
       insert into storagegroup values(11,'Default','otherguy','/mnt/sdb1/');

In this case, we're adding a second volume that is mounted on /mnt/sdb1 on otherguy, to give us more space. Your storage groups should now look something like this:

     +----+-----------+----------+------------+
     | id | groupname | hostname | dirname    |
     +----+-----------+----------+------------+
     |  7 | Default   | bigguy   | /MythTV/   |
     |  8 | Default   | bigguy   | /mnt/sdb1/ |
     |  9 | Default   | bigguy   | /mnt/sdc1/ |
     | 10 | Default   | otherguy | /MythTV/   |
     | 11 | Default   | otherguy | /mnt/sdb1/ |
     +----+-----------+----------+------------+
     5 rows in set (0.00 sec)

If you wish to weight the different partitions or directories in a storage group for purposes of giving preference to certain ones over the others (to, for example, include the system disk in a backend's storage group but only use it as a last resort when all of the other space in the storage group is used up), there is limited ability to do this via some undocumented settings, but there is no GUI to set them up.

Myth uses weights to determine which filesystem/directory to record to. The following default values are used:

     SGweightPerRecording  = 10
     SGweightPerPlayback   =  5
     SGweightPerCommFlag   =  5
     SGweightPerTranscode  =  5
     SGweightLocalStarting = -1.99 * SGweightPerRecording
     SGmaxRecOverlapMins   =  3

The physical drive with the lowest weight is used first. In a tie, the physical drive with the highest amount of free disk space is used first.

Each Storage Group directory has its own weight, but Myth is smart enough to know if several directories are on the same shared filesystem. When a weight is applied to a directory that is in use, it is applied to all directories on that filesystem because Myth is trying to spread the load out across filesystems, not directories on the same filesystem.

The starting weight of all physical drives is 0. Local filesystems/directories are then offset by SGweightLocalStarting, so by default they begin at -19 (SGweightPerRecording defaults to 10). This implies that local drives are preferred over remote drives. A local drive has to have an effective weight of 20 before a remote drive will be used to store a new recording. If you do not have any playback going on, this would mean that you'd have to have 2 recordings going to a local drive before a remote drive would get used. If you have 2 local drives and 1 remote drive, you'd have to have 4 recordings going on locally before a remote drive would get used.

If you wish to alter the way Myth decides to use a drive (and, hence, the directory or directories on it), you can do so using the undocumented SGweightPerDir setting. In order to make Myth not use a filesystem/directory, we need to artificially inflate the starting weight for that directory. We can do so by inserting a specific SGweightPerDir setting in the database.

The database key used for the specific SGweightPerDir setting is:

     SGweightPerDir:hostname:directory

The value for hostname is the actual hostname that mounts the directory. So if the directory is actually on server1 but is mounted via NFS on server2 (which is the server running mythbackend), we'd use server2 for hostname. The value for directory is the local path on hostname, so we'd use the mounted directory name (e.g. /mnt/video). For example:

     SGweightPerDir:server2:/mnt/video

The value assigned to this setting will be applied as an offset to the initial weight for this directory. You can play it safe by setting the value to something large like 99 or 100 or even higher. To set a value of 99 for the directory shown in the example above, you would run the following SQL to insert this setting into the settings table:

     insert settings
       (value, data, hostname)
       values("SGweightPerDir:server2:/mnt/video", 99, "server2");

This would pretty much guarantee that the directory would only get used as a directory of last resort, when all other directories filled up.

However, if you'd like to order the way the directories are used up but still have the local directory of last resort be used for recordings before any remote directories, you should pick a number that will result in a calculated weight that is greater than -19 but less than 0. If, for example you chose 15 (assuming that the directory is mounted on a local drive), when the Storage Groups scheduling code runs, /mnt/video will start out with a weight of 0, whereupon it will have an initial offset of -19 added to the 15, specified in the settings table via SGweightPerDir, to arrive at a weight of -4. Other, normal local directories start out at -19 while any remote directories start out at 0. So unless you have a two recordings, or four playbacks, or a recording and two playbacks going on each of your other local drives, the directory or last resort will never be used unless the locals fill up.

Finally, be aware that there is no way to delete a storage group from the GUI, once it is added, nor is they any way to delete a path from any storage group. You can change the name of an existing path but, if you set it to blank, the path will be set to "/" (when the crappy MythTV code adds a "/" to the end of the path). So, it is best to choose your storage groups carefully and add new path names carefully.

However, if you must delete a storage group or path from a storage group, you can connect to the MySQL database and delete it by hand from the storage groups table:

     mysql -uroot -p mythconverg
       select * from storagegroup;

Look through the listed storage groups and pick the one to delete:

     mysql -uroot -p mythconverg
       delete from storagegroup where groupname='MyGroup';

Alternately, you can delete the storage group based on the path to the directory where it is stored:

     mysql -uroot -p mythconverg
       delete from storagegroup where dirname='/my/store/path';

Secret, Hidden Options

Some of the options that affect the way the Mythbuntu frontend does things are not settable from the User Interface. If you'd like to change its behavior and you can't find out where to do so from the UI, there's always the direct-database-hacking approach. All of the configuration settings for each frontend are stored in the database in the "settings" table. This table has a key for the frontend's hostname. You can see all of the settings for a particular host, in alphabetical order, by doing this (on the master backend):

     mysql -uroot -p mythconverg
       select * from settings where hostname='yourhost' order by value asc;

If you want to see all of the settings for a particular setting on all of the frontends (so that you can compare the working ones against the broken ones), you can do this:

     mysql -uroot -p mythconverg
       select * from settings where value='ValueName' order by hostname asc;

Settings can be altered by:

     update settings set data='datavalue' where hostname='yourhost'
       and value='ValueName';

Settings can be deleted by:

     delete from settings where hostname='yourhost' and value='ValueName';

When you're done, exit mysql via the "quit" command.

Some settings of particular interest are:

     DisplayGroupDefaultViewMask   n       A bitmask that defines which groups are
                                           to be included in the "Default" group.
                                           Doesn't seem to be any way to get rid
                                           of it from the UI so, if you don't want
                                           the "Default" group to show up in the
                                           recorded list, delete this value.

Adding HDTV Channels Not Detected By MythTV

MythTV is supposed to be able to automagically create a lineup by scanning all of the HDTV channels that are present on your capture card's input but some people have reported that it doesn't do so well with cable lineups (especially from my favorite cable company, Comcast).

If you really think your cable or broadcast lineup should include HDTV channels that MythTV is not detecting, you should see the Wiki entry at:

     http://www.mythtv.org/wiki/Adding_QAM_Channels_For_HDTV_Tuner_Cards

However, running scan (as described in the Wiki) and dealing with its output is not a whole lot of fun and the MythTV auto detect feature has improved considerably since the old days. This being the case, you should probably give it the old college try first, before resorting to using scan. If you still think channels are missing (especially channels that are supposed to be present but are not), you can use scan to find all of the channels present on the capture card's input (note that atscscan, mentioned in a lot of Web posts, is no longer with us so don't bother looking for it) and add them to those found by MythTV.

To begin looking for the missing HDTV channels, you will need to install the utilities in the DVBApps package (if they aren't already there). On Mythbuntu, you can install the package with:

     sudo apt-get install dvb-utils

Make sure that the MythTV backend is not running before you run any of the programs in the DVBApps suite:

     sudo /etc/init.d/mythtv-backend stop

For later versions of Mythbuntu that use upstart, you should use:

     sudo stop mythtv-backend
     sudo ps x -A | grep mythtv

Check the output of the ps/grep to ensure that the backend has indeed stopped running (the stop command doesn't always work). If it has, you're good to go. Otherwise, you may need to cancel a few PIDs by hand.

The install (in DVBApps, above) puts the programs and files in different directories than noted in the Wiki. Run scan as follows:

     /usr/bin/scan /usr/share/dvb/atsc/\
       us-Cable-Standard-center-frequencies-QAM256 >Cable-MyTown.scte

If this fails because the scan cannot find the frequency table (on earlier versions of Mythbuntu), you can try looking for it in:

     /usr/share/doc/dvb-utils/examples/scan/atsc/\
       us-Cable-Standard-center-frequencies-QAM256

The scan will take a long time (since it must tune to every frequency that is in the list of standard frequencies) and will produce a list of frequencies that looks something like this:

     [0001]:153000000:QAM_256:2048:2049:1
     [0002]:153000000:QAM_256:1985:1986:2
     [0037]:219000000:QAM_256:1984:1985:55
     [0039]:219000000:QAM_256:2048:2049:57
     [0038]:219000000:QAM_256:2112:2113:56
     [000a]:243012500:QAM_256:0:1985:10
     [000c]:243012500:QAM_256:0:2049:12
     [000b]:243012500:QAM_256:0:2113:11
     [0001]:351012500:QAM_256:0:1985:1
     [0002]:351012500:QAM_256:0:2050:2
     [0002]:369012500:QAM_256:0:1985:2
     [0001]:369012500:QAM_256:0:2049:1
     [0003]:369012500:QAM_256:0:2113:3
     [0004]:369012500:QAM_256:0:2177:4
          .
          .
          .

You now are faced with the task of connecting up the stuff returned by scan to the channel numbers that we know and love. If you are a Comcast customer (you have my sympathies) or you are just interested in the HDTV channels (i.e. not the SD channels that your cable company broadcasts as a replacement for the analog channels that used to be), you should take a look at the scte65scan program:

     http://www.mythtv.org/wiki/Comcast_Users_And_scte65scan

This program can use the PSIP tables, sent over the true HDTV channels, as well as the DTA channel maps (VCTs), sent by Comcast for their el-cheapo digital-to-analog set top boxes (called DTAs), to decode the results produced by running the scan, above. Download the latest copy of this program, unzip it and install it (we put it in /usr/local/bin):

     tar -xvzf scte65scan-0.3.tgz
     cd scte65scan-0.3
     make
     sudo cp scte65scan /usr/local/bin
     sudo chmod ugo+x /usr/local/bin/scte65scan

Run it as follows:

     /usr/local/bin/scte65scan -p /usr/share/dvb/atsc/\
       us-Cable-Standard-center-frequencies-QAM256 >Cable-MyTown.scte

Note that, if you see a message that says something like:

     /dev/dvb/adapter0/frontend0: Device or resource busy

It is probably because the Myth backend is running and it has allocated the DVB adapters. You must also end the backend (as you did above, when you ran scan), before you can run this program, which may cramp your style but that's just the way it is.

The results should look something like this:

     VCT_ID 3020 (0x0bcc) at 525000000hz, version 10
       VC CD.PROG M# NAME
     ====================
        2   82.1   4 WGBH2
        3   79.9   4 HSN
        4   82.2   4 CBS4
          .
          .
          .
     VCT_ID 3010 (0x0bc2) at 525000000hz, version 10
       VC CD.PROG M# NAME
     ====================
        2   82.1   4 WGBH2
        3   84.1   4 LOCAL01
        4   82.2   4 CBS4
        5   82.3   4 WCVB5
          .
          .
          .
     PSIP channels
        VC    NAME    FREQUENCY   MODULATION PROG
     ============================================
       2.1   WGBH HD  585000000hz QAM_256      1
       2.101 WGBH UP  585000000hz QAM_256      6
       2.102 WGBH UP  585000000hz QAM_256      7
       4.1   WBZ HD   603000000hz QAM_256      2
       5.1   WCVB HD  597000000hz QAM_256      1
       7.1   WHDH HD  597000000hz QAM_256      2
       7.2   WHDH TH  597000000hz QAM_256      3
          .
          .
          .

If you follow the instructions on the wiki, for determining which VCT is your's, you should be able to figure out what all of the virtual analog channels (that Comcast broadcasts as SD channels) are.

The "-p" option will also scan for all PSIP VCTs broadcast by the true HDTV channels. This will help you map the HDTV channels to their appropriate scan frequencies. When you are all done, you should have an annotated frequency map that shows all of the channels that you can receive. We build something that looks like this:

.

       .
  # Freq 79 ->
  [000a]:555000000:QAM_256:0:1985:10      71, QVC SD (Shopping)
  [0009]:555000000:QAM_256:0:2049:9       3, HSN SD (Shopping)
  [0002]:555000000:QAM_256:0:2113:2
  [0007]:555000000:QAM_256:0:2177:7       42, CNN SD
  [000c]:555000000:QAM_256:0:2241:12      43, CNN Headline News (HLN) SD
  [0001]:555000000:QAM_256:0:2305:1       44, CSPAN1 SD
  [0005]:555000000:QAM_256:0:2369:5       55, Spike TV SD
  [0003]:555000000:QAM_256:0:2433:3       63, Animal Planet SD
  [0006]:555000000:QAM_256:0:2497:6       64, TV Land SD
  [0008]:555000000:QAM_256:0:2625:8       65, Golf SD
  [0004]:555000000:QAM_256:0:2561:4       53, Travel SD

# Freq 82 ->
[0001]:573000000:QAM_256:1984:1985:1 202-1, WGBH 2 SD
[0002]:573000000:QAM_256:2048:2049:2 204-1, WBZ 4 SD
[0003]:573000000:QAM_256:2112:2113:3 205-1, WCVB 5 SD
[0004]:573000000:QAM_256:2176:2177:4 207-1, WHDH 7 SD
[0007]:573000000:QAM_256:2240:2241:7 225-1, WFXT 25 SD
[0008]:573000000:QAM_256:2304:2305:8 27-1, WUNI HD
[0009]:573000000:QAM_256:2368:2369:9 238-1, WSBK 38 SD [000a]:573000000:QAM_256:2432:2433:10 44-1, WGBX HD [000b]:573000000:QAM_256:2496:2497:11 50-1, WZMY HD [000c]:573000000:QAM_256:2560:2561:12 256-1, WLVI 56 SD

  [007e]:573000000:QAM_256:2624:0:126     3001, DTA_CDL

# Freq 83 ->
[0001]:579000000:QAM_256:1984:1985:1 268-1, WBPX 68 SD
[0003]:579000000:QAM_256:2048:2049:3 10-1, WJAR HD
[0005]:579000000:QAM_256:2112:2113:5 62-1, WMFP HD [000a]:579000000:QAM_256:2176:2177:10 66-1, WUTF HD [000b]:579000000:QAM_256:2240:2241:11 48-1, WYDN HD [0006]:579000000:QAM_256:2304:2305:6 236-1, WSBE 36 SD
[0004]:579000000:QAM_256:2368:2369:4
[000c]:579000000:QAM_256:2432:2433:12 46-1, WWDP HD [0008]:579000000:QAM_256:2496:2497:8 60-1, WNEU HD [0002]:579000000:QAM_256:2560:2562:2 47, Weather SD [0007]:579000000:QAM_256:2624:2625:7 83, Inspiration SD (Religious)

       .
       .
       .

Note that, if you have a regular HDTV television set that is capable of scanning and adding the available channels to its internal lineup, you can scan all of the channels being broadcast by your cable provider or over the air and get a good feel for what is "out there". Most television channels display their logo on the screen at all times, now days, so you can just surf through the channels that your TV set finds and see what they are. This may be especially useful for the SD channels that don't use the PSIP VCTs. Doing this can help you decide which DTA VCT is applicable in your area. In most cases, the TV set will simply use the real channel and program number for the displayed channel number, if there is no PSIP VCT (e.g. 84-12). Thus, the displayed channel number can be used to look up the actual frequency, and from thence the actual program within that frequency, directly.

Alternately, we find that scte65scan with the "-p" option is quite useful to just scan all of the available channels directly, skipping the scan step entirely. With a little modification, it can be used to directly scan both cable and over the air channels. The following patch should first be applied to the 0.3 scte65scan source for scte65scan.c:

scte65scan-0.3/scte65scan.c:

     --- scte65scan-0.3.c        2013-04-04 01:11:00.000000000 -0400
     +++ scte65scan-0.3.x.c      2019-08-03 22:39:12.000000000 -0400
     @@ -185,6 +185,7 @@
      outfmt_t outfmt = {OUTPUT_VC_NAME, TXTTABLE_FMT, -1, 1};
      int vctid=-1;
      char psip = 0;
     +char cableonly = 0;
 
     // vc list formed backwards, so reverse order
     static struct vc_record *reverse_vc_list(struct vc_record *vc_rec) {

@@ -287,11 +288,19 @@

       switch (buf[0]) {
         case 0xc9: // CVCT
  +        debugp("Found CVCT\n");
           done = parse_psip_vct(buf, section_len, psip_list, outfmt->freq);
           break;
  -      case 0xc8: // TVCT (we shouldn't be running this on a cable system)
  -        warningp("Huh? Detected Terrestial ATSC VCT on Cable system\n");
  -        return 0;
  +      case 0xc8: // TVCT (apart from 2 reserved bits where the path_select
  +                 // and out_of_band fields are, the TVCT is identical to
  +                 // the CVCT)
  +        if (cableonly) {
  +          warningp("Ignoring ATSC Terrestial VCT on Cable system\n");
  +        } else {
  +          debugp("Found TVCT\n");
  +          done = parse_psip_vct(buf, section_len, psip_list, outfmt->freq);
  +        }
  +        break;
         // ignore the following ATSC PSIP tables:
         case 0xc7: // MGT
         case 0xca: // RRT
  @@ -1216,6 +1225,7 @@
             "    -s N    N second timeouts (default N=5)\n"
             "    -V N    only output VCT_ID=N or -1 for all (default N=-1)\n"
             "    -n N    name: 0=no output, 1=Vchannel#, 2=callsign, 3=both (default N=3)\n"
  +          "    -c      only scan for cable data (i.e. ignore TVCTs)\n"
             "    -k      keep going (scan all freqs for all SCTE-65 tables, not just 1st)\n"
             "    -p      also scan for ATSC PSIP data\n"
             "    -f N    output format. Myth scripts, specify sourceid by adding a comma\n"
  @@ -1313,7 +1323,7 @@
     int opt;
     struct transponder *t_tail;
 
     -  while ((opt = getopt (argc, argv, "A:D:F:H:i:t:s:V:n:f:qpkvh")) != -1)
     +  while ((opt = getopt (argc, argv, "A:D:F:H:i:t:s:V:n:f:qpckvh")) != -1)
          {
            switch (opt)
              {
     @@ -1382,6 +1392,9 @@
              case 'k':
                outfmt.flags |= OUTPUT_FREQ;
                break;
     +        case 'c':
     +          cableonly = 1;
     +          break;
              case 'p':
                psip = 1;
                break;

Once the patch is applied, you can build scte65scan, as shown above, and use it to scan both cable and over the air lineups. To scan for a cable lineup, use:

     /usr/local/bin/scte65scan -p -c /usr/share/dvb/atsc/\
       us-Cable-Standard-center-frequencies-QAM256 >Cable-MyTown.scte

To scan for a terrestrial lineup, use:

     /usr/local/bin/scte65scan -p /usr/share/dvb/atsc/\
       us-ATSC-center-frequencies-8VSB >Terrestrial-MyTown.scte

Using all of this information, you can build a set of updates that can be fed into MythTV. If you are able to use scte65scan, the following command will get you started (use the actual VCT ID in place of "nnnn"):

     /usr/local/bin/scte65scan -p -V nnnn -f 3 /usr/share/dvb/atsc/\
       us-Cable-Standard-center-frequencies-QAM256 >Update-Cable-MyTown.sql

You can feed the SQL file that is produced by scte65scan directly into MythTV but we prefer to manually inspect and adjust them before letting MySQL rip on them. There are too many ways this step can go wrong so checking to make sure that everything is on the up and up is wise.

Verify that the deletes are deleting the correct lines from the dtv_multiplex and channel tables. The deletes are by sourceid but you can use a range of mplexids (for the dtv_multiplex table) or chanids (for the channel table). To see what's there, try:

     select * from dtv_multiplex where sourceid=1 order by mplexid asc;
     select * from channel where sourceid=1 order by chanid asc;

You can replace "1" with 2 or 3 or 4, depending on which input source you are working with.

If you used scte65scan as a starting point, inspect the portion of the channel table insert lines that look like this, very carefully:

     mplexid=(SELECT mplexid from dtv_multiplex where frequency=585000000)

It is possible that the frequency that scte65scan uses in the dtv_multiplex table will be different than the frequency that it detects later on when it does the actual scan and proceeds to build the channel table. This will result in the insert failing to find the proper mplexid and the channel table being borked. We prefer to supply the actual mplexid by hand, like this:

     insert into channel set chanid=1021, channum='2_1', freqid=115, sourceid=1,
       callsign='WGBH-HD', name='WGBH HD', serviceid=1, mplexid=115, ...

And, note that scte65scan fails to set the atsc_major_chan and atsc_minor_chan fields when it updates the channel section. This is a mixed blessing (see the Fixing Formerly Working/Now Broken HDTV Channels section) but, suffice to say, if you want to receive the on-air-guide via the transmitted EIT data, you need to set them manually. You also need to set the useonairguide flag.

Alternately, if you will be loading your own guide data (see Making Up Guide Data) or using one of the XMLTV grabbers to obtain guide data, you will need to set the xmltvid field to the channel identifier that matches the second display-name that the XMLTV data uses for each channel. Typically, this is the channel number or call sign but you may want to inspect the XMLTV data first to determine what to use.

A further note is that your cable company may transmit the same channel in two formats (Verizon and Comcast do this, for example) so you will see the same channel on two multiplexes in the scan. Be sure that you pick the correct HD channel, if that's what you want (why wouldn't you). Sometimes the SD channel will display as a 16x9 picture but without high definition (obviously). Check all of the channels that are duplicates to ensure that they look good (to us, it is pretty obvious when a 16x9 picture is not high definition).

Finally, you can mark those channels that you don't want to see with the visible flag (it is set on, by default). But, bear in mind that the useonairguide flag should still be set for invisible channels, if you plan to use the transmitted EIT data (see Getting EIT To Work) for any of the channels included in the ones broadcast under the chosen mplexid.

Your updates should look something like this:

     -- WARNING: The following line clears out the us-cable frequencies in the
     --          dtv_multiplex table
     delete from dtv_multiplex where sourceid=1;
     -- Add the frequency table from SCTE-65 CDS
     insert into dtv_multiplex set sistandard='atsc', mplexid=1,
       frequency=75250000, modulation='qam_256', sourceid=1;
     insert into dtv_multiplex set sistandard='atsc', mplexid=2,
       frequency=57000000, modulation='qam_256', sourceid=1;
     insert into dtv_multiplex set sistandard='atsc', mplexid=3,
       frequency=63000000, modulation='qam_256', sourceid=1;
          .
          .
          .
     insert into dtv_multiplex set sistandard='atsc', mplexid=118,
       frequency=759000000, modulation='qam_64', sourceid=1;
          .
          .
          .
     -- WARNING: The following line clears out the HD and SD channels in the
     --          channel table
     delete from channel where sourceid=1;
     -- Add the HD channels from the PSIP section
     insert into channel set chanid=1021, channum='2_1', freqid=115, sourceid=1,
       callsign='WGBH-HD', name='WGBH HD (PBS, Boston)', serviceid=1, mplexid=115,
       useonairguide=1, atsc_major_chan=2, atsc_minor_chan=1;
     insert into channel set chanid=1041, channum='4_1', freqid=114, sourceid=1,
       callsign='WBZ-HD', name='WBZ HD (CBS)', serviceid=2, mplexid=114,
       useonairguide=1, atsc_major_chan=4, atsc_minor_chan=1;
     insert into channel set chanid=1051, channum='5_1', freqid=113, sourceid=1,
       callsign='WCVB-HD', name='WCVB HD (ABC)', serviceid=1, mplexid=113,
       useonairguide=1, atsc_major_chan=5, atsc_minor_chan=1;
          .
          .
          .
     insert into channel set chanid=1661, channum='66_1', freqid=83, sourceid=1,
       callsign='WUTF-HD', name='WUTF HD (Telefutura)', serviceid=10, mplexid=83,
       visible=0, useonairguide=1, atsc_major_chan=66, atsc_minor_chan=1;
          .
          .
          .
     -- Add the SD channels from VCT_ID 3020 (0x0bcc) at 525000000hz, version 28
     insert into channel set mplexid=87, serviceid=9, freqid=3, chanid=2003,
       sourceid=1, channum='3_9', callsign='HSN-SD', name='HSN SD (Shopping)',
       visible=0;
     insert into channel set mplexid=89, serviceid=6, freqid=6, chanid=2006,
       sourceid=1, channum='6_9', callsign='NECN-SD', name='NECN SD (News)';
          .
          .
          .
     -- WARNING: The following line clears out the us-bcast frequencies in the
     --          dtv_multiplex table
     delete from dtv_multiplex where sourceid=2;
     -- Add the frequency table for US Broadcast
     insert into dtv_multiplex set mplexid=159, sourceid=2, transportid=\N,
       networkid=\N, frequency=195000000, inversion='0', symbolrate=0,
       fec='auto', polarity='v', modulation='8vsb', bandwidth='a',
       lp_code_rate='auto', transmission_mode='a', guard_interval='auto',
       visible=0, constellation='8vsb', hierarchy='a', hp_code_rate='auto',
       sistandard='atsc', serviceversion=33,
       updatetimestamp='2010-03-15 16:13:59';
     insert into dtv_multiplex set mplexid=160, sourceid=2, transportid=\N,
       networkid=\N, frequency=207000000, inversion='a', symbolrate=0,
       fec='auto', polarity='v', modulation='8vsb', bandwidth='a',
       lp_code_rate='auto', transmission_mode='a', guard_interval='auto',
       visible=0, constellation='8vsb', hierarchy='a', hp_code_rate='auto',
       sistandard='atsc', serviceversion=33,
       updatetimestamp='2010-03-15 16:13:59';
          .
          .
          .
     -- WARNING: The following line clears out the HD Over The Air channels in the
     --          channel table
     delete from channel where sourceid=2;
     -- Add the HD OTA channels broadcast locally
     insert into channel set chanid=9021, channum='902_1', freqid=19, sourceid=2,
       callsign='WGBH-DT', name='WGBH HD (PBS, Boston)', icon='', finetune=\N,
       videofilters='', xmltvid='', recpriority=0, contrast=32768,
       brightness=32768, colour=32768, hue=32768, tvformat='ATSC',
       commfree=0, visible=1, outputfilters='', useonairguide=1,
       mplexid=163, serviceid=3, atscsrcid=\N, tmoffset=0,
       atsc_major_chan=2, atsc_minor_chan=1, last_record='0000-00-00 00:00:00',
       default_authority='', commmethod=-1;
     insert into channel set chanid=9041, channum='904_1', freqid=30, sourceid=2,
       callsign='WBZ-DT', name='WBZ HD (CBS)', icon='', finetune=\N,
       videofilters='', xmltvid='', recpriority=0, contrast=32768,
       brightness=32768, colour=32768, hue=32768, tvformat='ATSC',
       commfree=0, visible=1, outputfilters='', useonairguide=1,
       mplexid=166, serviceid=1, atscsrcid=\N, tmoffset=0,
       atsc_major_chan=4, atsc_minor_chan=1, last_record='0000-00-00 00:00:00',
       default_authority='', commmethod=-1;
          .
          .
          .
     -- WARNING: The following line clears out the analog channels in the
     --          channel table
     delete from channel where sourceid=3;
     -- Add the only real analog channels from the PSIP section
     insert into channel set chanid=3002, channum='2', freqid=2, sourceid=3,
       xmltvid='', callsign='WGBH', name='WGBH-2 (PBS, Boston)';
     insert into channel set chanid=3003, channum='3', freqid=3, sourceid=3,
       xmltvid='', callsign='HSN', name='HSN (Shopping)', visible=0;
          .
          .
          .
     -- Add the analog virtual channels from the PSIP section
     insert into channel set chanid=3023, channum='23', freqid=23, sourceid=3,
       xmltvid='', callsign='DAYSTAR', name='Daystar (Religious)', visible=0;
     insert into channel set chanid=3024, channum='24', freqid=24, sourceid=3,
       xmltvid='', callsign='DISNEY', name='Disney';
          .
          .
          .

Again, to reiterate some of the previously made points and note a few more tips, in the dtv_multiplex section, make sure that the source ID is correct for the source that you've defined for digital reception. Dumping the existing dtv_multiplex table ahead of time (as shown above) and inspecting it can help you with this choice.

Check all of the frequencies, in the dtv_multiplex section, against the actual values in your annotated frequency map or the file output by scan. Be careful that the frequency that you set is correct, since this is the number that will be used to actually tune the encoder. At the same time, pay attention to the modulation setting. Most cable multiplex frequencies will use QAM-256 but occasionally one will use QAM-64 or something else. Over the air broadcasts will be 8VSB.

In the channel section, don't delete existing channel IDs, if possible, just update them with the correct info. This will keep all of the existing recordings and upcoming recordings copacetic. You can change the serviceid and mplexid of existing channels with impunity, since this information is only used to record the next recording. Changing the callsign of any channel should be done carefully (see How MythTV Chooses Which Input To Record), only after considering the repurcussions on the upcoming recordings.

Again, in the channel section, watch out for the wording that says "mplexid=(select mplexid from dtv_multiplex where frequency=nnnnnnnnn)". If the frequency used in the select doesn't match the one in the dtv_multiplex, you will end up with a bogus mplexid and the encoder won't be able to tune to the channel.

For digital channels that have channel numbers like "n_n", always use the same separator as the other defined channels and be sure that it is the one that MythTV is using. Myth actually separates channel numbers using this separator and sorts them into two columns. If you don't stick with the convention, your channels will be sorted in incorrect order.

Be aware that you can have two channels with the same number (especially if one is analog and one is digital) but you probably won't be happy with the consequences. For example, despite the fact that you're viewing TV using a digitial encoder, and you've defined a digital channel 12, entering 12 on your remote, to change to that digital channel, may result in MythTV switching to an analog encoder and showing you analog channel 12 instead. Worse yet, recordings may end up on the wrong encoder (see How MythTV Chooses Which Input To Record).

Consequently, for digital channels that mirror virtual analog channels, it is much better to append a second component to the channel number (or move them to a higher range, such as 2nn), thereby keeping them unique. We like to append "_9" to preserve the sort order with the regular channels. Note that you can use anything you like but, if you don't use numerics and you don't use the proper separator, MythTV will sort your channels in odd order.

Once you've built your channel definitions file, you can feed it in to MySQL with this command:

     source /path/to/file/MyLineup.sql

After you'd done so, always check the upcoming recordings list. Despite the fact that your channel lineup should be fine, after you update it, MythTV can get confused and show upcoming recordings as "not listed". Usually, you can fix this problem by modifying the recording (you don't actually have to modify anything) and re-saving it. However, you may have to delete and re-add any truly broken ones.

Fixing Formerly Working/Now Broken HDTV Channels

This section could be subtitled, "Keeping Up With Those Butt-Heads at Comcast".

HDTV channels can have a whole bunch of sub-channels (called programs), all under the one multiplex frequency. This allows the broadcaster or, in the case of your favorite bunch of clowns at the cable company, the marketing guys, to assign content to whatever sub-channel they like. If they're being nice, they'll keep the lineup the same and everything will work fine. If they're being butt-heads, they'll periodically move things around and stuff will break.

Luckily, the MythTV guys thought of all this. Ha, ha, ha, haaaa! Fooled you. You actually believed that? What a schmuck. Here's what really happens.

The idiots at the broadcaster/cable company change something in the channel lineup (e.g. the ATSC major channel and minor channel numbers change for one of the channels that you normally record in slot 1 of channel 84 -- channel 2_2 moves to 2_1, as it recently did on Comcast). MythTV keeps recording shows on the channel with nary a wimper. However! The recording file that the database points to never actually gets created and there's no actual recording. Nice, huh? If you look in /var/log/mythtv/mythbackend.log for the date/time of the recording, you'll see thousands of entries saying:

     Could not find channel 2_2 in CVCT

What this really means is that MythTV went and looked up the channel information in the dtv_multiplex table and tuned to the channel/sub-channel specified. Since it got a lock, it was all set to start recording. Then, just as a precaution, MythTV decided to check that the ATSC major/minor channel numbers, as specified in the Cable Virtual Channel Table [ATSC Syntax] (CVCT) (see www.etherguidesystems.com/Help/SDOs/ATSC/Syntax/TableSections/CVCT.aspx) matched what was set in the channel table. They didn't so it simply dumped the recording in the bit-bucket, with no warning to the user.

The clue as to how to fix this problem is found right in the log at the same place as the first error message. You will see a listing of the channels that are described in the CVCT immediately following. They look like:

     VCT Cable: channels(4) tsid(0x807c) seclength(259)
     Channel #0 name(WLVI HD) 56-1 mod(SCTE mode 2) cTSID(0x807c)
      pnum(2) ETM_loc(0) access_ctrl(0) hidden(0)
     path_select(0) out_of_band(0) hide_guide(0) service_type(2) source_id(1)
      descriptors length(27) count(1)
       ExtendedChannelNameDescriptor: 'WLVI HD (PRIMARY)'
     Channel #1 name(WGBH HD) 2-1 mod(SCTE mode 2) cTSID(0x807c)
      pnum(1) ETM_loc(0) access_ctrl(0) hidden(0)
     path_select(0) out_of_band(0) hide_guide(0) service_type(2) source_id(6)
      descriptors length(27) count(1)
       ExtendedChannelNameDescriptor: 'WGBH HD (PRIMARY)'
     Channel #2 name(WGBH UP) 2-101 mod(SCTE mode 2) cTSID(0x807c)
      pnum(6) ETM_loc(0) access_ctrl(0) hidden(0)
     path_select(0) out_of_band(0) hide_guide(0) service_type(4) source_id(7)
      descriptors length(32) count(1)
       ExtendedChannelNameDescriptor: 'WGBH UPDATE0 (PRIMARY)'
     Channel #3 name(WGBH UP) 2-102 mod(SCTE mode 2) cTSID(0x807c)
      pnum(7) ETM_loc(0) access_ctrl(0) hidden(0)
     path_select(0) out_of_band(0) hide_guide(0) service_type(4) source_id(8)
      descriptors length(32) count(1)
       ExtendedChannelNameDescriptor: 'WGBH UPDATE1 (PRIMARY)'

In this case, what was channel 2_2 has been updated to 2_1, as can be seen from "name(WGBH HD) 2-1". The entry for channel 2_2 in the channel table must be updated to match the ATSC major number (2, in this case) and ATSC minor number (1, in this case). You can do this with the following SQL command:

     update channel set atsc_major_chan=2, atsc_minor_chan=1 where chanid=1022;

Another fix that appears to work is to set both the ATSC major and ATSC minor numbers to zero, thereby telling MythTV not to check the channel when it tunes to it. This can be done with:

     update channel set atsc_major_chan=0, atsc_minor_chan=0 where chanid=1022;

Its your call, whether you want MythTV to record nothing at all or whether you just want it to record the wrong content (or maybe its the right content, just the wrong name). But, to throw another variable into the mix, if you set the ATSC major and ATSC minor numbers to zero, you won't be able to use the on air guide that is sent in the EIT (see Getting EIT To Work). So, probably the best bet is to set ATSC major and ATSC minor numbers to the proper values and keep your eye out for recordings that disappear in the night.

You will, of course, need to figure out what the correct chanid is in order to do this update. This SQL query should help:

     select * from channel where freqid=84;

Replace 84 with the frequency ID you are trying to fix and then inspect the resultant listing to find the broken channel. The chanid column is the unique key that you can use for the update. Incidentally, this assumes that whoever or whatever built the channel table put the correct frequency number into each entry. If this isn't the case, you may have to work backwards from first principals. First, begin by selecting the correct dtv_multiplex entry:

     select * from dtv_multiplex where sourceid=1 and frequency=585000000;

Replace "1" with the actual sourceid for the input source in question and "585000000" with the center frequency of the channel that is broken. Using the resultant mplexid, select the channel information:

     select * from channel where mplexid=184;

Note that other possibilities for "broken" include the wrong slot number being chosen in the channel as well as the wrong frequency being used to tune the channel (this is Scenario 2 in the Comcast playbook, where they change the entire lineup, unannounced, the premise being that everybody is watching via a settop box anyway so it makes no nevermind where we move things and when).

Using /usr/bin/scan, as described in the "Adding HDTV Channels Not Detected By MythTV" section, will give you a listing of all the frequencies that can be tuned on your input connections. The mplexid field of the channel entry should point to the proper frequency in the dtv_multiplex table. If it doesn't change it to match the mplexid from that table that has the correct frequency:

     update channel set mplexid=7 where chanid=1022;

Update the serviceid field to choose the correct slot, as given by the path number value (e.g. "pnum(1)") in the /var/log/mythtv/mythbackend.log file:

     update channel set serviceid=1 where chanid=1022;

Once you have the channel recording properly again, you may want to change its actual name (e.g. "2_2" changes to "2_1"). You can do this from the channel editor in the MythTV Backend setup program, which is accessed from the System portion of the Gnome Main Menu or you can use this SQL command:

     update channel set channum='2_1' where chanid=1022;

One word of caution. Do NOT, I repeat, DO NOT leave any encoder on any system connected to the master backend, whose database you're updating, tuned to the old channel name. If you do, when you change the channel name, everything will hang, including recordings, watching live TV and the master backend itself. The only way out of this fiasco is to go to the machine that actually has the encoder installed in it, run the MythTV Backend setup program, choose Input setup, pick the encoder in question and set its default channel to something else, although, sometimes, you can put the channel number back the way it was, then cycle thru all of the encoders and set them to something else, then re-set the channel number to what you wanted it to be. But, its much easier to not get in this bind in the first place, by setting each encoder to a legit channel before you make the changes.

Fixing Live TV Tuning Problems

Live TV can become locked up if you select a bad channel or one that offends MythTV in some way. Typically, this kind of problem manifests itself in a channel selection that seems to be OK (i.e. it gets a LAM Lock) but doesn't display properly (either no picture or a broken picture). Sometimes the display just locks or freezes. Sometimes you get a message that you should have gotten a LAM lock but the display stays blank. A further symptom may be that the frontend will bail out of the Live TV display after 30 seconds or so, with some incoherent message about no buffer or not being able to record the program (e.g. "Video frame buffering failed too many times"). This problem can also occur on a valid channel that has the "Copy Never" flag set (either for a particular piece of content or always) when a cable card is being used.

In their infinite wisdom, the MythTV guys decided that, in this situation, none of the other keys (that you might use to get out of this mess) should work. This means that the menu key won't work to allow you to pop up the source switching dialog. Nor do any of the arrow keys work so you can't change the channel to something that works. You're just stuck.

If you get lucky and the frontend does give up after 30 seconds, you can continue with the steps below, to fix the problem. Otherwise, if you can telnet or SSH to the system, you can kill the frontend like this:

     su
     ps x -A | grep myth
     (make a note of the PID for mythfrontend or mythfrontend.real)
     kill -9 [mythfrontend.real-PID]    (for later versions of Myth)
     kill -9 [mythfrontend-PID]    (for earlier versions of Myth)

Once the frontend gets back to the main menu, you will still be stuck. Because, in another stroke of genius, the MythTV guys decided to remember which channel Live TV was watching when you exited. In this case, it remembers the broken channel. Nice going! When you start up Live TV again, it goes right back to the broken channel and hangs again. Brilliant!

The solution is to change the default channel ID in the database. In order to do this, you must first exit the frontend completely on the machine which cannot watch Live TV (the current Live TV channel ID is stored on a machine by machine basis). The frontend saves the current value when you exit it so, if you change it while the frontend is still running, the value will simply be reset when you exit the frontend. And, you must exit the frontend to cause it to reread the changed value.

After you exit the frontend, select the default channel ID from the settings table for the machine in question. For example:

     select * from settings where hostname='yourhost' and value='DefaultChanid';

If you see the default channel ID that you wish to change, you can go ahead and change it like this:

     update settings set data='3071'
       where hostname='yourhost' and value='DefaultChanid';

Note that the value used for the channel ID must be a channel ID number, not the channel's virtual channel number or call sign or anything else. The channel ID number can be found under the "chanid" column in the channel table. If you don't know what to use, you can search by call sign like this:

     select callsign, chanid, channum from channel where callsign='WGBH';

This will give you a channel ID to update in the settings table (above). Once you've made the replacement in the "settings" table, you can restart the frontend and you should be able to go back to Live TV without any problems.

How MythTV Chooses Which Input To Record

The subtitle of this section could be "Setting Up A Backup Input Source". If you are like us, happy customers of Comcast, you might want to set up a backup input source to record from, when your service provider arbitrarily porks your lineup or otherwise drops the signal on the ground, during the middle of your favorite program.

For example, a spare encoder hooked up to that Radio Shack flying saucer up in the atic can provide an alternate source of program material. Since all terrestrial broadcasts (in the US, at least) are HDTV, there's no compromise in picture quality, providing the signal is acceptable. No reason not to record from such a source, especially as a back-em-up.

Making backup recordings requires that you understand how MythTV schedules recordings. Essentially, the scheduler is interested in recording a call sign, not a channel from a particular source. Normally, this works in your favor, since the scheduler will decide which input source to record from, based on what call signs it has available. If you ask for a recording of Ken Burn's latest magnum opus and there are three encoders that provide WGBH, the scheduler will pick whichever one it finds free at the time. It makes no difference that one is a HD encoder tuned to channel 2_1, the second is an analog encoder tuned to channel 2 via a settop box and the third is another HD encoder tuned to the SD rebroadcast of the HD channel used by your service provider to feed their el-cheapo settop boxes.

However, if you'd actually like to tell the scheduler which input to use, you need to think differently. Let's say that you'd like to make one recording of a program using channel 6 (which is an analog channel that is fed from a settop box that converts a SD channel) and another recording of the same program using channel 6_9 (which is the actual SD channel). Why would you want to do this, you ask? Well, the recording of the program using channel 6 is probably guaranteed to work, even if your friends at the cable company change the lineup on the fly, since the settop box will be reprogramed by them, at the same time, thereby handling the lineup change automatically. However, the SD broadcast is probably a better candidate for recording, since its quality will be better and the resultant file may be smaller (the compression used by the broadcaster is usually more efficient than the compression that the encoder card's MPEG encoder makes up, on the fly). You'd like to make two recordings so that you can view the best one but be assured that you'll at least have something to watch.

Alternately, if your plan is to back up your cable feed with recordings from a terrestrial antenna, you'll once again need to convince the scheduler to make one recording from Encoder A and a second recording from Encoder B. Normally, it is not inclinded to make two recordings of the same program from two different sources.

The clue to making the scheduler do what you want is to convince it that it is dealing with different call signs. If every channel on every input has a unique call sign, you can do this. So, for example, you might define the following lineup:

     WGBH      2       Analog channel on settop box
     WGBH-HD   2_1     HDTV channel in the clear from cable feed
     WGBH-SD   2_9     SD rebroadcast of HDTV channel for el-cheapo settop boxes
     WGBH-DT   902_1   HDTV channel from terrestrial antenna

Note that, not only are all the channel numbers unique (note that you can use any channel numbers you like but, if you don't use numerics and you don't use the proper separator, MythTV will sort your channels in odd order) but the call signs are unique too.

This means that you can now ask the scheduler to schedule one recording of Program X from WGBH-HD and a second, backup from WGBH-DT. The first recording will be made using an encoder that is attached to the cable feed and the second will be made using an encoder that is attached to the terrestrial antenna.

The flip side is that you can force the scheduler to choose from any of the available inputs, regardless of what kind they are, by giving the channels on their sources the same, identical call signs. You may elect to go this route if you're using legacy equipment and haven't upgraded all of your encoders to the top of the line (i.e. HDTV), etc. But, be advised that the scheduler may pick what you'd consider to be the wrong input, all things being equal, so you may want to weight the encoders with different priorities so that it uses them in your preferred order.

Also, be warned that, should you give identical call signs to the channels on a given input as those used on another input, and then later change your mind and assign different call signs, your upcoming recordings list may well be royally screwed. Because the scheduler will have assigned the work to do based on the call sign (which is now different), you may have to delete an reschedule recordings to get them assigned to the correct call sign/channel/input. It is best to ponder everything carefully ahead of time and do it right the first time.

Getting EIT To Work

There is quite a bit of mythology in the various wikis and blogs about what it takes to get over-the-air guide data working, using the EIT information. Most of them state that the only way is to allow MythTV to scan for channels on the input source and let it build the dtv_multiplex and channel tables. For example:

     http://ubuntuforums.org/showthread.php?t=1410407

We can categorically state that this isn't true. We've built channel lineups entirely from scratch, including setting up the dtv_multiplex table and the channel table with information made up from a scan by a television set. Follow these notes and you can do it too.

In North America, the most important information, from the EIT scan point of view, is the ATSC major and minor channel numbers. The atsc_major_chan and atsc_minor_chan fields must be set in the channel table or EIT scan will not work. This is because the data in the EIT must be matched back up to the channel it belongs to, so that it can be incorporated into the guide data, and this is where these two fields come in. That's swell because the tables we've seen generated by scte65scan don't have those fields set. And, apparently, importing a channels.conf file from scan fails to set these fields. So, EIT no workee.

Meanwhile, in Europe, the above statement about needing some way to convert the information in the EIT into a channel ID that MythTV can use to store the data is still relevant. Only, for Europe, the channel ID is looked up using serviceid, networkid and transportid. So, if those fields are not set in your database you're going nowhere fast.

Another thing to consider is that EIT scan only scans the first sub-channel (called a program or service) that is mapped to the multiplex frequency. For true over-the-air channels, this isn't usually a problem, since each multiplex frequency contains only the programs from a single broadcaster and the lowest sub-channel is almost always a real channel that you're interested in. But, for HDTV channels, transmitted by your favorite cable provider, you may find more than one real channel under a single multiplex frequency. For example, in our neck of the woods, Comcast is currently broadcasting the following on one multiplex frequency:

     WCVB HD   5_1     serviceid=1
     WHDH HD   7_1     serviceid=2
     This TV   7_2     serviceid=3

This means that, if we want to see EIT data from channel 7_1, we have to turn it on for channel 5_1 (hey, that's intuitive). Even more intuitive is the fact that EIT may need to be turned on for all of the sub-channels in the multiplex frequency for it to be used by any of them. But, knowing this, we can now construct a set of channel entries for our example:

     insert into channel set chanid=1051, channum='5_1', freqid=113, sourceid=1,
       callsign='WCVB-HD', name='WCVB HD (ABC)', serviceid=1, mplexid=113,
       useonairguide=1, atsc_major_chan=5, atsc_minor_chan=1;
     insert into channel set chanid=1071, channum='7_1', freqid=113, sourceid=1,
       callsign='WHDH-HD', name='WHDH HD (NBC, Boston)', serviceid=2, mplexid=113,
       useonairguide=1, atsc_major_chan=7, atsc_minor_chan=1;
     insert into channel set chanid=1072, channum='7_2', freqid=113, sourceid=1,
       callsign='This', name='WHDH This TV', serviceid=3, mplexid=113,
       useonairguide=1, atsc_major_chan=7, atsc_minor_chan=2;

Pay attention to the fact that the atsc_major_chan and atsc_minor_chan fields (or, in Europe, that the, serviceid, networkid and transportid fields), along with the useonairguide field are set. Even if the visible field is set to zero, the useonairguide field should be set on.

There is nothing unusual that needs to be done for the dtv_multiplex table except that the multiplex ID must be set in the mplexid field. Mind you, without this field being set, you won't be looking at any picture or hearing any sound so this is a no-brainer.

The next thing to do is make sure that active EIT scan is turned on for each of the DVB cards that you want to use for active EIT scanning (you could just allow passive scanning but this means that you actually have to view each of the channels before its guide data will show up). You'll want to have at least one card that is mapped to each input source but you can have more since the scan knows how to effectively use multiple cards. You can do this from the Capture Card section of the Myth Backend configuration application or you could try something like this:

     update capturecard set dvb_eitscan=1 where cardtype='DVB';

Finally, you need to turn on EIT scanning for the input source in question. You can do this from the Input Sources section of the Myth Backend configuration application, at the same time you turn on active EIT scan, or you could try something like this:

     update videosource set xmltvgrabber='eitonly', useeit=1 where sourceid=1;

You may need to recycle the backend on each of the machines that actually have the capture cards that will do the EIT scanning installed, although launching the Myth Backend configuration application takes care of this for you.

Note that, if over-the-air guide data via EIT still doesn't work, once you've done all this, you should enter the following SQL command:

     select channum, min(chanid), mplexid
       from channel, cardinput, capturecard, videosource
       where cardinput.sourceid=channel.sourceid
         and videosource.sourceid=channel.sourceid
         and capturecard.cardid=cardinput.cardid
         and channel.mplexid is not null and useonairguide=1 and useeit=1
         and channum!='' and cardinput.cardid=1
       group by mplexid
       order by cardinput.sourceid, mplexid, atsc_major_chan, atsc_minor_chan;

Change the cardid value from "1" to the actual card number of the capture card that's to do the EIT scanning. You should see a table that looks something like this:

     +---------+-------------+---------+
     | channum | min(chanid) | mplexid |
     +---------+-------------+---------+
     | 27_1    |        1271 |      82 |
     | 10_1    |        1101 |      83 |
     | 68_1    |        1361 |      99 |
     | 7_2     |        1051 |     113 |
     | 25_1    |        1041 |     114 |
     | 2_1     |        1021 |     115 |
     | 38_1    |        1381 |     116 |
     +---------+-------------+---------+

If you don't you've messed something up. Keep checking things until such a listing appears. Then, check the channel table entries for each of the channel IDs shown. They, at least, must have their ATSC major and minor numbers set (or, in Europe, their service ID, network ID and transport ID values set). But, it wouldn't hurt to set the ATSC major and minor numbers for all of the channels that have the same multiplex ID as those listed.

If you're still having problems and you can figure out what channels you want ATSC EIT data for, the returned EIT data must match this select:

     select chanid, useonairguide from channel
       where atsc_major_chan=xx and atsc_minor_chan=yy
         and sourceid=1;

Where xx and yy are the ATSC major and minor numbers and 1 is the source number (typically 1). If the select doesn't find anything, your EIT data won't get stored.

Alternately, if you're in Europe and you're still having trouble with DVB-T, for instance, the returned EIT data must match this select:

     select chanid, useonairguide from channel, dtv_multiplex
       where serviceid=xx and networkid=yy and transportid=zz
         and channel.mplexid=dtv_multiplex.mplexid;

Where xx, yy and zz are the service ID, network ID and transport ID. Again, if the select doesn't find anything, no EIT data for you.

Also note that the scan optionally adds this to the where clause, if the sourceid is set:

     and channel.sourceid=1

Where 1 is the source number (typically 1).

Either way, Europe or North America, there doesn't seem to be much magic involved. You can take a look at the applicable code in eitscanner.cpp and eithelper.cpp (both in libs/libmythtv) if you still can't get it to work but it looks fairly straightforward. There is some special case stuff, supposedly for special EIT data from the German provider Premiere for the optional channels Premiere Sport and Premiere Direkt, but other than that, it looks like: read the EIT data; resolve the channel number; parse the data; stuff the data in the database.

One final note. Your friends at your favorite cable company may strip the over-the-air guide data from your local HDTV channels. This is definitely the case with Comcast in our area, for example. Whereas the EIT data from a terrestrial broadcast of WCVB includes program names, episode titles and extensive episode descriptions for the next 18-20 hours, the EIT data from WCVB on Comcast cable only includes the program names, and only for the next 8-10 hours. Not that it matters from the scheduler's point of view, mind you, since guide data changes due to EIT scanning are reflected immediately but you will be missing the extended program information such as episode titles and descriptions.

Making Up Guide Data

Guide data is loaded into the MythTV database by a program called mythfilldatabase. This program expects that the guide data will be in a format specified by the XMLTV standard, a description of which is found here:

     http://xmltv.cvs.sourceforge.net/checkout/xmltv/xmltv/xmltv.dtd

Additional descriptive information can be found in the XMLTV wiki here:

     http://wiki.xmltv.org/index.php/XMLTVFormat

The program that obtains guide data (from whichever source is appropriate) is called a grabber in XMLTV parlance. For many countries, a grabber has already been written and is included in the XMLTV package. Check the MythTV wiki for a list of what's available:

     http://www.mythtv.org/wiki/XMLTV

If there is no grabber available for your country or your goal is simply to create your own guide data (for whatever reasons), from some source of your own, you'll need to generate XMLTV files containing the data, probably on a daily basis. You can use a support module from the Perl XMLTV package, if you're inclined to write your code in Perl, to generate guide data files in the correct format, which can be fed into mythfilldatabase.

Begin by downloading the latest version of the complete XMLTV package from sourceforge:

     http://sourceforge.net/projects/xmltv/files/

Unzip the distribution file:

     tar -xvjf xmltv-0.5.56.tar.bz2

Now, generate the package's makefile, like so:

     cd xmltv-0.5.56
     perl Makefile.PL

This will ask you a lot of questions about which optional components and grabbers you want. Answer no to all of them. All we really want is the XMLTV.pm module itself, so that we can use it to write XMLTV files.

If need be, install any missing prerequisites (but not any of the optional modules). For example, install Slurp and the XML writer like this:

     perl -MCPAN -e shell
     install File::Slurp
     install XML::Writer

Once you've installed any missing prerequisites, you can build XMLTV:

     make

Then, find the XMLTV.pm module in the lib directory and copy it somewhere that Perl programs can find it. For example:

     su
     cp lib/XMLTV.pm /usr/lib/perl5/site_perl/5.8.8

When you build your guide data, make sure to generate channel data that looks like this:

     <channel id="nn">
       <display-name>CALLSIGN</display-name>
       <display-name>nn</display-name>
     </channel>

The "CALLSIGN" value is whatever call sign is used for that channel (e.g. "WGBH"). This is typically not the name used to display the channel by MythTV but, rather, the official call letters for an over-the-air broadcaster or short name for a cable broadcaster. The important thing is that "nn", the actual channel number that is used by MythTV in the channel's xmltvid field of the channel table (see below), is the second display name. It is imperative that every channel that is described in the XMLTV data has a second display name that matches the xmltvid field of some channel in the channel table or mythfilldatabase will make a channel up, which could have quite unpleasant results.

This Perl code should work to generate the correct XML:

     @ChanList = ();
     push(@ChanList, [$CallSign]);
     push @ChanList, [$Channel];
     $XMLTVHand->write_channel({
       id => $Channel,
       "display-name" => \@ChanList });

Program detail slots are generated for each channel. Each slot gives the start and stop time for the program, as well as the channel it is broadcast on:

     <programme start="yyyymmddhhmmss" stop="yyyymmddhhmmss" channel="nn">
       <title lang="en">The National Parks: America's Best Idea</title>
       <sub-title lang="en">The Scripture of Nature (1851-1890)</sub-title>
       <episode-num system="xmltv_ns">.1.</episode-num>
     </programme>

When you generate your program data, forget about the timezone offset on the start and stop stamps and the story about GMT in the XMLTV DTD. Its local time all the way, no matter what you do. Also, be aware that "nn" must match the previously-written channel entry. Here is some sample Perl that should do the trick:

     %Program = ();
     $Program{channel} = $Channel;
     ($Sec, $Min, $Hour, $MDay, $Mon, $Year) = localtime($StartTime);
     $Program{start} = sprintf("%04d%02d%02d%02d%02d%02d",
       1900+$Year, 1+$Mon, $MDay, $Hour, $Min, $Sec);
     ($Sec, $Min, $Hour, $MDay, $Mon, $Year) = localtime($SlotStamp+1);
       $Program{stop} = sprintf("%04d%02d%02d%02d%02d%02d",
     1900+$Year, 1+$Mon, $MDay, $Hour, $Min, $Sec);
     $Program{"episode-num"} = [[sprintf(".%d.", $EpisodeNum), "xmltv_ns"]];
     $Program->{title} = [["en", "The National Parks: America's Best Idea"]];
     $Program->{"sub-title"} = [["en", "The Scripture of Nature (1851-1890)"]];

You'll probably want to set episode numbers with code like this:

     $Program{"episode-num"} = [[sprintf(".%d.", $EpiNum), "xmltv_ns"]];

You can read the story about the episode numbering scheme employed by XMLTV in the DTD but, essentially, you just want to set the middle component of the episode number to the actual, sequential episode number, which you do by generating a number like ".11.".

If you have them available, run times for programs or movies need to be converted into seconds. Normally, run times are the actual time of the program, without commercials (e.g. for a movie, it would be the running time in the movie theatre or on the DVD). You can add them with code like this:

     $Program{length} = $RunTime * 60;

The genre groups that MythTV uses are the common ones such as "news", "sports", "comedy" and "drama". If you had, for example, a set of simple genre tags you might use some code like this, inside of a loop, to convert them to genres that MythTV can use, in the XMLTV file:

     @GenreGroups = ();
     foreach $ProgType (@ProgTypes)
         {
         if ($ProgType eq "com") { push(@GenreGroups, ["comedy", "en"]); }
         elsif ($ProgType eq "dra") { push(@GenreGroups, ["drama", "en"]); }
         elsif ($ProgType eq "kid") { push(@GenreGroups, ["children", "en"]); }
         elsif ($ProgType eq "mov") { push(@GenreGroups, ["movie", "en"]); }
         elsif ($ProgType eq "new") { push(@GenreGroups, ["news", "en"]); }
         elsif ($ProgType eq "sci")
             { push(@GenreGroups, ["science fiction", "en"]); }
         elsif ($ProgType eq "sop") { push(@GenreGroups, ["daytime", "en"]); }
         elsif ($ProgType eq "spo") { push(@GenreGroups, ["sports", "en"]); }
         }
     if (scalar(@GenreGroups) > 0) { $Program{category} = [@GenreGroups]; }

For data that repeats, such as crew members, you can push the items onto an array and then generate the XMLTV data from the arrays like this:

     @Actors = split(/,\s/, $ActorNames);
     @Directors = split(/,\s/, $DirectorNames);
     @Producers = split(/,\s/, $ProducerNames);
     @Writers = split(/,\s/, $WriterNames);
     if (scalar(@Actors) > 0) { $Program{credits}{actor} = \@Actors; }
     if (scalar(@Directors) > 0)
         { $Program{credits}{director} = \@Directors; }
     if (scalar(@Producers) > 0)
         { $Program{credits}{producer} = \@Producers; }
     if (scalar(@Writers) > 0) { $Program{credits}{writer} = \@Writers; }

For any data that has no special requirements, you can use a table that looks something like this to indicate how it is processed:

     my %ProgramTags = (                     # Tags for program data
         "DE", "desc|en",                    # Description
         "DT", "date",                       # Release date (year)
         "ET", "sub-title|en",               # Episode title
         "MP", "rating|MPAA",                # MPAA rating
         "TI", "title|en",                   # Program title
         "ZZ", "Junk");                      # Placeholder
     if (exists($ProgramTags{$FieldKey}))
         {
         if ($ProgramTags{$FieldKey} =~ /\|/)
             {
             @XtraTags = split(/\|/, $ProgramTags{$FieldKey});
             $FieldTag = shift(@XtraTags); unshift(@XtraTags, $InfoItem);
             $Program{$FieldTag} = [[@XtraTags]];
             }
         else { $Program{$ProgramTags{$FieldKey}} = $InfoItem; }
         }

When all is said and done, the program data should be written to the XMLTV file:

     $XMLTVHand->write_programme(\%Program);

Before you attempt to load any guide data into MythTV, be sure that you set the xmltvid field of each channel in the channel table to the same value as was set for the second display-name in your generated data. You can update the field like this:

     update channel set xmltvid='nn' where chanid=mmmm;

Or, you can go back and reload your channel table with the original data that you used to populate it, setting the xmltvid in that data, like so:

     -- Add the only real analog channels from the PSIP section
     insert into channel set chanid=3002, channum='2', freqid=2, sourceid=3,
       xmltvid='2', callsign='WGBH', name='WGBH-2 (PBS, Boston)';
     insert into channel set chanid=3003, channum='3', freqid=3, sourceid=3,
       xmltvid='3', callsign='HSN', name='HSN (Shopping)', visible=0;
          .
          .
          .
     -- Add the analog virtual channels from the PSIP section
     insert into channel set chanid=3023, channum='23', freqid=23, sourceid=3,
       xmltvid='23', callsign='DAYSTAR', name='Daystar (Religious)', visible=0;
     insert into channel set chanid=3024, channum='24', freqid=24, sourceid=3,
       xmltvid='24', callsign='DISNEY', name='Disney';
          .
          .
          .

Once you've generated your XMLTV guide data files and made them available to the MythTV master backend, you can load the generated data with:

     mythfilldatabase --file n /path/to/my/guidedata.xml

Where "n" is the source number (e.g. cable, antenna) that is to be updated.

We suggest that you try this on your test system first, in case you muck it up (its easy to do). To begin with, you can trim your generated data to only include one channel and a day's worth of listings. Once you get the listings to show up as the right channel, at the right times, you can switch to your production system.

A good way to check the listings is with MythWeb. The TV/Program Listing page will show you pretty quickly whether the data is good or not. If you do muck it up and want to retry, these deletes will clear the database:

     delete from channel where chanid=bogus;
     delete from program where chanid=bogus;
     delete from programrating where chanid=bogus;

or, for a range of guide data:

     delete from channel where chanid>=bogus-low and chanid<=bogus-hi;
     delete from program where chanid>=bogus-low and chanid<=bogus-hi;
     delete from programrating where chanid>=bogus-low and chanid<=bogus-hi;

Note that the oldprogram table may hold borked program descriptions but its probably best not to delete things from it, since it is used by recorded programs, etc. Besides, who cares if SpongeBob mistakenly investigates a murder in a hotel in New York, anyway?

After you've got your code working and you are successfully generating XMLTV guidedata files, you'll need to load them into MythTV. We use a script that is run by cron at regular intervals. Here it is:

guidedata-update:

     #!/bin/sh
     #
     # Script to update MythTV guide data using XMLTV files that were built
     # elsewhere, on a remote server.
     #
     # This script will mirror the remote server's XMLTV directory for the chosen
     # zipcode, using lftp, and then load any files, using mythfilldatabase, that
     # are newer than the time of the last load.  Note that the mirror directory
     # on the local host and the remote server's XMLTV directory must have the
     # same path name.
     #
     #
     # Should be run at regular intervals from cron, any time after the XMLTV
     # files are built on the remote server.  Use the following:
     #
     #      guidedata-update zipcode source
     #
     # zipcode -   The zipcode or Canadian postal code to update data for.
     #
     # source -    The source number (from the mythconverg database) whose guide
     #             data is to be updated.  More than one source can be updated at
     #             once by specifying a comma-separated list.  The default, if
     #             omitted, is 1.
     #
     #
     # Where things are found.
     #
     RemoteHost=192.168.1.1
     RemoteUser=guidedata
     RemotePass=asecretpass
     XMLTVDir=/var/guidedata/XMLTVData
     Owner=root
     Group=mythtvuser
     #
     # Stupidity checking and parameter processing.
     #
     if test x"$1" = x; then
         echo "Zipcode omitted, defaulting to 12345"
         ZipCode="12345"
     else
         ZipCode=$1
     fi
     XMLTVPath="${XMLTVDir}/${ZipCode}"
     if test x"$2" = x; then
         echo "Source omitted, defaulting to 1"
         Source="1"
     else
         Source=$2
     fi
     Source=${Source},
     #
     # Mirror the remote server's XMLTV directory here.
     #
     # Note that we must include the path to echo in the mirror command, otherwise
     # it fails under cron.
     #
     /bin/echo -e "mirror -e ${XMLTVPath}/ ${XMLTVPath}" \
         | /usr/bin/lftp -u ${RemoteUser},${RemotePass} ${RemoteHost}
     chown ${Owner}:${Group} ${XMLTVPath}/
     chmod ug=rw,o=r ${XMLTVPath}/
     #
     # For each source that we were asked to update, troll through the mirrored
     # directory looking for any guide data files that are newer than the time of
     # the last update.
     #
     while echo $Source | grep \, 2>&1 >/dev/null; do
         #
         # Grab the next source out of the list.  Then, remove it from the list.
         
         ProgSrc=${Source%%\,}
         Source=${Source\,}
         #
         # Process all of the files that we haven't done yet.
         #
         if [ ! -f ${XMLTVDir}/${ZipCode}_${ProgSrc}previousupdate ]; then
             touch -t 197001010500 \
                   -f ${XMLTVDir}/${ZipCode}_${ProgSrc}previousupdate
         fi
      /usr/bin/find ${XMLTVPath} -name *.xml -type f \
          -newer ${XMLTVDir}/${ZipCode}_${ProgSrc}previousupdate \
          -exec /usr/bin/mythfilldatabase --file ${ProgSrc} \{\} \; \
                >/dev/null 2>&1
      #    -exec echo "/usr/bin/mythfilldatabase --file ${ProgSrc} {}" \;
      #    -exec /usr/bin/mythfilldatabase --file ${ProgSrc} \{\} \;
      touch -f ${XMLTVDir}/${ZipCode}_${ProgSrc}previousupdate

done

Updating The DVB Capture Card Drivers

If after you have everything set up properly, you find that your pcHDTV card will not capture Analog NTSC signals properly, you may need to rebuild the card's drivers from newer source. As of 2008 Feb 14, Mythbuntu's 7.10 kernel still contains code which will give you problems switching back and forth between NTSC and ATSC. Mythbuntu 8.04LTS, on the other hand, does contain the newest code and, furthermore, compiling and installing the fixes shown herein will break the DVB drivers. So, if you have 8.04LTS and it still does not work, you have the s.o.l. blues. Basically, this card is a piece of crap when it comes to Analog NTSC (many people in the pcHDTV/Ubuntu forums complain of it not working). If you still want Analog NTSC (now that the rest of us have moved on to HDTV), maybe you should try the Haupaugge WinTV-PVR-150 cards.

Anyway, under the earlier releases of Mythbuntu, to fix the DVB drivers, you need to compile the v4l-dvb tree yourself and install it over your current kernel modules. Follow these steps:

     sudo apt-get install gcc linux-headers-`uname -r` mercurial
     cd your/build/directory
     hg clone http://linuxtv.org/hg/v4l-dvb
     cd v4l-dvb
     make
     sudo make install
     sudo reboot

The second step should change to your local build directory (whatever that is), where the third step will clone a copy of the v4l-dvb build directory. If you want to put this in your home directory or some other inncuous spot, the build can be done without root priviledges. You only need root priviledges to install the resultant build.

Once the build/install is done, you need to reboot for the new drivers to be loaded. It should fix problems with the pcHDTV card. It is known to work on Mythbuntu 7.10, for example.

One more thing. Should you apply these changes to your system and they hose the DVB drivers, you can recover by firing up the package manager and reinstalling these packages:

     linux-image-ver-generic
     linux-ubuntu-modules-ver

Note that, despite what the comments tell you about using linux-image-generic instead, reinstalling it won't cut it because it does not force the dependant packages to be reinstalled (droppage). You must pick the two packages mentioned above, with the highest version numbers, and reinstall them individually.

Video Cards

If you are using one of the NVidia Geforce 440MX or newer video cards, the built-in XvMC support is supposed to offload a lot of work from the CPU when viewing HDTV streams. On the other hand, many users have reported that instead of improving the video, it makes it worse. This has certainly been my experience.

The stock setup will pick a video replay configuration that uses XvMC, if it is available, for certain frame sizes. If you experience problems when viewing video with one of the NVidia cards, this could be the cause. You will need to override the stock configuration.

Another problem is that many of the newer CPUs are dual processors but the video transcoding operation is forced by the stock configuration to use only one CPU. Thus, when you turn off XvMC, your processor will not be fast enough to transcode the video using only the one processor. The solution is to allow the use of two processors in your new configuration.

From the MythTV frontend, choose Utilities/Setup from the main menu, then Setup, TV Settings, and Playback from the menu tree. Navigate to the third page (Playback Profiles (3/9)) and select the "Add New" choice near the top of the page. Give your new entry a name (I called mine "Dual Core").

Once you've added the new playback group and named it, pick the "Add New Entry" choice near the bottom of the page. On the first screen, for the first Match Criteria, choose ">=" and 1280, 720. Leave the second Match Criteria blank. For the Decoder pick "Standard" and set Max CPUs to 2. For Video Renderer, select "xv-blit" and for OSD Renderer pick "softblend". On the second page, Primary Deinterlacer should be set to "Linear blend", as should Fallback Deinterlacer. Complete this playback entry.

Pick "Add New Entry" a second time. On the first screen, for the first Match Criteria, choose ">" and 0, 0. Leave the second Match Criteria blank. For the Decoder pick "Standard" and set Max CPUs to 2. For Video Renderer, select "xv-blit" and for OSD Renderer pick "softblend". On the second page, Primary Deinterlacer should be set to "Greedy HighMotion (2x)". Fallback Deinterlacer should be set to "Kernel". Complete this playback entry.

Navigate through the remaining screens to cause the configuration to be stored and selected.

Newest NVidia Driver

If you are using an NVidia graphics card and are unfortunate enough to be trying to connect to a display that is not recognized by the NVidia driver, you will undoubtedly have problems configuring that display, since the shipping NVidia driver in many releases of Mythbuntu (e.g. 8.04LTS) does not recognize Modelines in the xorg.conf file. Before you can configure your display, using the information outlined below, you may have to install the newest NVidia driver (let the goat roping continue).

Firstly, since you are going to be messing with the X-Windows configuration and the display adapter, you must shutdown X. This pretty much means that you must first ensure that you have a working SSH connection to the machine in question, since shutting down X on the Mythbuntu distributions renders the machine useless (no, it does not revert to a console that you can enter commands into -- it just sits there in dumb-ass mode). So, get a copy of your favorite telnet, turn on SSH on the box and make sure you can talk to it that way. When you're happy that SSH works, shut down the X-Server:

     sudo /etc/init.d/gdm stop

From the telnet session, make sure you have the driver build environment (this is not necessarily the full kernel build environment). To verify that you do, try:

     ls -l /lib/modules/`uname -r`/build

If you have this directory installed, skip down to the libc step below (Ubuntu usually provides them in a typical installation or if you if you already did these steps in conjunction with compiling a NIC driver, above). Otherwise, you'll need to first get the build environment:

     sudo apt-get install build-essential

Then, you should make sure to install the latest headers for your kernel. When you enter the following command, be sure to use back-quotes:

     sudo apt-get install linux-headers-`uname -r`

Next, link the headers to the build folder in the proper place.

     sudo ln -s /usr/src/linux-headers-`uname -r` /lib/modules/`uname -r`/build

In addition to the driver build environment, you'll need the libc development package, the package configuration module, and the XOrg development package installed. Use the following command to get and install them:

     sudo apt-get install libc6-dev pkg-config xorg-dev

This should allow you to build the NVidia driver.

Create a new directory and download the latest NVidia driver for Linux from http://www.nvidia.com/object/unix.html:

     mkdir NVidia
     cd NVidia
     use your favorite browser to navigate through the NVidia pages and download
       the driver

Purge the NVidia restricted package, if installed, by doing:

     sudo dpkg --purge nvidia-glx-new

Run the NVidia installer:

     sudo sh NVIDIA-Linux-x86-173.14.05-pkg1.run

You can let the installer have a crack at finding a pre-compiled version on the NVidia Web site (but this didn't work for Mythbuntu 8.04LTS). If it doesn't find one, or you just want to compile it locally, skip that step. Allow the installer to build the driver locally. Then, allow it to update your xorg.conf file.

Note that the installer may whine about the compiler version not matching the one used to build the kernel. You've just got to love the guys who thought it would be a smooth idea to use compiled in kernel interfaces for all of the device drivers. Nothing like having to compile your device drivers every time you change kernels. So, if we're going that route, might as well build structures that depend on the compiler version for the interface to work. Why not? What a crock of shit....

Anyway, the warning is probably bogs, since different point releases of the compiler don't usually change the way structures are aligned. You can probably ignore it. But, if you're worried, you can try the following (it worked for me):

     sudo sh NVIDIA-Linux-x86-173.14.05-pkg1.run --add-this-kernel
     sudo sh NVIDIA-Linux-x86-173.14.05-pkg1-custom.run

This will build a custom install script especially for the currently-running kernel. You can then execute that script to build the NVidia driver especially for it. There shouldn't be any whining about the compiler version but, if you still have problems, here is the full story:

     If you know what you are doing and want to override this check, you can do
     so by setting the environment variable IGNORE_CC_MISMATCH, before doing the
     build.
     Otherwise, set the CC environment variable to the name of the compiler that
     was used to compile the kernel.
     The reason for compiling the NVIDIA kernel module with the same compiler
     version that was used to compile your kernel (as was noted above) is that
     some Linux kernel data structures are dependent on the version of gcc used
     to compile them; for example, in include/linux/spinlock.h:
     ...
     * Most gcc versions have a nasty bug with empty initializers.
     */
     #if (__GNUC__ > 2)
       typedef struct { } rwlock_t;
       #define RW_LOCK_UNLOCKED (rwlock_t) { }
     #else
       typedef struct { int gcc_is_buggy; } rwlock_t;
       #define RW_LOCK_UNLOCKED (rwlock_t) { 0 }
     #endif
     If the kernel is compiled with gcc 2.x, but gcc 3.x is used when the kernel
     interface is compiled (or vice versa), the size of rwlock_t will vary, and
     things like ioremap will fail.  To check what version of gcc was used to
     compile your kernel, you can examine the output of:
     cat /proc/version
     To check what version of gcc is currently in your $PATH, you can examine the
     output of:
     gcc -v

Oh, and one other little wrinkle. On some later versions of the OS (e.g. Mythbuntu 9.04), the geniuses at XOrg decided to add an irrelevant windge to the X command when "-showDefaultLibPath" is used. So, when the following command is run:

     /usr/bin/X -showDefaultLibPath

You see:

     X: warning; process set to priority -2 instead of requested priority 0
     /usr/lib

First of all, who gives a rat's butt what priority X runs at? And, certainly, who gives a rat's butt what priority it runs at when its echoing the default library path? Are these guys on some planet where stupidity is the norm? But, ranting aside, the windge comes as a huge surprise to the NVidia install script which is expecting the path name of a directory, not some meaningless bleating. The script gets all confused and complains about the fact that the directory "X: warning ... /usr/lib" doesn't exist. Duh! Fortunately, it picks /usr/lib by default and all is well, despite what could have been another blow for lack of upward compatibility.

Here are the instructions for the installer, just in case you need them. The complete instructions can be found in the README file on the NVidia Web site at: http://www.nvidia.com/object/unix.html.

     The .run file is a self-extracting archive. When executed, it extracts the
     contents of the archive and runs the contained nvidia-installer utility,
     which provides an interactive interface to walk you through the installation.
     nvidia-installer will also install itself to /usr/bin/nvidia-installer, which
     may be used at some later time to uninstall drivers, auto-download updated
     drivers, etc. The use of this utility is detailed later in this chapter.
     You may also supply command line options to the .run file. Some of the more
     common options are listed below.
     --info              Print embedded info about the .run file and exit.
     --check             Check integrity of the archive and exit.
     --extract-only      Extract the contents of NVIDIA-Linux-x86-173.14.05.run,
                         but do not run nvidia-installer.
     --help              Print usage information for the common commandline
                         options and exit.
     --advanced-options  Print usage information for common command line options
                         as well as the advanced options, and then exit.
     --uninstall         During installation, the installer will make backups of
                         any conflicting files and record the installation of
                         new files. The uninstall option undoes an install,
                         restoring the system to its pre-install state.
     --latest            Connect to NVIDIA's FTP site, and report the latest
                         driver version and the url to the latest driver file.
     --update            Connect to NVIDIA's FTP site, download the most recent
                         driver file, and install it.
     --ui=none           The installer uses an ncurses-based user interface if
                         it is able to locate the correct ncurses library.
                         Otherwise, it will fall back to a simple commandline
                         user interface. This option disables the use of the
                         ncurses library.

Black list the nv driver in the /etc/default/linux-restricted-modules-common file. Do so by editing the file with your favorite editor and changing the DISABLED_MODULES line to include "nv". For example:

     DISABLED_MODULES="nv"

Check that no prior installations of any versions of the NVidia driver have left crap-oh-la lying about to mess things up. In /etc/modprobe.d, you may find a module named "nvidia-kernel-nkc.conf". In it you may see something like:

     alias char-major-195* nvidia
     options nvidia NVreg_DeviceFileUID=0 NVreg_DeviceFileGID=44
                    NVreg_DeviceFileMode=0660

This will cause no end of grief by loading a copy of the NVidia kernel driver that is left over from the prior installation. When the newly-installed driver attempts to run, it will complain about the kernel driver API being wrong and quit, thereby causing XOrg not to start (you'll see this in /var/log/Xorg.0.log upon reboot). A sure test is to do "rmmod nvidia" and then restart gdm. If this causes gdm to start OK, you've got a conflicting module loaded.

Also, someone or something may have mistakenly tried to fix this situation by adding a blacklist for the nvidia driver to one of the blacklist files in /etc/modprobe.d. The most likely place is "blacklist-local.conf" but it may be somewhere else too. Look for any file containing:

     blacklist nvidia

Remove this line from the file. If it is the only line in the file, you may delete it too, if you wish.

Incidentally, some of the blogs or mail archives on the Internet suggest adding "rmmod nvidia" to /etc/init.d/gdm, right before gdm is started. If you fix the problem correctly, this should be completely unnecessary.

Start the gdm server back up:

     sudo /etc/init.d/gdm start

If you wish to use the NVidia-supplied configurator for the xorg.conf file, you can find the man page under:

     man nvidia-xconfig

Video Displays

Normally, Mythbuntu does a pretty good job of detecting the display connected to it and configuring it automagically. However, if your video display does not play well with Mythbuntu (i.e. it cannot be probed and set up automagically), you may have to configure it yourself.

This section describes what to do about this situation but first, a note about how to get out of a bind, if for some reason your display does not work properly and you cannot recover from this state because the picture is too garbled to run the usual configuration tools.

Using SSH on another system, connect to the system that is in trouble and go to the /etc/X11 directory. There, you should find files named xorg.conf*. You should rename xorg.conf to something like xorg.conf.brokey and then symlink xorg.conf to the xorg.conf.failsafe file:

     cd /etc/X11
     sudo mv xorg.conf xorg.conf.brokey
     sudo ln -s xorg.conf.failsafe xorg.conf

This should get you up and running, at which point you can begin monkeying around with the display configuration to arrive at one that works for your display.

Also, before you start playing around with any of the display settings, be aware that some of the NVidia drivers don't handle modelines properly so you may want to check into that first, before you waste a whole lot of time (like we did) trying to set something that's going to have no effect.

If the display you are trying to work with is a TV, you may find some useful notes about setting it up at this URL:

     http://www.linuxis.us/linux/media/howto/linux-htpc/
       video_card_configuration.html

Basically, you are trying to figure out one or more modelines that can be used to set the various screen resolutions supported by your display. There should be a chart in the back of your display's manual that lists all of the supported modes (beware that some of the charts we've seen have the vertical and horizontal frequencies exchanged - a good clue is that the vertical frequency is usually the one that matches the number in the VESA name). First off, you should try to pick one of the standard modes from the list below. Also, it is best to try and pick the highest vertical refresh rate (in Hz) supported by your display:

     # 640x400 @ 85Hz (VGA VESA 85) hsync: 37.9kHz
     ModeLine "640x400"    31.5    640  672  736  832  400  401  404  445 \
       -hsync +vsync
     # 640x480 @ 60Hz (Industry standard) hsync: 31.5kHz
     ModeLine "640x480"    25.2    640  656  752  800  480  490  492  525 \
       -hsync -vsync
     # 640x480 @ 72Hz (VGA VESA 72) hsync: 37.9kHz
     ModeLine "640x480"    31.5    640  664  704  832  480  489  491  520 \
       -hsync -vsync
     # 640x480 @ 75Hz (VGA VESA 75) hsync: 37.5kHz
     ModeLine "640x480"    31.5    640  656  720  840  480  481  484  500 \
       -hsync -vsync
     # 640x480 @ 85Hz (VGA VESA 85) hsync: 43.3kHz
     ModeLine "640x480"    36.0    640  696  752  832  480  481  484  509 \
       -hsync -vsync
     # 720x400 @ 85Hz (VESA 85) hsync: 37.9kHz
     ModeLine "720x400"    35.5    720  756  828  936  400  401  404  446 \
       -hsync +vsync
     # 800x600 @ 56Hz (SVGA VESA 56) hsync: 35.2kHz
     ModeLine "800x600"    36.0    800  824  896 1024  600  601  603  625 \
       +hsync +vsync
     # 800x600 @ 60Hz (SVGA VESA 60) hsync: 37.9kHz
     ModeLine "800x600"    40.0    800  840  968 1056  600  601  605  628 \
       +hsync +vsync
     # 800x600 @ 72Hz (SVGA VESA 72) hsync: 48.1kHz
     ModeLine "800x600"    50.0    800  856  976 1040  600  637  643  666 \
       +hsync +vsync
     # 800x600 @ 75Hz (SVGA VESA 75) hsync: 46.9kHz
     ModeLine "800x600"    49.5    800  816  896 1056  600  601  604  625 \
       +hsync +vsync
     # 800x600 @ 85Hz (SVGA VESA 85) hsync: 53.7kHz
     ModeLine "800x600"    56.3    800  832  896 1048  600  601  604  631 \
       +hsync +vsync
     # 1024x768 @ 43Hz (industry standard) hsync: 35.5kHz
     ModeLine "1024x768"   44.9   1024 1032 1208 1264  768  768  776  817 \
       +hsync +vsync Interlace
     # 1024x768 @ 60Hz (XGA VESA 60) hsync: 48.4kHz
     ModeLine "1024x768"   65.0   1024 1048 1184 1344  768  771  777  806 \
       -hsync -vsync
     # 1024x768 @ 70Hz (VESA 70, HP1070) hsync: 56.5kHz
     ModeLine "1024x768"   75.0   1024 1048 1184 1328  768  771  777  806 \
       -hsync -vsync
     # 1024x768 @ 75Hz (XGA VESA 75) hsync: 60.0kHz
     ModeLine "1024x768"   78.8   1024 1040 1136 1312  768  769  772  800 \
       +hsync +vsync
     # 1024x768 @ 85Hz (XGA VESA 85) hsync: 68.7kHz
     ModeLine "1024x768"   94.5   1024 1072 1168 1376  768  769  772  808 \
       +hsync +vsync
     # 1152x864 @ 75Hz (SXGA VESA 75) hsync: 67.5kHz
     ModeLine "1152x864" 108.0    1152 1216 1344 1600  864  865  868  900 \
       +hsync +vsync
     # 1280x960 @ 60Hz (SXGA VESA 60) hsync: 60.0kHz
     ModeLine "1280x960"  108.0   1280 1376 1488 1800  960  961  964 1000 \
       +hsync +vsync
     # 1280x960 @ 85Hz (SXGA VESA 85) hsync: 85.9kHz
     ModeLine "1280x960"  148.5   1280 1344 1504 1728  960  961  964 1011 \
       +hsync +vsync

If you didn't find your display's resolution in this list, there are more standard modes listed at:

     http://m.domaindlx.com/LinuxHelp/resources/modelines.htm

Another way to obtain a modeline for your display is to use videogen. If it is not installed on your Mythbuntu system, you can obtain it with:

     sudo apt-get install videogen

To use it, you select the maximum dot or pixel clock frequency from your display's specifications, along with the maximum vertical and horizontal refresh rates. Feed the desired screen resolution plus these values into videogen:

     videogen -m640x480 -mdc=108 -mhf=87 -mvf=72

This will generate a modeline with the highest refresh rate that can be supported by your monitor for the resolution selected. In the above example, we determined that the maximum dot clock was 108 (from perusing all of the resolutions listed for the monitor) and the maximum horizontal frequency was 87 KHz, while the maximum vertical frequency was 72Hz.

This would yield a modeline for a dot clock of 30MHz, a horizontal refresh rate of 36.4 kHz and a vertical refresh rate of 72Hz.

Yet another alternative is to use the modeline calculator at:

     http://xtiming.sourceforge.net/cgi-bin/xtiming.pl

Instead of determining the maximum refresh rate for your display, this will let you put in the refresh rate and calculate the modeline from that. If you are trying to match your display's refresh rate with that of a video broadcast so as not to see jitter from interpolated frames, you might find this method more to your liking.

Now, make a copy of your working xorg.conf file in /etc/X11 and begin hacking the Monitor section. Set the device identification fields to something useful:

     Identifier   "Syntax LT27HV LCD Display"
     VendorName   "Syntax"
     ModelName    "Olevia LT27HV"

Next, you should probably set the minimum and maximum horizontal and vertical sync frequencies from the chart of your display's capabilities:

     HorizSync    56-87
     VertRefresh  24-72

These values are not used to calculate any actual display settings but the values in the modelines are checked against these limits to ensure that you do not exceed your display's capabilities (and possibly destroy it).

Then, add the modelines to this section:

     # 640x480 @ 85Hz (VGA VESA 85) hsync: 43.3kHz
     ModeLine "640x480-85"  36.0  640 696 752 832  480 481 484 509  -hsync -vsync
     # 800x600 @ 85Hz (SVGA VESA 85) hsync: 53.7kHz
     ModeLine "800x600-85"  56.3  800 832 896 1048  600 601 604 631  +hsync +vsync
     # 1024x768 @ 85Hz (XGA VESA 85) hsync: 68.7kHz
     ModeLine "1024x768-85"  94.5  1024 1072 1168 1376  768 769 772 808 \
       +hsync +vsync
     # 1280x720 @ 60Hz (1280x720-60) vsync: 60.39Hz, hsync: 45.72kHz, clk: 74.25
     # This is the only true native mode for the LT27HV display.
     Modeline "1280x720-60" 74.25 1280 1312 1592 1624 720 735 742 757 \
       +hsync +vsync

For the Syntax Olevia models, you may want to add the following, as well:

     # Power saving mode
     Option       "DPMS"
     # We know everything about this display
     Option       "UseEDID" "false"
     # We know what the dot pitch is
     Option       "DPI" "96×96"
     # Make sure the video card always picks the CRT.  Or, if you have the
     # display plugged in on the DVI connection, use "DFP" instead of "CRT-0".
     Option       "UseDisplayDevice" "CRT-0"

Next, hack the Screen section to use the display that you just defined by setting the Display SubSection to point to it:

     # The color depth
     Depth        24
     # All of the supported modes that we defined in modelines.  The first is
     # the default mode chosen at startup.
     Modes        "1280x720-60"  "1024x768-85"  "800x600-85"  "640x480-85"

Now, you can either copy this file over the top of xorg.conf or symlink it:

     sudo rm -f xorg.conf
     sudo ln -s xorg.conf.failsafe xorg.conf

If you have any more questions about the configuration of display devices under Xorg, you can look at the man page:

     man xorg.conf

Getting Rid of Overscan and Centering the Image

If the image displayed on your display device is not properly centered or has overscan, you may be able to correct it by following these procedures. The important thing to understand is that the visible part of the image is only a portion of the overall image you send to the screen. Since HDTVs can be very, very finicky about accepting a signal, it's best to get a modeline they can accept (see above) and then tweak it to get the image you want.

Let's say, in my case, my Olevia LT27HV would sync to a 1280x720 signal, but with the image centered too far to the right and to far up the screen, leaving a black bar on the left and at the bottom.

The orignal modeline that the TV was syncing to:

     # 1280x720 @ 60Hz (1280x720-60) vsync: 60.39Hz, hsync: 45.72kHz, clk: 74.25
     # This is the only true native mode for the LT27HV display.
     Modeline "1280x720-60" 74.25 1280 1312 1592 1624 720 735 742 757 \
       +hsync +vsync

This, however, left me with a black strip of about 1" on the right and on the bottom.

So, to move the image to the left, all we do is move the horizontal sync bar to the right. The horizontal sync bar is given by the 4th and 5th parameters in the modeline (1312 and 1592 above). That bar always stays fixed, so if we 'move' the bar to the left the picture moves to the right. Let's try adding 10 pixels to it:

     Modeline "1280x720-60" 74.25 1280 1322 1602 1624 720 735 742 757 \
       +hsync +vsync

The vertical sync bar is given by the 8th and 9th numbers (735 and 742 above), and works the same way: increase the numbers and the image moves up, decrease the numbers and the image moves down.

Now that the top left is positioned correctly, let's say we needed to fix some overscan. To do that, we'd tell the video card to put the image into a smaller portion of the overall frame it sends to the TV. We'd do that by reducing the numbers in the 3rd and 7th columns (1280 and 720 above). Now they read 1280x720 but if that's too big for the TV to display correctly, a bit of trial and error might produce a modeline where the image is centered correctly, and has no overscan:

     Modeline "1280x720-60" 74.25 1274 1322 1602 1624 716 730 737 757 \
       +hsync +vsync

For an excellent graphical and technical explanation, see:

     http://www.epanorama.net/documents/vga2rgb/timings.html

Desktop Problems

The most common problem that occurs, with the Mythbuntu desktop, is the disappearance of the xfce-panel. What is it, you ask? Why, its simply the application that shows the taskbar at the top/bottom of the desktop. If this application is turned off or if it fails to launch, you won't see the taskbar.

To cure the problem, it is best to reset your xfce-panel settings to their original values. The easiest way to do this (you can monkey with the panel settings application through the display manager for a couple or six hours but this usually proves to be fruitless, not to mention frustrating) is to shut down the display manager and then fix up the config files, like so:

     sudo /etc/init.d/gdm stop   (earlier systems like Mythbuntu 9.04)

or

     sudo stop lightdm   (later systems like Mythbuntu 12.04)

Once the display manager stops, edit its settings config file for the local user that is being logged on (e.g. "mythtv"). Make sure that the SaveOnExit line looks like this:

/home/mythtv/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml:

.

       .
  <property name="SaveOnExit" type="empty"/>
       .
       .
       .

Then, get rid of any saved xfce save sessions in the user's cache. For the "mythtv" user, you'd do something like this:

     sudo rm -f /home/mythtv/.cache/sessions/xfce4-session*

Once that is done, you can start up the display manager and you should see the panel the way it used to be (i.e. with the task bar):

     sudo /etc/init.d/gdm start   (earlier systems like Mythbuntu 9.04)

or

     sudo start lightdm   (later systems like Mythbuntu 12.04)

Sound Problems

For HDMI sound, see the following section.

If you have problems with sound volume, from prior experience with other sound cards it is usually due to the master volume being muted (a number of sound drivers are installed with the master volume muted), the master volume being set too low, the PCM volume being set too low or the switches, such as the number of channels available, being set incorrectly. For example, selecting 2-channel sound when 4-, or 6-channel sound has to be selected, even though only two speakers are actually used.

Also, another common problem caused by the sound card not being set up properly is that the frontend will not restart properly after you view a recorded video or live TV. Instead, when you exit from viewing the video, you will simply see a black screen and the frontend will have to be killed and restarted to get the Myth menu back. So, if you have this problem, especially after you install a new sound card, mess with the sound settings or clone a machine to new hardware, check all of the steps outlined here for fixing sound problems.

You can often overcome problems with the master volume being set too low or the PCM volume being set too low, directly through the setup pages of the Mythbuntu frontend. Enter through the "Utils/Setup" menu choice and then navigate through the menus via the "Setup" and "General" choices or directly via "Setup" and then "Audio", on later versions. Then, page forward until you reach the "Audio/Mixer" page. Set these settings as follows:

     Mixer Controls: PCM
     Master Mixer Volume: 100
     PCM Mixer Volume: 100

If changing these settings in the Mythbuntu frontend still doesn't work, try experimenting with the settings in alsamixer:

     alsamixer

Typically, the master volume, PCM volume and particularly the front speaker volume (the front speaker volume is not settable from the Mythbuntu frontend) should all be set to 100 and the three controls not muted. The up/down arrows raise/lower the volume and the 'M' toggles mute. If "MM" is shown for the control, it is muted.

Or, if you prefer a nicer GUI, for earlier versions of Mythbuntu (up to 9.04) you can try aumix, if the aumix-gtk package is installed like so:

     sudo apt-get install aumix-gtk

The mixer can be run from the Multimedia menu or by typing:

     aumix &

For later versions of Mythbuntu (9.10 and beyond), you can run the "GNOME ALSA Mixer" from the Multimedia menu, if the gnome-alsamixer package is installed thusly:

     sudo apt-get install gnome-alsamixer

Once you set the volume levels in the aforementioned manner, they should stick each time the system is rebooted (i.e. you only have to set them once). If they don't, you could use the command line program "amixer" in the "rc.local" startup script to set the mixer volume each time the system reboots but, so far, we haven't had to resort to this.

A couple of commands that may be useful to test the sound are:

     speaker-test
     aplay -D plughw:0,0 /usr/share/sounds/alsa/Front_Center.wav

If there isn't any sound, you can try running the following script to see what sound cards are installed and activated, and how they named. You should pick one of the names enumerated as the output device of MythTV.

RecognizeAudio

     #!/bin/sh
     #
     # Script to find the sound cards installed in the system and give some
     # useful information about them.
     #
     # This script can be useful in debugging ALSA sound problems.  It will find
     # all of the sound cards installed in the system by querying the PCI bus and
     # looking for sound card models.  It will then scan the ALSA modules loaded
     # into the kernel and see which sound cards are recognized by ALSA.  Of the
     # recognized modules, it checks which ones are activated (i.e. capable of
     # playing sound).  Finally, a list of the sound playback devices (according
     # to ALSA) are enumerated, followed by the names used to select these
     # devices.
     #
     # If you run this script and you don't see all of the following headings,
     # there is probably something wrong with your ALSA setup:
     #
     #      Sound cards recognized by the system:
     #      Sound cards recognized by ALSA:
     #      Sound cards recognized by ALSA, and activated:
     #      ALSA playback devices:
     #      Names used to reference ALSA playback devices:
     #
     # Find all of the sound cards on the PCI bus.
     echo "Sound cards recognized by the system:"
     lspci -nn | grep --color=none '\[04[80][13]\]'
     # For each of the sound cards on the PCI bus, see which ones have an ALSA
     # kernel module loaded.
     Module=`lspci -nnk | grep -A 3 '\[04[80][13]\]' | while read Line; do
         if ( echo $Line | grep -q '\[04[80][13]\]' ); then
             Card=$Line
         else
             if ( echo $Line | grep -q 'Kernel module' ); then
                 echo $Card
             fi
         fi
     done`
     if [ "$Module"x != x ]; then
         echo
         echo "Sound cards recognized by ALSA:"
         echo $Module
     fi
     # Now, for each of the sound cards on the PCI bus, see which ones have an
     # ALSA device driver.
     Driver=`lspci -nnk | grep -A 3 '\[04[80][13]\]' | while read Line; do
         if ( echo $Line | grep -q '\[04[80][13]\]' ); then
             Card=$Line
         else
             if ( echo $Line | grep -q 'Kernel driver' ); then
                 echo $Card
             fi
         fi
     done`
     if [ "$Driver"x != x ]; then
         echo
         echo "Sound cards recognized by ALSA, and activated:"
         echo $Driver
     fi
     # Give a list of all of the ALSA playback devices and a list of their names.
     if [ "$Driver"x != x ]; then
         echo
         echo "ALSA playback devices:"
         aplay -l | tail -n +2
      echo
      echo "Names used to reference ALSA playback devices:"
      aplay -L

fi

One solution for fixing missing or misconfigured ALSA devices is to reinstall the ALSA package as follows:

     sudo apt-get remove --purge alsa-base
     sudo apt-get install alsa-base
     sudo alsa force-reload

If you still experience problems, the Comprehensive Sound Problem Solutions Thread, which can be found at this URL, may prove helpful with a solution:

     http://ubuntuforums.org/showthread.php?t=1885240
     https://docs.google.com/document/d/
       1iTlJ8BfqXUjaHO__TEdlkvuqB1WLOkGaudngc5SFLMI/edit

However, before you start out on any sound debugging procedure, make sure that your system's BIOS settings are set so that sound is enabled. On some motherboards with built-in sound, the sound can be disabled or set to high-definition audio in the BIOS. This may preclude the sound from working and no end of monkeying with the ALSA/mixer settings will have any effect. So, check out the BIOS settings first.

Also, there are known problems with the dreaded ALC887 chipset (either from Realtek, or emulated by Nvidia). If your motherboard or soundcard has one of these on it (you should probably throw it in the trash, return it, or get another model), the ALSA drivers don't handle detection of the headphone signal correctly and consequently turn the speakers off all the time. This problem is reported to be fixed by adding this line to the end of the /etc/modprobe.d/alsa-base.conf file:

     options snd_hda_intel model=auto position_fix=3

If that doesn't work, some users have reported that the sledge hammer approach works, when you add this line to the end of the /etc/modprobe.d/alsa-base.conf file:

     options snd_hda_intel model=generic

In either case, a reboot is required.

Finally, you should check your MythTV sound settings, either through MythTV itself or by listing the pertinent rows in the settings table:

     mysql -uroot -p mythconverg
       select * from settings where hostname='mrfrntend'
         and value in ('AudioOutputDevice', 'PassThruOutputDevice',
           'MaxChannels', 'AudioUpmixType', 'AC3PassThru', 'DTSPassThru',
           'AggressiveSoundcardBuffer', 'MythControlsVolume');

For analog sound, the following settings seem to work well:

     mysql -uroot -p mythconverg
       update settings set data='ALSA:default'
         where value='AudioOutputDevice' and hostname='mrfrntend';
       update settings set data='Default'
         where value='PassThruOutputDevice' and hostname='mrfrntend';
       update settings set data=2
         where value='MaxChannels' and hostname='mrfrntend';
       update settings set data=0
         where value='AudioUpmixType' and hostname='mrfrntend';
       update settings set data=0 where
         value='AC3PassThru' and hostname='mrfrntend';
       update settings set data=0
         where value='DTSPassThru' and hostname='mrfrntend';
       update settings set data=0
         where value='AggressiveSoundcardBuffer' and hostname='mrfrntend';
       update settings set data=1
         where value='MythControlsVolume' and hostname='mrfrntend';

HDMI Sound


To get HDMI sound working, you essentially switch the output device to the appropriate video card, so that the sound is sent out the HDMI cable along with the video signal. From MythTV's point of view, this is transparent, since the switching is done via ALSA (more below). However, there are some MythTV settings which can effect how the HDMI sound works.

So, to begin, you should check your MythTV sound settings, either through MythTV itself or by listing the pertinent rows in the settings table:

     mysql -uroot -p mythconverg
       select * from settings where hostname='mrfrntend'
         and value in ('AudioOutputDevice', 'PassThruOutputDevice',
           'MaxChannels', 'AudioUpmixType', 'AC3PassThru', 'DTSPassThru',
           'AggressiveSoundcardBuffer', 'MythControlsVolume');

For digital sound, the following settings should work well, if your HDMI output device (i.e. your video card) is set as the default output:

     mysql -uroot -p mythconverg
       update settings set data='ALSA:default'
         where value='AudioOutputDevice' and hostname='mrfrntend';
       update settings set data='Default'
         where value='PassThruOutputDevice' and hostname='mrfrntend';
       update settings set data=2
         where value='MaxChannels' and hostname='mrfrntend';
       update settings set data=0
         where value='AudioUpmixType' and hostname='mrfrntend';
       update settings set data=1
         where value='AC3PassThru' and hostname='mrfrntend';
       update settings set data=1
         where value='DTSPassThru' and hostname='mrfrntend';
       update settings set data=0
         where value='AggressiveSoundcardBuffer' and hostname='mrfrntend';
       update settings set data=0
         where value='MythControlsVolume' and hostname='mrfrntend';

These settings will pass digital sound directly through to the HDMI display, instead of monkeying with them or re-encoding them (with a subsequent loss of sound quality).

However, you may need to use something like this, to cause MythTV to send the sound directly to the HDMI display via the channel of the display card that it is connected to, without counting on the ALSA default to be set properly (which it is often not):

     mysql -uroot -p mythconverg
       update settings set data='ALSA:dmix:CARD=NVidia,DEV=7'
         where value='AudioOutputDevice' and hostname='mrfrntend';

See below for the details on how to determine which card and device you should set in the settings (above).

Before going further, you should check that your userid and the mythtv userid are both in the "audio" group. To do that, do:

     grep audio /etc/group

You should see something like:

     audio:x:29:mythtv,joeuser

If either your userid or the mythtv userid isn't in the audio group, add them like this:

     su
     adduser joeuser audio

The next step is to set the default ALSA device to be the video card. You can find the appropriate sound card with:

     cat /proc/asound/cards

By way of example, you'll probably see something like this:

     0 [Intel          ]: HDA-Intel - HDA Intel
                          HDA Intel at 0xddc40000 irq 140
     1 [NVidia         ]: HDA-Intel - HDA NVidia
                          HDA NVidia at 0xdd080000 irq 17

Since the graphics card is probably the NVidia device, we should set ALSA up to use "Card 1" as the default sound ouput. You can determine any aliases that can be used for the card by looking directly at the /proc/asound directory. There should be a symlink for each alias. In the case of the NVidia card, it will likely look like this:

     lrwxrwxrwx 1 root root 5 May 26 22:50 NVidia -> card1

Create (or update) /etc/asound.conf and add the following two lines:

     defaults.pcm.card n
     defaults.ctl.card n

Replace "n" with the sound card number found in the first step.

#>>>>>>
Note that some HDMI audio cards have more than one device. You may have to figure out which device to use (e.g. some NVidia cards show devices 3, 7, 8, etc. and the correct device is not the first one but often 7 or 8), to get the sound to work.

You can obtain further information about the card by looking at the directories in /proc/asound. The devices file will list all of the audio devices found on all of the audio cards. By way of example, here is the output from a system with both Intel and NVidia sound cards:

  1. : sequencer
  2. [ 0- 2]: digital audio capture
  3. [ 0- 0]: digital audio playback
  4. [ 0- 0]: digital audio capture
  5. [ 0- 0]: hardware dependent
  6. [ 0] : control
  7. [ 1- 9]: digital audio playback
  8. [ 1- 8]: digital audio playback
  9. [ 1- 7]: digital audio playback
  10. [ 1- 3]: digital audio playback
  11. [ 1- 3]: hardware dependent
  12. [ 1- 2]: hardware dependent
  13. [ 1- 1]: hardware dependent
  14. [ 1- 0]: hardware dependent
  15. [ 1] : control
  16. : timer

Not all that helpful but it does show that devices 3, 7, 8 and 9 on the NVidia care are meant for digital audio playback. So, we're at least on the right track. More information may be gleaned from looking in the device directory for the specific card in question. In the case of our NVidia device, we list the contents of ls -l /proc/asound/card1 and found this:

.

       .

dr-xr-xr-x 3 root root 0 May 26 22:50 pcm3p dr-xr-xr-x 3 root root 0 May 26 22:50 pcm7p dr-xr-xr-x 3 root root 0 May 26 22:50 pcm8p dr-xr-xr-x 3 root root 0 May 26 22:50 pcm9p

       .
       .
       .

Once you do that, you can set the default device too, by adding the following two lines to /etc/asound.conf:

     defaults.pcm.device d
     defaults.ctl.device d

Replace "d" with the correct device number (but, see below). #<<<<<<

Run alsamixer from the command line and set up the chosen sound card. If you see one or more S/PDIF sliders, make sure that all of them are turned on and not muted. Muted sliders show "MM" at the bottom. To turn them on, cursor over to each slider and press "M". This will toggle them to "OO", which means that they are turned on. There is no need to set the volume, since this has no effect on digital sound.

If going the default device under ALSA route doesn't work with MythTV, you may also be able to set the right card and device directly under the MythTV FrontEnd Setup menu on the machine in question. Once you see the Setup menu, pick Sound. From there, you can set up the audio output device to directly use the proper HDMI card and correct device. MythTV will even tell you whether your monitor is connected via a chosen device, if your HDMI monitor is plugged in and powered on at the time. Until you see a card/device choice that mentions your particular monitor, you should keep trying other combinations until you find the one working combination.

Network Problems

You may periodically experience one or more of the systems pounding the heck out of your network for no apparent reason. For example, its five o'clock in the morning and nobody is watching anything, nor are there any recordings in progress and all of the recordings from the previous day have been commercial flagged. In other words, to paraphrase Mr. R., it should be a quiet day in the neighborhood. But, something is pounding the heck out of the network switch.

Install the program nethogs like this:

     su
     apt-get install nethogs

When you run it, it will show you which process generating all of the network traffic. Generally, we find that it is the backend. On later versions of Myth, you can simply kill it and it will restart automagically. This may solve the problem.

Unfortunately, in our experience, the most common reason for the network being pounded by the backend process is related to the Hauppauge HVR-2250 capture card. Something in the code for this device causes its two encoders to head south and stop working while, at the same time, causing the backend process to pound the heck out of the NIC. Killing the backend process does get rid of the network traffic temporarily. But, as soon as something tries to use one of the encoders on the HVR-2250, the pounding starts right up again. And, neither of the two encoders works. So, the only solution appears to be a reboot.

Frontend Problems

Myth's internal player is a fragile thing. I has been known to crash under a number of circumstances. When it does, you'll be looking at a blank, black screen, with no way to get back to the frontend. The only solution is to go to another system, telnet into the Myth system, determine the PID of the frontend, and kill it:

     su
     ps x -A | grep myth

You'll see something like:

     1571 ?     S      0:00 /usr/bin/dbus-launch --exit-with-session \
                             /usr/share/mythbuntu/session.sh
     1620 ?     S      0:00 /bin/sh /usr/bin/mythfrontend --service
    28209 ?     Sl     9:46 /usr/bin/mythfrontend.real --syslog local7

The process to kill is the one that is running "mythfrontend.real". To do so, use a command like:

     su
     kill -9 28209

The frontend should respawn itself and you will again be in business.

The causes of crashes while playing videos are varied and unknown, mostly having to do with malformed video or audio streams and the internal player's inability to handle poor quality data well. Bounds checking and other hardening techniques would go a long way to making it more robust but these are not techniques that are practiced by all, sad to say.

On the other hand, if the player crashes when you exit from watching a video, recording or live TV, the causes of such a crash are better known. One has to do with the inability of the frontend to contact the master backend for further instructions. To fix the cause of these sorts of crashes, you should review your /etc/udev/rules.d/70-persistent-net.rules to ensure that your system's NIC is properly mapped to the expected ethernet device. Look in /etc/network/interfaces to verify that the network device is properly set up.

Examine the /etc/hostname file to make certain that the correct host name is given therein, and then look at /etc/hosts to see that it is mapped to its correct IP address. While you're at it, also make certain that all of the other Myth host names, particularly the backend's, are mapped to their correct IP addresses so that DNS need not be invoked to map them to their IP addresses.

Define the master backend and its access parameters in the text file /etc/mythtv/mysql.txt. Pay particulat attention to these options, which should have values something like this:

     DBHostName=192.168.1.13
     DBUserName=mythtv
     DBPassword=asecret
     DBName=mythconverg
     DBType=QMYSQL3

If you copied or changed any of the data in the "settings" table, look at that data to make sure that the system's hostname is associated with all of the appropriate settings and that they all have appropriate values (see the next few paragraphs). If it helps, compare them against all of the values set for a known working system:

     mysql -uroot -p mythconverg
       select * from settings
         where hostname = 'wrkingsys' or hostname = 'newsys'
         order by value asc, hostname asc;

Another reason for the player crashing when you exit from watching a video, recording or live TV, is any of a number of problems with your system's audio configuration. Audio configuration is handled entirely through options in the "settings" table of the database. Once again, comparing the audio settings against those of a known good, working system can be instructive. In this case we look at all systems, since there are not that many options to evaluate:

     mysql -uroot -p mythconverg
       select * from settings
         where value like '%audio%' or value like '%passthru%'
           or value like '%sound%' or value like '%volume%'
           or value like '%mixer%'
         order by value asc, hostname asc;

The values chosen for the "AudioOutputDevice" and the "MixerDevice" are curcial and must be chosen correctly or the internal player will surely crash and leave you to face a blank screen. You might also want to consult the sections on "Sound Problems" and "HDMI Sound", above for further information on getting the audio hardware set up properly.

Remote Controls

Many remote controls are supported directly by Mythbuntu. From years of experience with third party IR receivers, we have learned that the best ones to use (from the user experience perspective) are any of the USB, MCE-based remotes -- those that use the MCE driver lirc_mceusb or just mceusb (for later versions of Mythbuntu such as 12.04). The lirc_mceusb/mceusb driver is loaded into the kernel and therefore responds quickly and reliably to button presses by the user. The instances where the system does not respond to the helm are minimized, thereby maintaining the user's illusion of control. The Home Electro USB Tira-2 also seems to work well. Response to button presses is consistent and unexpected lockups rarely if ever occur.

However, despite warnings against crappy performance, unexpected lockups and other eratic behavior, should you still wish to use one of the other third party IR receivers (e.g. Home Electro serial Ira, or Iguana Works USB IguanaIR), you will need to do some work. Or, if you wish to use your favorite, unsupported remote, you will likewise have your work cut out for you.

For the MCE-based receivers, LIRC supports them via the "default" driver. You merely need to load the correct kernel module via modprobe for the MCE-based receivers to work properly. Typically, this is done automatically by the LIRC startup script, when you choose one of the MCE-based remotes in the config file so there's nothing else to be done. This is especially true for the latest versions of Mythbuntu (such as 12.04), which include, by default, drivers for not only the MCE-based receivers but a large number of other receivers as well.

Despite the fact that many remotes are directly supported by LIRC, you may sitll want or need to change the kernel module used by your current version of LIRC. For example, you may wish to replace the lirc_mceusb kernel driver in version 0.8.6 of LIRC (which comes built in to earlier versions of Mythbuntu), with a newer version of this driver that supports IR blasting for the latest TopSeed and Pinnacle MCE IR receivers. These receivers are readily obtainable on the Internet for a reasonable price but some of them (the 0x0008 version of the TopSeed, for example) have quirks that prevent IR blasting from working without the use of the latest code in lirc_mceusb.

If you have the latest version of Mythbuntu, it probably comes with version 0.9.0 of LIRC built in. It works quite well with many remotes. For earlier versions of Mythbuntu, that don't have the latest LIRC built in, or if you need to build an up-to-date version of LIRC to support some new, bleeding edge remote, you should follow these steps.

To begin, get the latest, packaged source for LIRC from http://www.lirc.org/software.html and prepare to build it in the usual manner. Then, if necessary, either download the new bleeding edge driver source from SourceForge (or wherever else is appropriate) and replace it in the proper subdirectory of the LIRC build tree, or update the latest source with any patches that you wish to make. Be careful that any new driver source that you use is compatible with the LIRC source that you download. The changes found in the latest source in the build tree may render it incompatible with the distributed source.

For instance, the code that adds support for IR blasting using the 0x0008 version of the above noted TopSeed receivers was added to the build tree after major architectural changes had been made that diverged from the 0.8.6 version of LIRC. Thus, to get TopSeed IR blasting to work, the following patch should be applied to the 0.8.6 LIRC source for lirc_mceusb.c:

lirc-0.8.6/drivers/lirc_mceusb/lirc_mceusb.c:

     --- lirc_mceusb-0.8.6.c     2009-09-02 10:04:02.000000000 -0400
     +++ lirc_mceusb-topseed.c   2010-05-19 17:59:01.824157087 -0400
     @@ -184,6 +184,8 @@
             { USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
             /* Topseed eHome Infrared Transceiver /
             { USB_DEVICE(VENDOR_TOPSEED, 0x000a) },
     +       / Topseed eHome Infrared Transceiver /
     +       { USB_DEVICE(VENDOR_TOPSEED, 0x0011) },
             / Ricavision internal Infrared Transceiver /
             { USB_DEVICE(VENDOR_RICAVISION, 0x0010) },
             / Itron ione Libra Q-11 /
     @@ -226,6 +228,12 @@
             { }
      };
 
     +static struct usb_device_id gen3_list[] = {
     +       { USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
     +       { USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
     +       {}
     +};
     +
      static struct usb_device_id pinnacle_list[] = {
             { USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
             {}
     @@ -245,6 +253,7 @@
             { USB_DEVICE(VENDOR_TOPSEED, 0x0007) },
             { USB_DEVICE(VENDOR_TOPSEED, 0x0008) },
             { USB_DEVICE(VENDOR_TOPSEED, 0x000a) },
     +       { USB_DEVICE(VENDOR_TOPSEED, 0x0011) },
             { USB_DEVICE(VENDOR_PINNACLE, 0x0225) },
             {}
      };
     @@ -272,7 +281,7 @@
             unsigned char is_pulse;
             struct {
                     u32 connected:1;
     -               u32 pinnacle:1;
     +               u32 gen3:1;
                     u32 transmitter_mask_inverted:1;
                     u32 microsoft_gen1:1;
                     u32 reserved:28;
     @@ -296,6 +305,12 @@
      static char pin_init2[] = { 0x9f, 0x13};
      static char pin_init3[] = { 0x9f, 0x0d};
 
     +static char DEVICE_RESET[]     = {0x00, 0xff, 0xaa};
     +static char GET_CARRIER_FREQ[] = {0x9f, 0x07};
     +static char GET_RX_TIMEOUT[]   = {0x9f, 0x0d};
     +static char GET_TX_BITMASK[]   = {0x9f, 0x13};
     +static char GET_RX_SENSOR[]    = {0x9f, 0x15};
     +
      #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11)
      static unsigned long usecs_to_jiffies(const unsigned int u)
      {
     @@ -944,8 +959,9 @@
             int i;
             char buf[63], name[128] = "";
             int mem_failure = 0;
     -       int is_pinnacle;
     -       int is_microsoft_gen1;
     +       bool is_gen3;
     +       bool is_microsoft_gen1;
     +       bool is_pinnacle;
 
          dprintk(DRIVER_NAME ": %s called\n", __func__);
 
     @@ -955,10 +971,12 @@
 
          idesc = intf->cur_altsetting;
 
     -       is_pinnacle = usb_match_id(intf, pinnacle_list) ? 1 : 0;
     +       is_gen3 = usb_match_id(intf, gen3_list) ? 1 : 0;
 
          is_microsoft_gen1 = usb_match_id(intf, microsoft_gen1_list) ? 1 : 0;
 
     +       is_pinnacle = usb_match_id(intf, pinnacle_list) ? 1 : 0;
     +
             / step through the endpoints to find first bulk in and out endpoint /
             for (i = 0; i < idesc->desc.bNumEndpoints; ++i) {
                     ep = &idesc->endpoint[i].desc;
     @@ -975,13 +993,14 @@
                                     "found\n");
                             ep_in = ep;
                             ep_in->bmAttributes = USB_ENDPOINT_XFER_INT;
     -                       if (is_pinnacle)
     +                       if (!is_pinnacle)
                                     /
     -                                * setting seems to 1 seem to cause issues with
     -                                * Pinnacle timing out on transfer.
     +                                * Ideally, we'd use what the device offers up,
     +                                * but that leads to non-functioning first and
     +                                * second-gen devices, and many devices have an
     +                                * invalid bInterval of 0. Pinnacle devices
     +                                * don't work witha  bInterval of 1 though.
                                      /
     -                               ep_in->bInterval = ep->bInterval;
     -                       else
                                     ep_in->bInterval = 1;
                     }
 
     @@ -997,13 +1016,14 @@
                                     "found\n");
                             ep_out = ep;
                             ep_out->bmAttributes = USB_ENDPOINT_XFER_INT;
     -                       if (is_pinnacle)
     +                       if (!is_pinnacle)
                                     /
     -                                * setting seems to 1 seem to cause issues with
     -                                * Pinnacle timing out on transfer.
     +                                * Ideally, we'd use what the device offers up,
     +                                * but that leads to non-functioning first and
     +                                * second-gen devices, and many devices have an
     +                                * invalid bInterval of 0. Pinnacle devices
     +                                * don't work witha  bInterval of 1 though.
                                      /
     -                               ep_out->bInterval = ep->bInterval;
     -                       else
                                     ep_out->bInterval = 1;
                     }
             }
     @@ -1103,7 +1123,7 @@
             ir->len_in = maxp;
             ir->overflow_len = 0;
             ir->flags.connected = 0;
     -       ir->flags.pinnacle = is_pinnacle;
     +       ir->flags.gen3 = is_gen3;
             ir->flags.microsoft_gen1 = is_microsoft_gen1;
             ir->flags.transmitter_mask_inverted =
                     usb_match_id(intf, transmitter_mask_list) ? 0 : 1;
     @@ -1136,7 +1156,7 @@
             ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
          / initialize device /
  -       if (ir->flags.pinnacle) {
  +       if (is_pinnacle) {
                  int usbret;
 
                  /
  @@ -1165,6 +1185,38 @@
                  request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND);
                  request_packet_async(ir, ep_out, pin_init3, sizeof(pin_init3),
                                       MCEUSB_OUTBOUND);
  +       }
  +
  +       /* initialize device /
  +       if (ir->flags.gen3) {
  +               request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND);
  +
  +               / device reset /
  +               request_packet_async(ir, ep_out, DEVICE_RESET,
  +                                    sizeof(DEVICE_RESET), MCEUSB_OUTBOUND);
  +               request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND);
  +
  +               / get the carrier and frequency /
  +               request_packet_async(ir, ep_out, GET_CARRIER_FREQ,
  +                                    sizeof(GET_CARRIER_FREQ),
  +                                    MCEUSB_OUTBOUND);
  +               request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND);
  +
  +               / get the transmitter bitmask /
  +               request_packet_async(ir, ep_out, GET_TX_BITMASK,
  +                                    sizeof(GET_TX_BITMASK), MCEUSB_OUTBOUND);
  +               request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND);
  +
  +               / get receiver timeout value /
  +               request_packet_async(ir, ep_out, GET_RX_TIMEOUT,
  +                                    sizeof(GET_RX_TIMEOUT), MCEUSB_OUTBOUND);
  +               request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND);
  +
  +               / get receiver sensor setting /
  +               request_packet_async(ir, ep_out, GET_RX_SENSOR,
  +                                    sizeof(GET_RX_SENSOR), MCEUSB_OUTBOUND);
  +               request_packet_async(ir, ep_in, NULL, maxp, MCEUSB_INBOUND);
  +
          } else if (ir->flags.microsoft_gen1) {
                  / original ms mce device requires some additional setup */
                  mceusb_gen1_init(ir);

Once your have the updated or modified source, build LIRC as follows:

     cd lirc-0.8.6
     ./configure --with-driver=mceusb
     make

Most versions of Mythbuntu install the necessary build environment to allow you to build the mceusb driver from scratch. However, if you get an error message that says "you need to have the Linux kernel source installed for this driver", you may have used the wrong driver name with the configure command (e.g. you used "--with-driver=lirc_mceusb" by mistake, instead of "--with-driver=mceusb") or you may not have the correct build environment installed. If you're sure you didn't use the wrong driver name, you should be able to install what you need with:

     sudo apt-get install build-essential linux-headers-`uname -r`

After the build succeeds, locate the existing LIRC kernel driver with a command something like this (here we're searching for the mceusb driver):

     sudo find /lib -name \*mceusb.ko

Once you find the existing driver, replace it in this fashion (assuming that the existing module is found in the kernel modules tree):

     sudo cp ~/lirc/lirc-0.8.6/drivers/lirc_mceusb/lirc_mceusb.ko \
       /lib/modules/`uname -r`/kernel/ubuntu/lirc/lirc_mceusb

Note that you may also need to replace the lirc_dev module if the new lirc_mceusb module references new symbols in lirc_dev. If that's the case, follow the same steps outlined herein for lirc_mceusb but substitute lirc_dev instead.

Check to see if the original module is loaded by the kernel and, if so, remove it:

     lsmod | grep lirc_mceusb
     sudo rmmod lirc_mceusb

Now, complete the install of the new module on the Mythbuntu machine:

     sudo depmod -a
     sudo insmod \
       /lib/modules/`uname -r`/kernel/ubuntu/lirc/lirc_mceusb/lirc_mceusb.ko

You can check whether the install is successful by doing:

     lsmod | grep lirc_mceusb

After you've completed all of the above, you must make the changes permanent. Mythbuntu boots from a RAM image of the kernel which will still have the old driver (if any) installed and the new driver missing. You need to update this image or the original driver will still get loaded. To update the RAM image:

     sudo update-initramfs -u

Reboot the machine to see if the changes are permanent and that the remote still works:

     sudo reboot

Then, test the updates that you've made accordingly.

Note that for later versions of the kernel and lirc (e.g. 3.2.0 and 0.9.0), mceusb is now one of the kernel drivers. Thus, mceusb.ko is now found in /lib/modules/`uname -r`/kernel/drivers/media/rc and you must build it as a kernel driver instead of as part of lirc. Hopefully, you won't have any need to do so but, if you do, make sure you have the driver build environment (this is not necessarily the full kernel build environment). To verify that you do have the driver build environment, try:

     ls -l /lib/modules/`uname -r`/build

If you have this directory installed, you're good to go (Mythbuntu usually provides them in a typical installation). Otherwise, you'll need to first get the build environment, either using the Package Manager or by doing:

     sudo apt-get install build-essential

Then, you should make sure to install the latest headers for your kernel:

     sudo apt-get install linux-headers-`uname -r`

Finally, if the link doesn't already exist, link the headers to the build folder in the proper place. This should get you compiling:

     sudo ln -s /usr/src/linux-headers-`uname -r` /lib/modules/`uname -r`/build

Download the latest version of the mceusb driver from the kernel sources Web site of your choice and place it in a convenient directory (you can build it in a subdirectory under your home directory, for example lirc_mceusb).

You can find lots of build instructions for kernel drivers on the Internet. Here's a link to a site that covers building the mceusb kernel module:

     http://www.hack-job.org/uncategorized/
          recompile-a-kernel-module-example-mceusb-c/

Apparently, it isn't necessary to place the driver in the system source tree any more, in order to build it (i.e. the way it used to be). Of course, you may opt to do this, if you wish, but we build it in our own directory. To do so, we create this makefile with our favorite editor:

.../lirc_mceusb/Makefile:

     obj-m = mceusb.o
     KVERSION = $(shell uname -r)
     all:
             make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
     clean:
             make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean

Note that the whitespace before each of the indented "make" commands is a single tab, not a bunch of spaces.

Once you have the makefile, you can compile the driver like this:

     cd .../lirc_mceusb
     make

Now, install the mceusb.ko module into the system:

     sudo install -m 744 -c mceusb.ko
          /lib/modules/`uname -r`/kernel/drivers/media/rc

There could be an older version of the module that you are replacing. You can check, for example, if the mceusb module is installed as follows:

     lsmod | grep mceusb

If mceusb is installed then you should remove it:

     sudo rmmod mceusb

Now, complete the install of the new module on the machine:

     sudo depmod -a
     sudo insmod mceusb.ko

You can check whether the install is successful by doing:

     lsmod | grep mceusb

Once you've completed all of the above, you must make the changes permanent. Mythbuntu boots from a RAM image of the kernel which will still have the old driver installed and the new driver missing. You need to update this image or the old driver will still get loaded. To do so, update the RAM image:

     sudo update-initramfs -u

Reboot the machine to make the changes permanent:

     sudo reboot

Then, test the updates that you've made accordingly.

LIRC supports the Tira-2 so Mythbuntu should have support for it built in. You can check whether it does with the following command:

     lircd --driver=?

This will give a list of drivers that are built into the lircd that is installed on the system. If you see "tira", you should be in business and you can skip ahead to the irrecord step, below. However, some versions of Mythbuntu ship without tira being built into LIRC. To remedy this situation, if you don't see the tira driver in the list, you will first need to download the latest LIRC software from http://www.lirc.org/software.html.

Once you've downloaded the software, you can uncompress it and unpack it, then build LIRC with tira enabled:

     cd lirc
     tar -xvjf lirc-0.8.3.tar.bz2
     cd lirc-0.8.3
     ./configure --with-driver=tira
     make

To install the new lircd, become super user and do the install:

     sudo make install

This should put the new lircd in /usr/local/sbin while keeping the original in /usr/sbin -- handy if you need to fall back on the original lircd. You can now skip ahead to the part about using irrecord to record your remote's key codes.

For the Ira-2 or Ira-3 OEM serial IR receivers from Home Electro, the setup is essentially the same as the Tira-2, above. You should check whether Mythbuntu has support for serial devices built in with the following command:

     lircd --driver=?

This will give a list of drivers that are installed on the system. If you see "irman", you should be in business. You can skip ahead to the irrecord step, below. If you don't see the irman driver in the list, in order to get the Ira-2/3 to work, you will first need to download the latest LIRC software from http://www.lirc.org/software.html.

Once you've downloaded the software, you can uncompress it and unpack it, then build LIRC with tira enabled:

     cd lirc
     tar -xvjf lirc-0.8.3.tar.bz2
     cd lirc-0.8.3
     ./configure --with-driver=irman
     make

To install the new lircd, become super user and do the install:

     sudo make install

This should put the new lircd in /usr/local/sbin while keeping the original in /usr/sbin -- handy if you need to fall back on the original lircd. You can now skip ahead to the part about using irrecord to record your remote's key codes.

The Iguana Works USB iguanaIR driver requires a special daemon to operate with LIRC (consider carefully the repercussions on response time and the potential for lockup issues that are implied by this architecture). You can try applying the appropriate RPM or module from their Web site but we have found that we need to compile it ourselves, on Mythbuntu.

To begin with, the daemon needs a whole bunch of prerequisite modules to build properly. On Mythbuntu 9.04, the required modules are:

     python-dev
     libusb-1.0-0
     libusb-1.0-0-dev
     libpopt-dev
     swig

You can install these modules from the Synaptic package manager's GUI or you can use the following command line, once for each package:

     sudo apt-get install pkgname

Once you got all the prerequisites, you can download the latest daemon source from http://iguanaworks.net/downloads.php. After you've done that, uncompress it and unpack it, then build the Iguana daemon:

     cd iguana
     tar -xvjf iguanaIR-1.0pre2.tar.bz2
     cd iguanaIR-1.0pre2
     ./configure
     make

Install the new daemon and other modules into the system:

     sudo make install

At this point, you must reboot, since a new rule is added to /lib/udev/rules.d (named 80-iguanaIR.rules) that creates the /dev/iguanaIR directory and sets its ownership to iguanair:iguanair. This allows the driver to run as user iguanair, not root, which is much safer. However, if you don't reboot, the udev rule will not yet be applied and the next step will fail.

Incidentally, if you experience problems with the responsivness of the remote or just want to be preemptive, you may want to alter the iguanaIR startup script to set the nice level to -3. This will give the daemon a higher priority than other tasks in the system (although a lower priority than the really important ones). Change the lines that set the start parameters as follows:

/etc/init.d/iguanaIR:

.

           .
      # figure out what command to run to start the daemon
      #
      # Set the nice level to -3 so that the remote is more responsive.
      if [ "$LOCKFILE" != "" ]; then 
          if [ ! -e $LOCKFILE ]; then
              START="daemon --user=iguanair -3 $IGPATH $IGUANAIR_OPTIONS \
                  -l $LOGFILE"
          fi
      else
          START="start-stop-daemon --start --chuid iguanair \
              --group iguanair --nicelevel -3 --exec $IGPATH -- \
              $IGUANAIR_OPTIONS -l $LOGFILE"
      fi
           .
           .
           .

Another problem with the startup script is that the Iguana install script sets it up to start in the wrong order. If you use the default installation of LIRC, it will probably start lirc in runlevels 2,3,4,5 at step 19. The Iguana install script sets iguanaIR up to run at step 20. Basically, its a race. Sometimes iguanaIR wins and all is fine. Sometimes lirc beats it to the punch and the remote disappears. Swell.

The fix is to start iguanaIR earlier on, before lirc is even started. You can list the contents of the runlevel 5 directory and see whether the start order is wrong. Enter this command:

     ls -l /etc/rc5.d

If you see:

     /etc/rc5.d/S19lirc --> ./init.d/lirc
     /etc/rc5.d/S20iguanaIR --> ./init.d/iguanaIR

You've got the makings of a race condition. The following commands should fix it:

     sudo rm -f /etc/rc*.d/S20iguanaIR
     sudo ln -s ../init.d/iguanaIR /etc/rc2.d/S15iguanaIR
     sudo ln -s ../init.d/iguanaIR /etc/rc3.d/S15iguanaIR
     sudo ln -s ../init.d/iguanaIR /etc/rc4.d/S15iguanaIR
     sudo ln -s ../init.d/iguanaIR /etc/rc5.d/S15iguanaIR

Note that we picked step 15 in runlevels 2,3,4,5 because there is nothing in between step 15 and step 19 (when lirc is started) that iguanaIR should depend on. If there is, you could change it to start at a later step. You could even move lirc, if you have to. However, starting iguanaIR at step 15 does the trick (eliminating the race) and hasn't caused any side effects as far as we can tell.

Once you've made your changes to the startup script (or not), start up the Iguana daemon:

     sudo /etc/init.d/iguanaIR start

Test it with:

     igclient --receiver-on --sleep 10

You should see commands being sent to the driver and the results being echoed for about 10 seconds, if all is well. If not, proceed to the IguanaWorks troubleshooting page:

     http://iguanaworks.net/projects/IguanaIR/wiki/TroubleShooting

Make sure that the Iguana device driver is started at the proper runlevels (2, 3, 4, and 5). To do this, using the dain-bramaged update-rc.d, run:

     sudo update-rc.d iguanaIR defaults

If you're on a regular system that uses chkconfig, you know what to do.

Now, as noted above for the other drivers, download the latest LIRC software from http://www.lirc.org/software.html, uncompress it and unpack it, then build LIRC with iguanaIR enabled:

     cd lirc
     tar -xvjf lirc-0.8.3.tar.bz2
     cd lirc-0.8.3
     ./configure --with-driver=iguanaIR
     make

To install the new lircd, become super user and do the install:

     sudo make install

Once again, this should put the new lircd in /usr/local/sbin while keeping the original in /usr/sbin where you can get to it if you need to fall back on the original lircd.

Since the new lircd is installed in a different location than the original, we need to modify /etc/init.d/lirc to invoke it. We can choose to do this by adding a new variable called LOAD_PATH that we set to "/usr/local/sbin". We then change all occurrences of /usr/sbin to ${LOAD_PATH}. This lets us change back to the original lircd, if need be.

Also, in some versions of the lirc startup script, it appears that someone forgot about the need to create the /var/run/lirc directory. We can fix this by adding a line in the start routine to create /var/run/lirc.

And, speaking of forgetting things, the hardware.conf file has pointers to two config files, one for the remote and one for the transmitter. Unfortunately, the lircd daemon always loads its config from /etc/lirc/lircd.conf and the two config files pointed to by hardware.conf are ignored. Consequently if you'd like to use two remote config files, one for your actual remote, and one for blasting your cable box, something needs to be done to make up a composite lircd.conf on the fly, using the two named config files (however, you should be careful with this change, if you aren't going to be setting the proper config file name in hardware.conf, since it will break any pre-existing lircd.conf).

Some later versions of lirc create the sockets needed for communication with their client in /var/run/lirc whereas your version of MythTV may expect to find them in /dev. This comes as a huge surprise to MythTV which petulantly refuses to talk to lircd. Consequently, the startup script may need to be modified to always tell lircd to create a pipe named /dev/lircd or /var/run/lirc/lircd instead of where it thinks the pipe should go. Bear this in mind, if all else in your remote setup is perfect and MythTV still won't talk to the remote. The startup script can be made to force the use of one socket name or another, as your MythTV requires.

Finally, you may experience problems with sluggish response from your remote control at times when the system is busy. Since the user typically believes (and who's to argue with them) that the system should always respond promptly to their commands, such sluggish response may not be acceptable. Setting the nice level of lircd to give it a higher priority may help. If you wish to try it, that change can be made in the startup script too.

Here's the complete, modified, startup script:

/etc/init.d/lirc:

     #! /bin/sh
     ### BEGIN INIT INFO
     # Provides:          lirc
     # Required-Start:    $remote_fs $syslog
     # Required-Stop:     $remote_fs $syslog
     # Default-Start:     2 3 4 5
     # Default-Stop:      0 1 6
     # Short-Description: Starts LIRC daemon.
     # Description:       LIRC is used to control different
     #                    infrared receivers and transceivers.
     ### END INIT INFO
     # Where we load lircd and lircmd from.
     LOAD_PATH=/usr/sbin
     # LOAD_PATH=/usr/local/sbin
     # The old name where lirc used to put its socket.  Some programs may still
     # look there.
     #
     # If this variable is defined, a symlink will be made when lircd is started
     # and removed when it is stopped.
     OLD_SOCKET="/dev/lircd"
     load_modules ()
     {
         local MODULES_MISSING=false
      log_daemon_msg "Loading LIRC modules"
      for mod in $*; do
          if [ $mod = "udev" ]; then
              log_end_msg 0
              log_success_msg "Restarted via udev, don't reload modules"
              break
          else
              modprobe $mod 2> /dev/null || MODULES_MISSING=true
          fi
      done
      log_end_msg $?
      if $MODULES_MISSING; then
          log_failure_msg "Unable to load LIRC kernel modules. Verify your"
          log_failure_msg "selected kernel modules in /etc/lirc/hardware.conf"
          START_LIRCMD=false
          START_LIRCD=false
      fi

}

     build_remote_args ()
     {
         local REMOTE_ARGS="$*"
      #For remote only detection support, we need
      #both REMOTE_DEVICE and TRANSMITTER_DEVICE undefined
      if [ -z "$REMOTE_DEVICE" ] && [ -z "$TRANSMITTER_DEVICE" ]; then
          for dev in /dev/lirc0; do
              if [ -c $dev ]; then
                  REMOTE_DEVICE="$dev"
                  break
              fi
          done
      fi
      #If we have a REMOTE_DEVICE or REMOTE_DRIVER defined (either because
      #no devices were defined, OR if we explicitly did), then populate
      #REMOTE_ARGS
      if [ ! -z "$REMOTE_DEVICE" ] || [ ! -z "$REMOTE_DRIVER" ]; then
          if [ -n "$REMOTE_DEVICE" ] && [ "$REMOTE_DEVICE" != "none" ]; then
              REMOTE_ARGS="--device=$REMOTE_DEVICE $REMOTE_ARGS"
          fi
          if [ -n "$REMOTE_DRIVER" ] && [ "$REMOTE_DRIVER" != "none" ]; then
              REMOTE_ARGS="--driver=$REMOTE_DRIVER $REMOTE_ARGS"
          fi
          #Now, if we ALSO have a transmitter defined, add some args
          #To make the first lircd listen up
          if [ ! -z "$TRANSMITTER_DEVICE" ] \
              || [ ! -z "$TRANSMITTER_DRIVER" ]; then
              REMOTE_ARGS="$REMOTE_ARGS --listen"
          fi
          #Because there's some confusion with locally-compiled versions of
          #lircd over what our pipe name is, let's make sure we're all
          #talking on the same one.
          REMOTE_ARGS="$REMOTE_ARGS --output=$REMOTE_SOCKET"
      fi
    
      echo $REMOTE_ARGS

}

     build_transmitter_args ()
     {
         local TRANSMITTER_ARGS="$*"
      #Transmitters must be explicitly be defined
      if [ ! -z "$TRANSMITTER_DEVICE" ] \
          || [ ! -z "$TRANSMITTER_DRIVER" ]; then
          if [ -n "$TRANSMITTER_DEVICE" ] \
              && [ "$TRANSMITTER_DEVICE" != "none" ]; then
              TRANSMITTER_ARGS="--device=$TRANSMITTER_DEVICE $TRANSMITTER_ARGS"
          fi
          if [ -n "$TRANSMITTER_DRIVER" ] \
              && [ "$TRANSMITTER_DRIVER" != "none" ]; then
              TRANSMITTER_ARGS="--driver=$TRANSMITTER_DRIVER $TRANSMITTER_ARGS"
          fi
          # Now, if we ALSO have a remote defined, add some args
          # to make the second lircd connect.
          if [ ! -z "$REMOTE_DEVICE" ] || [ ! -z "$REMOTE_DRIVER" ]; then
              TRANSMITTER_ARGS="$TRANSMITTER_ARGS \
                  --output=$TRANSMITTER_SOCKET --connect=localhost:8765 \
                  --pidfile=/var/run/lircd1.pid"
          # Otherwise, because there's some confusion with locally-compiled
          # versions of lircd over what our pipe name is, let's make sure
          # we're all talking on the same one.
          else
              TRANSMITTER_ARGS="$TRANSMITTER_ARGS --output=$TRANSMITTER_SOCKET"
          fi
      fi
      echo $TRANSMITTER_ARGS

}

     in_kernel_support()
     {
         if [ -d /sys/class/rc ]; then
             for file in `find /sys/class/rc/*/ -name protocols`; do
                 if [ "$1" = "disable" ]; then
                     echo "lirc" > $file
                 else
                     echo "none" > $file
                     for protocol in `cat $file`; do
                         echo "+${protocol}" > $file
                     done
                 fi
             done
         fi
     }
     . /lib/lsb/init-functions
     test -f ${LOAD_PATH}/lircd || exit 0
     test -f ${LOAD_PATH}/lircmd || exit 0
     START_LIRCMD=true
     START_LIRCD=true
     START_IREXEC=true
     if [ -f /etc/lirc/hardware.conf ];then
         . /etc/lirc/hardware.conf
     fi
     # The hardware.conf file has pointers to two config files, one for the
     # remote and one for the transmitter.  Unfortunately, the lircd daemon
     # always loads its config from /etc/lirc/lircd.conf and the two config files
     # pointed to by hardware.conf are ignored.  Nice, huh?  Consequently, we
     # make up lircd.conf on the fly, here, from the two named config files.
     if [ -n "$1" ] && [ "$1" = "start" ]; then
         rm -f /etc/lirc/lircd.conf >/dev/null 2>&1
      if [ -n "$REMOTE_LIRCD_CONF" ] \
          && [ "$REMOTE_LIRCD_CONF" != "none" ]; then
          cat $REMOTE_LIRCD_CONF >/etc/lirc/lircd.conf
          if [ -n "$TRANSMITTER_LIRCD_CONF" ] \
              && [ "$TRANSMITTER_LIRCD_CONF" != "none" ]; then
              cat $TRANSMITTER_LIRCD_CONF >>/etc/lirc/lircd.conf
          fi
      else
          if [ -n "$TRANSMITTER_LIRCD_CONF" ] \
              && [ "$TRANSMITTER_LIRCD_CONF" != "none" ]; then
              cat $TRANSMITTER_LIRCD_CONF >/etc/lirc/lircd.conf
          fi
      fi
      # Here we test to see if anyone has configured the lircd.conf file.  If
      # we made one up (above), it should be configured.  If not, there may
      # be a default one that was put there by install.  It is possible that
       the user configured this file.  If not, we don't start lirc.
      if [ ! -f /etc/lirc/lircd.conf ] \
          || grep -q "^UNCONFIGURED"  /etc/lirc/lircd.conf;then
          if [ "$1" = "start" ]; then
              log_success_msg "No valid /etc/lirc/lircd.conf has been found."
              log_success_msg "Remote control support has been disabled."
              log_success_msg "Reconfigure LIRC or manually replace \
                  /etc/lirc/lircd.conf to enable."
          fi
          START_LIRCD=false
          START_LIRCMD=false
          START_IREXEC=false
      fi

fi

     # Here we test to see if anyone has configured the lircmd.conf file.  If
      not, we don't start lircmd.
     if [ ! -f /etc/lirc/lircmd.conf ] \
         || grep -q "^UNCONFIGURED" /etc/lirc/lircmd.conf; then
         START_LIRCMD=false
     fi
     # Here we test to see if anyone has configured the lircrc.conf file.  If
      not, we don't start irexec.
     if [ ! -f /etc/lirc/lircrc ] \
         || grep -q "^UNCONFIGURED" /etc/lirc/lircrc; then
         START_IREXEC=false
     fi
     # The user can define which pipe path to use.  The default is /var/run/lirc
     # but this can be overridden.
     if [ -n "$PIPE_PATH" ] && [ "$PIPE_PATH" != "none" ]; then
         OUTPUT_PATH=$PIPE_PATH
     else
         OUTPUT_PATH="/var/run/lirc"
     fi
     # The user can define what socket names to use.  The defaults are "lirc"
     # and "lirc1".
     if [ -z "$REMOTE_SOCKET" ]; then
         REMOTE_SOCKET="${OUTPUT_PATH}/lircd"
     else
         REMOTE_SOCKET="${OUTPUT_PATH}/${REMOTE_SOCKET}"
     fi
     if [ -z "$TRANSMITTER_SOCKET" ]; then
         TRANSMITTER_SOCKET="${OUTPUT_PATH}/lircd"
      # Now, if we ALSO have a remote defined, change the default
      # transmitter socket.
      if [ ! -z "$REMOTE_DEVICE" ] || [ ! -z "$REMOTE_DRIVER" ]; then
          TRANSMITTER_SOCKET="${TRANSMITTER_SOCKET}1"
      fi
  else
      TRANSMITTER_SOCKET="${OUTPUT_PATH}/${TRANSMITTER_SOCKET}"

fi

     # Process the command given to this script (e.g. start, stop).
     case "$1" in
      # Start up all of the daemons.
      start)
          if [ "$LOAD_MODULES" = "true" ] && [ "$START_LIRCD" = "true" ]; then
              load_modules $2 $REMOTE_MODULES $TRANSMITTER_MODULES $MODULES
              in_kernel_support "disable"
          fi
          # If we're starting the lirc daemon, do it now.
          if [ "$START_LIRCD" = "true" ]; then
              # If the socket/pid directory isn't there, create it.
              if [ ! -d $OUTPUT_PATH ]; then
                  mkdir -p $OUTPUT_PATH >/dev/null 2>&1
              fi
              log_daemon_msg "Starting remote control daemon(s) : LIRC "
              REMOTE_LIRCD_ARGS=`build_remote_args $REMOTE_LIRCD_ARGS`
              TRANSMITTER_LIRCD_ARGS=`build_transmitter_args \
                  $TRANSMITTER_LIRCD_ARGS`
              # If we have a remote defined, it is the primary process
              #
              # We'll set the nice level of this process so that the remote
              # control is more responsive.
              if [ ! -z "$REMOTE_LIRCD_ARGS" ]; then
                  start-stop-daemon --start --quiet --nicelevel -5 \
                      --exec ${LOAD_PATH}/lircd -- $REMOTE_LIRCD_ARGS \
                      </dev/null
                  log_end_msg $?
                  # If an old socket is named, symlink it to the one that lirc
                  # is using now.  Note that, because of the "&&", the symlink
                  # is only put in if the old socket exists.
                  if [ -S "$REMOTE_SOCKET" \
                      -a "$OLD_SOCKET" != "$REMOTE_SOCKET" ]; then
                      rm -f $OLD_SOCKET \
                          && ln -s $REMOTE_SOCKET $OLD_SOCKET
                  fi
                  # Now, if we additionally have a transmitter defined, it
                  # is secondary process.
                  if [ ! -z "$TRANSMITTER_LIRCD_ARGS" ]; then
                      ${LOAD_PATH}/lircd $TRANSMITTER_LIRCD_ARGS < /dev/null
                      # If an old socket is named, symlink it to the one that
                      # lirc is using now.  Note that, because of the "&&",
                      # the symlink is only put in if the old socket exists.
                      if [ -S "$TRANSMITTER_SOCKET" ]; then
                          rm -f ${OLD_SOCKET}1 \
                              && ln -s $TRANSMITTER_SOCKET ${OLD_SOCKET}1
                      fi 
                  fi
              # Otherwise, if there's a transmitter defined, it is the
              # primary process.
              elif [ ! -z "$TRANSMITTER_LIRCD_ARGS" ]; then
                  start-stop-daemon --start --quiet \
                      --exec ${LOAD_PATH}/lircd -- $TRANSMITTER_LIRCD_ARGS \
                      </dev/null
              # Otherwise, we're done.
              else
                  log_end_msg 1
              fi
          fi
          # If we're starting the mouse daemon, do it now.
          if [ "$START_LIRCMD" = "true" ]; then
              # If the socket/pid directory isn't there, create it.
              if [ ! -d $OUTPUT_PATH ]; then
                  mkdir -p $OUTPUT_PATH >/dev/null 2>&1
              fi
              log_daemon_msg "Starting remote control mouse daemon : LIRCMD "
              start-stop-daemon --start --quiet \
                  --exec ${LOAD_PATH}/lircmd </dev/null
              log_end_msg $?
          fi
          # If we're starting the execution daemon, do it now.
          if [ "$START_IREXEC" = "true" ]; then
              # If the socket/pid directory isn't there, create it.
              if [ ! -d $OUTPUT_PATH ]; then
                  mkdir -p $OUTPUT_PATH >/dev/null 2>&1
              fi
              log_daemon_msg "Starting execution daemon: irexec"
              start-stop-daemon --start --quiet --oknodo \
                  --exec ${LOAD_PATH}/irexec -- -d /etc/lirc/lircrc \
                  </dev/null
              log_end_msg $?
          fi
          ;;
      # Shut down all of the daemons.
      stop)
          in_kernel_support "enable"
          # If we're started the execution daemon, do it now.
          if [ "$START_IREXEC" = "true" ]; then
              log_daemon_msg "Stopping execution daemon: irexec"
              start-stop-daemon --stop --quiet --exec ${LOAD_PATH}/irexec
              log_end_msg $?
          fi
          # If we're started the mouse daemon, do it now.
          if $START_LIRCMD; then
              log_daemon_msg "Stopping remote control mouse daemon: LIRCMD"
              start-stop-daemon --stop --quiet --exec ${LOAD_PATH}/lircmd
              log_end_msg $?
          fi
          # If we're started the lirc daemon, do it now.
          if $START_LIRCD; then
              log_daemon_msg "Stopping remote control daemon(s): LIRC"
              start-stop-daemon --stop --quiet --exec ${LOAD_PATH}/lircd
              log_end_msg $?
          fi
          ;;
      # Reload signals all of the daemons to reload their config.
      reload|force-reload)
          if [ "$START_IREXEC" = "true" ]; then
              start-stop-daemon --stop --quiet --signal 1 \
                  --exec ${LOAD_PATH}/irexec
          fi
          if [ "$START_LIRCD" = "true" ]; then
              start-stop-daemon --stop --quiet --signal 1 \
                  --exec ${LOAD_PATH}/lircd
          fi
          if $START_LIRCMD; then
              start-stop-daemon --stop --quiet --signal 1 \
                  --exec ${LOAD_PATH}/lircmd
          fi
          ;;
      # Restarts the service by shutting everything down and then starting
      # it back up.
      #
      # Note that, when we restart, we pass parameter $2, which is possibly
      # our udev paramater.
      restart)
          $0 stop
          $0 start $2
          ;;
      *)
          echo "Usage: /etc/init.d/lircd {start|stop|reload|restart|\
              force-reload}"
          exit 1

esac

     exit 0

For later versions of Mythbuntu, many of the services that are necessary to run the system have been migrated to upstart. Fortunately for us, as of Mythbuntu 12.04, this hasn't happened to LIRC yet. So, the script that is shown above can still be used with the latest Mythbuntu. As a matter of fact, you can probably just use the LIRC that is pre-installed on the system (no need to build the latest one because the OS probably comes with the latest one). To do this, you simply have to switch the load path as follows:

     # Where we load lircd and lircmd from.
     LOAD_PATH=/usr/sbin
     # LOAD_PATH=/usr/local/sbin

If your system already had the appropriate driver built into lircd or you've successfully installed the updated LIRC software, its time to record all of the key codes that are generated by the remote that you wish to use with Mythbuntu. These steps are repeated for each remote that you wish to use or every time that you add a new remote.

Begin by making sure that lircd is not running (if you are not doing this for the first time) and then record the buttons as follows (picking the appropriate invocation of irrecord, depending on which IR receiver you are using, and being sure to use the correct installation of irrecord, if you built the source from scratch):

     [sudo /etc/init.d/lirc stop]
     sudo irrecord -n MCEUSB_myremote.conf
     sudo irrecord -n -H tira -d /dev/ttyUSB0 Tira-2_myremote.conf
     sudo irrecord -n -H irman -d /dev/ttyS0 Ira_myremote.conf
     sudo irrecord -n -H iguanaIR -d /dev/iguanaIR/0 Iguana_myremote.conf

If you have problems with irrecord recognizing the keys on your remote, you can run it in raw mode and then deal with the problems post-facto:

     [sudo /etc/init.d/lirc stop]
     sudo irrecord -f -n MCEUSB_myremote.conf
     sudo irrecord -f -n -H tira -d /dev/ttyUSB0 Tira-2_myremote.conf
     sudo irrecord -f -n -H irman -d /dev/ttyS0 Ira_myremote.conf
     sudo irrecord -f -n -H iguanaIR -d /dev/iguanaIR/0 Iguana_myremote.conf

Essentially, once you're running irrecord, you should follow its instructions. Be sure to carry out the first steps exactly (i.e. keep pressing keys or holding down a single key, as it instructs, until it tells you to stop) so that the correct gap is found and irrecord figures out how to decode the raw data. Also, at the end, press a single key rapidly so that the toggle bits can be figured out. If you fail to do these tasks properly, the remote will not be set up correctly.

Incidentally, there may be a problem when some remotes are being recorded by some IR receivers (e.g. the Sony TiVo remotes with any of the irman serial receivers). In these cases, irrecord asks you to press and hold a single key until it can figure out the correct gap. However, this depends on the remote's key being typematic (i.e. repeats automatically at a rapid rate, when held). If the "arbitrary" key that you hold down isn't typematic or doesn't repeate at a fast enough rate, irrecord won't be able to figure things out. To get it to work, you need to pick a key that is typematic and repeats fast enough (you should see a good stream of dots forming in short order). Often, the volume controls on a remote (if it has them) are typematic and work quite well when irrecord asks you to hold down an "arbitrary" key.

Once the initial phase of remote setup is completed, irrecord proceeds to capturing each of the remote's key codes. For each of the keys, you enter the key name on the computer's keyboard, press the enter key, and then press the remote's key and hold it until irrecord can identify its key code and record it. Try to give the keys meaningful names that can be used in the various LIRC config files.

If you want the remote to work with other applications (especially the script that auto-generates the MythTV config files -- you'll thank me for this later), pick the common key names from this list:

     ArrowDown
     ArrowLeft
     ArrowRight
     ArrowUp
     ChannelUp
     ChannelDown
     Eight  (the number 8)
     Enter
     Exit
     Five  (the number 5)
     Forward
     Four  (the number 4)
     Guide
     Home
     Info
     List
     Menu
     Mute
     Nine  (the number 9)
     One  (the number 1)
     Pause
     Play
     Power
     Record
     Replay
     Return
     Rewind
     Seven  (the number 7)
     Six  (the number 6)
     Skip
     Stop
     Three  (the number 3)
     Two  (the number 2)
     VolumeDown
     VolumeUp
     Zero  (the number 0)

For other keys that don't appear on this list, you can examine one or more .lircrc files (e.g. for your favorite application) to see what names are common. The names that you choose will be used to map the LIRC keypress codes to your application's control commands so making them meaningful is a good idea. Also, it is best to know what names you'll be using for all of the remote's keys before you begin so that you won't have to go looking once you start. Just for the sake of having a plan, I usually start with the top-left key on the remote and work my way down to the bottom-right so having the key names printed out in that order is helpful.

Once you have recorded your remote or remotes, you should join all of the config files together, for all of the remotes that you wish to use simultaneously, into a single lircd.conf file in /etc/lirc. It should look something like this (let's assume we want to use either the Sony or the Philips TiVo remote, or the Samsung TV remote to run Mythbuntu, depending on which one is closer to hand):

/etc/lirc/lircd.conf:

     # ========================  Tira-2_TiVoSony.conf  ==========================
     # Please make this file available to others
     # by sending it to <lirc@bartelmus.de>
     #
     # this config file was automatically generated
     # using lirc-0.8.3(tira) on Thu May 15 13:21:08 2008
     #
     # contributed by: xxx@yyy.com (Xxx Yyy)
     #
     # brand: Home Electro Tira-2 xceiver
     # model no. of remote control: TiVo (Sony) (RMT-V303)
     # devices being controlled by this remote: MythTV (Mythbuntu)
     #
     begin remote
     name  TiVoSony
     bits           48
     eps            30
     aeps          100
     one             0     0
     zero            0     0
     pre_data_bits   8
     pre_data       0x0
     post_data_bits  8
     post_data      0x0
     gap          149967
     toggle_bit_mask 0x0
        begin codes
            Power                    0xC0FF49BF5EC3
            TVPower                  0xFF3C75000000  # Programmable by user
            Menu                     0xC003748C5DC3  # TiVo logo on button
            Guide                    0xC0C3B7735DC3
            List                     0xC00F874F5DC3
            UpArrow                  0xC0F348835DC3
            DownArrow                0xC003964352C3
            LeftArrow                0xC003974F51C3
            RightArrow               0xC00386735EC3
            Select                   0xC0F358B351C3
            ThumbsDown               0xC0C3B67F5EC3
            ThumbsUp                 0xC0C3A64F52C3
            Mute                     0xFF3F65000000  # TiVo logo on button
            Record                   0xC0FF8A8F5EC3
            Play                     0xC0FFAB7051C3
            Back                     0xC0FFBB405DC3
            Forward                  0xC0FF9ABF52C3
            Pause                    0xC0FFBA4C5EC3
            Slow                     0xC00F447F5DC3
            Replay                   0xC0F378405DC3
            Skip                     0xC0C3A74351C3
            VolumeUp                 0xFF3F54000000  # TiVo logo on button
            VolumeDown               0xFF3F44000000  # TiVo logo on button
            ChannelUp                0xC0FF694C52C3
            ChannelDown              0xC0FF797C5EC3
            One                      0xC03F594052C3
            Two                      0xC03F49705EC3
            Three                    0xC03F584C51C3
            Four                     0xC03F487C5DC3
            Five                     0xC03F698352C3
            Six                      0xC03F79B35EC3
            Seven                    0xC03F688F51C3
            Eight                    0xC03F78BF5DC3
            Nine                     0xC03F9A7052C3
            Zero                     0xC03F8A405EC3
            Clear                    0xC003877F5DC3
            Enter                    0xC03F8B4C5DC3
        end codes
     end remote
     # =======================  Tira-2_TiVoPhilips.conf  ========================
     # Please make this file available to others
     # by sending it to <lirc@bartelmus.de>
     #
     # this config file was automatically generated
     # using lirc-0.8.3(tira) on Thu May 15 06:22:55 2008
     #
     # contributed by: xxx@yyy.com (Xxx Yyy)
     #
     # brand: Home Electro Tira-2 xceiver
     # model no. of remote control: TiVo (Philips) Peanut (SBOM-00004-000)
     # devices being controlled by this remote: MythTV (Mythbuntu)
     #
     begin remote
     name  TiVoPhilips
     bits           48
     eps            30
     aeps          100
     one             0     0
     zero            0     0
     pre_data_bits   8
     pre_data       0x0
     post_data_bits  8
     post_data      0x0
     gap          207966
     min_repeat      2
     toggle_bit_mask 0x0
        begin codes
            Power                    0xFF3C75000000  # Programmable by user
            Menu                     0xA914FDFF5FFF  # TiVo logo on button
            Guide                    0x29147D7F5FFF
            UpArrow                  0x29147DF75FFF
            DownArrow                0x29147DD75FFF
            LeftArrow                0x29147D575FFF
            RightArrow               0x29147D775FFF
            Select                   0x29147D7D5FFF
            ThumbsDown               0x29147DFD5FFF
            ThumbsUp                 0x29147DDD5FFF
            Mute                     0xFF3C65000000  # Programmable by user
            Record                   0x8914DDFF5FFF
            Play                     0x8914DD7F5FFF
            Back                     0x8914DDDF5FFF
            Forward                  0x8914DDF75FFF
            Pause                    0x8914DD5F5FFF
            Slow                     0x8914DD775FFF
            Replay                   0x8914DDD75FFF
            Skip                     0x8914DD575FFF
            VolumeUp                 0xFF3C54000000  # Programmable by user
            VolumeDown               0xFF3C44000000  # Programmable by user
            ChannelUp                0x29147DD55FFF
            ChannelDown              0x29147D555FFF
            One                      0x8914DDFD5FFF
            Two                      0x8914DD7D5FFF
            Three                    0x8914DDDD5FFF
            Four                     0x8914DD5D5FFF
            Five                     0x8914DDF55FFF
            Six                      0x8914DD755FFF
            Seven                    0x8914DDD55FFF
            Eight                    0x8914DD555FFF
            Nine                     0x09145DFF5FFF
            Zero                     0x09145D7F5FFF
            Clear                    0x09145DDF5FFF
            Enter                    0x09145D5F5FFF
        end codes
     end remote
     # =====================  Tira-2_SamsungLN32A450.conf  ======================
     # Please make this file available to others
     # by sending it to <lirc@bartelmus.de>
     #
     # this config file was automatically generated
     # using lirc-0.8.4a(tira) on Sat Jan 23 19:28:51 2010
     #
     # contributed by: xxx@yyy.com (Xxx Yyy)
     #
     # brand: Home Electro USB Tira-2
     # model no. of remote control: Samsung LN32A450 TV (BN59-00687A)
     # devices being controlled by this remote: MythTV (Mythbuntu)
     #
     # Codes marked with "x" should not be used because the display interprets
     # them under all conditions (e.g. Power).
     #
     # Codes marked with "*" can be used but the display pops up an annoying
     # idiot message about the key not being available right now.  These keys
     # are good for displaying things like the OSD (i.e. something that will
     # hang around for awhile until the annoying message goes away).
     #
     # Codes marked with "M" work OK but they actually do something when the
     # Menu button is pressed and the Menu is displayed.  If you map these keys,
     # you probably should exit your application before you enter the display's
     # Menu.
     #
     begin remote
     name  SamsungLN32A450
     bits            48
     eps             30
     aeps            100
     one             0     0
     zero            0     0
     pre_data_bits   8
     pre_data        0x0
     post_data_bits  8
     post_data       0x0
     gap             207962
     min_repeat      1
     toggle_bit_mask 0x0
        begin codes
            Power                    0xFF17FC9FFF07    # x
            TVMode                   0x7F907D18FE07    # x
            Source                   0xFFF7FD7FFE07    # x
            One                      0xFF6FFCE7FF07    # *
            Two                      0xFFEFFD67FE07    # *
            Three                    0xFF0FFC87FF07    # *
            Four                     0xFF71FCF9FF07    # *
            Five                     0xFFF1FD79FE07    # *
            Six                      0xFF11FC99FF07    # *
            Seven                    0xFF69FCE1FF07    # *
            Eight                    0xFFE9FD61FE07    # *
            Nine                     0xFF09FC81FF07    # *
            Zero                     0x7FF67D7EFE07    # *
            Minus                    0x9F979D1FFE07    # *
            Previous                 0x7F967D1EFE07    # *  - Pre-Ch button
            VolumeUp                 0xFF8FFD07FE07    # x
            VolumeDown               0xFF91FD19FE07    # x
            Mute                     0xFF89FD01FE07    # x
            ChannelUp                0x7F167C9EFF07    # x
            ChannelDown              0x7F767CFEFF07    # x
            List                     0x87918519FE07    # *  - Ch. List button
            Menu                     0x7F107C98FF07    # x
            ClosedCaption            0x9FEF9D67FE07    # *  - CC button
            Tools                    0xE791E519FE07    # x  - Tools button
            Info                     0x7F887D00FE07    # x
            Return                   0x677064F8FF07    # M  - Return button
            Exit                     0x9FE99D61FE07    # xM
            ArrowUp                  0x877784FFFF07    # M  - In circular
                                                       #       button cluster
            ArrowDown                0x87F7857FFE07    # M
            ArrowLeft                0x87EF8567FE07    # M
            ArrowRight               0x8717849FFF07    # M
            Enter                    0x877184F9FF07    # M
            Red                      0x876984E1FF07    # Red button
            Green                    0x7F6E7CE6FF07    # Green button
            Yellow                   0x7FEE7D66FE07    # Yellow button
            Blue                     0x7F0E7C86FF07    # Blue button
            SRSButton                0x87098481FF07    # x  - SRS button
            MTSButton                0xFF77FCFFFF07    # x  - MTS button
            DMAButton                0x8797851FFE07    # x  - DMA button
            EMode                    0x796E7AE6FF07    # x  - E. Mode button
            PSize                    0x1F081C80FF07    # x  - P. Size button
            FavoriteChannel          0xE76FE4E7FF07    # x  - Fav. Ch. button
            Rewind                   0xE7EFE567FE07
            Pause                    0xE711E499FF07
            FastForward              0xE771E4F9FF07
            Record                   0xE7F1E579FE07
            Play                     0xE78FE507FE07
            Stop                     0xE70FE487FF07
        end codes
     end remote

As long as the codes are different for each remote, you can have as many remotes defined as you want. LIRC will figure out which one is being used by the codes that it receives. Thus, you can control one system with several remotes, if you're that ambitious.

LIRC needs a hardware configuration file to tell it what remote and IR blaster drivers to use, etc. This file should be set up now and should look something like this (the combined file, above, is used with a USB Tira-2):

/etc/lirc/hardware.conf:

     # /etc/lirc/hardware.conf
     #
     #Chosen Remote Control
     REMOTE="Combined"
     REMOTE_MODULES=""
     REMOTE_DRIVER="tira"
     REMOTE_DEVICE="/dev/ttyUSB0"
     REMOTE_LIRCD_CONF="/etc/lirc/lircd.conf"
     REMOTE_LIRCD_ARGS=""
     #Chosen IR Transmitter
     TRANSMITTER="None"
     TRANSMITTER_MODULES=""
     TRANSMITTER_DRIVER=""
     TRANSMITTER_DEVICE=""
     TRANSMITTER_LIRCD_CONF=""
     TRANSMITTER_LIRCD_ARGS=""
     #Enable lircd
     START_LIRCD="true"
     #Don't start lircmd even if there seems to be a good config file
     #START_LIRCMD="false"
     #Try to load appropriate kernel modules
     LOAD_MODULES="false"
     # Default configuration files for your hardware if any
     LIRCMD_CONF=""
     #Forcing noninteractive reconfiguration
     #If lirc is to be reconfigured by an external application
     #that doesn't have a debconf frontend available, the noninteractive
     #frontend can be invoked and set to parse REMOTE and TRANSMITTER
     #It will then populate all other variables without any user input
     #If you would like to configure lirc via standard methods, be sure
     #to leave this set to "false"
     FORCE_NONINTERACTIVE_RECONFIGURATION="false"
     START_LIRCMD=""

As another example, the hardware.conf file for a Samsung LN32A450 remote, used with a USB IguanaIR, should include this section for the remote:

     #Chosen Remote Control
     REMOTE="SamsungLN32A450"
     REMOTE_MODULES=""
     REMOTE_DRIVER="iguanaIR"
     REMOTE_DEVICE="/dev/iguanaIR/0"
     REMOTE_LIRCD_CONF="/etc/lirc/lircd.conf"
     REMOTE_LIRCD_ARGS=""

Finally, in this example a singel Philips TiVo remote is used with a serial Ira:

     #Chosen Remote Control
     REMOTE="TiVoPhilips"
     REMOTE_MODULES=""
     REMOTE_DRIVER="irman"
     REMOTE_DEVICE="/dev/ttyS0"
     REMOTE_LIRCD_CONF="/etc/lirc/lircd.conf"
     REMOTE_LIRCD_ARGS=""

If you want, you can give your config files meaningful names, based on the remote or class of remotes that they represent and then copy those files to the /etc/lirc directory, whereupon they can be symlinked to the proper file names. For example:

     sudo ln -s Ira_TiVoPhilips-hardware.conf hardware.conf
     sudo ln -s TiVoRemotes-lircd.conf lircd.conf

Incidentally, if you made the modifications to /etc/init.d/lirc, mentioned above, to allow the hardware.conf file to correctly specify which lircd config file should be used for the receiver and transmitter, you can have descriptions for the same remote under different receivers, in different files, and select them in the config file. For example, here's the same Samsung LN34A450 remote (shown in the combined file, above) as it would appear to an Iguana Works receiver:

/etc/lirc/IguanaIR_SamsungLN32A450.conf:

     # ====================  IguanaIR_SamsungLN32A450.conf  =====================
     # Please make this file available to others
     # by sending it to <lirc@bartelmus.de>
     #
     # this config file was automatically generated
     # using lirc-0.8.6(iguanaIR) on Fri Jan 22 14:30:37 2010
     #
     # contributed by: xxx@yyy.com (Xxx Yyy)
     #
     # brand: Iguana Works USB iguanaIR
     # model no. of remote control: Samsung LN32A450 TV (BN59-00687A)
     # devices being controlled by this remote: MythTV (Mythbuntu)
     #
     # Codes marked with "x" should not be used because the display interprets
     # them under all coditions (e.g. Power).
     #
     # Codes marked with "*" can be used but the display pops up an annoying
     # idiot message about the key not being available right now.  These keys
     # are good for displaying things like the OSD (i.e. something that will
     # hang around for awhile until the annoying message goes away).
     #
     # Codes marked with "M" work OK but they actually do something when the
     # Menu button is pressed and the Menu is displayed.  If you map these keys,
     # you probably should exit your application before you enter the display's
     # Menu.
     #
     begin remote
     name  SamsungLN32A450
     bits            16
     flags           SPACE_ENC
     eps             30
     aeps            100
     header          4529 4418
     one             586  1625
     zero            586  498
     ptrail          585
     pre_data_bits   16
     pre_data        0xE0E0
     gap             46780
     min_repeat      1
     toggle_bit_mask 0x0
        begin codes
            Power                    0x40BF    # x
            TVMode                   0xD827    # x
            Source                   0x807F    # x
            One                      0x20DF    # *
            Two                      0xA05F    # *
            Three                    0x609F    # *
            Four                     0x10EF    # *
            Five                     0x906F    # *
            Six                      0x50AF    # *
            Seven                    0x30CF    # *
            Eight                    0xB04F    # *
            Nine                     0x708F    # *
            Zero                     0x8877    # *
            Minus                    0xC43B    # *
            Previous                 0xC837    # *  - Pre-Ch button
            VolumeUp                 0xE01F    # x
            VolumeDown               0xD02F    # x
            Mute                     0xF00F    # x
            ChannelUp                0x48B7    # x
            ChannelDown              0x08F7    # x
            List                     0xD629    # *  - Ch. List button
            Menu                     0x58A7    # x
            ClosedCaption            0xA45B    # *  - CC button
            Tools                    0xD22D    # x  - Tools button
            Info                     0xF807    # x
            Return                   0x1AE5    # M  - Return button
            Exit                     0xB44B    # xM
            ArrowUp                  0x06F9    # M  - In circular button
                                               #      cluster
            ArrowDown                0x8679    # M
            ArrowLeft                0xA659    # M
            ArrowRight               0x46B9    # M
            Enter                    0x16E9    # M
            Red                      0x36C9    # Red button
            Green                    0x28D7    # Green button
            Yellow                   0xA857    # Yellow button
            Blue                     0x6897    # Blue button
            SRSButton                0x7689    # x  - SRS button
            MTSButton                0x00FF    # x  - MTS button
            DMAButton                0xC639    # x  - DMA button
            EMode                    0x29D6    # x  - E. Mode button
            PSize                    0x7C83    # x  - P. Size button
            FavoriteChannel          0x22DD    # x  - Fav. Ch. button
            Rewind                   0xA25D
            Pause                    0x52AD
            FastForward              0x12ED
            Record                   0x926D
            Play                     0xE21D
            Stop                     0x629D
        end codes
     end remote

The modified /etc/init.d/lirc, mentioned above, allows the hardware.conf file to correctly specify that the Iguana lircd config file should be used for the receiver, like this:

     #Chosen Remote Control
     REMOTE="SamsungLN32A450"
     REMOTE_MODULES=""
     REMOTE_DRIVER="iguanaIR"
     REMOTE_DEVICE="/dev/iguanaIR/0"
     REMOTE_LIRCD_CONF="/etc/lirc/IguanaIR_SamsungLN32A450.conf"
     REMOTE_LIRCD_ARGS=""

After your hardware configuration file is all set, you can restart the LIRC daemon and test whether your remote is being mapped properly:

     sudo /etc/init.d/lirc start
     sudo irw

As long as irw is running, you should see the names of each of the keys that you press on the remote echoed on the display.

Now, you should go to the Infrared Devices configuration page that is found under the Applications/System/Mythbuntu Control Center menu on the Mythbuntu desktop. Here you can select Enable A Remote Cotrol and pick the Custom remote, and optionally select Enable An IR Transmitter and pick the Custom IR blaster. Uncheck the box to Generate Dynamic Button Mappings. After you apply these changes, this should get MythTV listening to the remote.

The last step is to generate mappings for all of the applications, that you'll be using the remote with. Each mapping translates the key names, that you gave to each of the remote's keys, to the actions that are actually to be carried out in the application. In Mythbuntu, there is a slick little application that uses common key names (i.e. the ones that were suggested above) as input to create the key mappings for all of the Mythbuntu applications automatically. To use it, do the following:

     [Make sure you're logged in as the user that runs Mythbuntu]
     cd ~/
     mythbuntu-lircrc-generator

This will generate mapping files for all of the Mythbuntu applications in the ~/.lirc directory. If the remote then works perfectly with the generated mapping files, well and good. Be sure to test it with any and all of the following applications that you use:

     elisa
     mplayer
     mythtv
     totem
     vlc
     xine
     xmame
     xmess

If the remote does not work perfectly (what are the chances of that), you may wish to hack the files in the ~/.lirc directory. Begin by deleting any remote keys that are needed to operate other devices (e.g. the TV/Display). Here is a list of suggested keys to delete:

     ChannelDown
     ChannelUp
     Menu
     Mute
     VolumeDown
     VolumeUp

Next, you might want to add or remap the special keys that mean so much to your application (e.g. for MythTV, the commercial skip key is always a winner). Do this in consultation with your application's key/command table and a list of the remote's keys (or, you can just look at the remote). Here we show, by way of example, hacks made to the mythtv mapping file for a Sony TiVo remote:

~/.lirc/mythtv:

     Most of the generated key mappings are OK but, for the TiVo remote, you may
     want to add the missing keys like this:
     begin
         remote = TiVoSony
         prog = mythtv
         button = List
         config = I
         repeat = 0
         delay = 0
     end
     begin
         remote = TiVoSony
         prog = mythtv
         button = Select
         config = Return
         repeat = 0
         delay = 0
     end
     begin
         remote = TiVoSony
         prog = mythtv
         button = ThumbsDown
         config = W
         repeat = 0
         delay = 0
     end
     begin
         remote = TiVoSony
         prog = mythtv
         button = ThumbsUp
         config = C
         repeat = 0
         delay = 0
     end
     begin
         remote = TiVoSony
         prog = mythtv
         button = Back
         config = <
         repeat = 0
         delay = 0
     end
     begin
         remote = TiVoSony
         prog = mythtv
         button = Slow
         config = J
         repeat = 0
         delay = 0
     end
     begin
         remote = TiVoSony
         prog = mythtv
         button = Clear
         config = Esc
         repeat = 0
         delay = 0
     end

If we also wanted the Philips TiVo remote to control MythTV, here are the additional hacks made to the mythtv mapping file for a that remote:

~/.lirc/mythtv:

     Most of the generated key mappings are OK but, for the TiVo remote, you may
     want to add the missing keys like this:
     begin
         remote = TiVoPhilips
         prog = mythtv
         button = List
         config = I
         repeat = 0
         delay = 0
     end
     begin
         remote = TiVoPhilips
         prog = mythtv
         button = Select
         config = Return
         repeat = 0
         delay = 0
     end
     begin
         remote = TiVoPhilips
         prog = mythtv
         button = ThumbsDown
         config = W
         repeat = 0
         delay = 0
     end
     begin
         remote = TiVoPhilips
         prog = mythtv
         button = ThumbsUp
         config = C
         repeat = 0
         delay = 0
     end
     begin
         remote = TiVoPhilips
         prog = mythtv
         button = Back
         config = <
         repeat = 0
         delay = 0
     end
     begin
         remote = TiVoPhilips
         prog = mythtv
         button = Slow
         config = J
         repeat = 0
         delay = 0
     end
     begin
         remote = TiVoPhilips
         prog = mythtv
         button = Clear
         config = Esc
         repeat = 0
         delay = 0
     end

You could actually have the identical keys on the two remotes mapped to different functions, if you want, but there's no percentage in that. We're just pointing out that, because there's a set of mappings for each remote that can generate keys (from the lircd config file), each remote's keys can be handled in whatever way you see fit.

Anyway, here we show, by way of another example, the complete key mapping file for a Samsung LN32A450 remote. This remote comes with the LN32A450 display/TV and is normally meant to be used to control the TV. We'd like to only use one remote for watching Myth TV so we take over some of the TV remote's keys to control MythTV, thereby giving the user a single remote solution to MythTV and their display. Here's the mapping file:

~/.lirc/mythtv:

     # LIRCRC Auto Generated by Mythbuntu Lirc Generator
     # Author(s): Mario Limonciello, Nick Fox
     # Created for use with Mythbuntu
     #
     # Changed to reflect actual usage of the remote-ski.
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = One
         config = 1
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Two
         config = 2
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Three
         config = 3
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Four
         config = 4
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Five
         config = 5
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Six
         config = 6
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Seven
         config = 7
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Eight
         config = 8
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Nine
         config = 9
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Zero
         config = 0
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Previous
         config = I
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = List
         config = M
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = ClosedCaption
         config = T
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Return
         config = Escape
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = ArrowUp
         config = Up
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = ArrowDown
         config = Down
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = ArrowLeft
         config = Left
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = ArrowRight
         config = Right
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Enter
         config = Return
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Red
         config = W
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Green
         config = Q
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Yellow
         config = Z
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Rewind
         config = <
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Pause
         config = P
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = FastForward
         config = >
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Record
         config = Space
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Play
         config = P
         repeat = 0
         delay = 0
     end
     begin
         remote = SamsungLN32A450
         prog = mythtv
         button = Stop
         config = Escape
         repeat = 0
         delay = 0
     end

The best technique for building mapping files is to work your way through all of the keys in the appropriate LIRC config file for the remote and make sure that each key is mapped to something. You can also check that each key is only mapped once but this isn't a hard and fast rule (e.g. you might map both the Pause and Stop keys to a single command in MythTV, since the both do the same thing in that application).

All of the other files in the ~/.lirc directory may need hacking too, if you use the applications associated with them.

IR Blasters

IR blasters are needed when Mythbuntu must change channels through a set top box or digital transport adapter instead of just being able to record clear channels off of the antenna input. Usually, the set top box or digital transport adapter is required by a cable company so that they can control which channels you receive in a lineup or pack more services onto the wire using the most efficient technology. Whatever the reason, Mythbuntu must have some way of controlling the STB or DTA to cause it to change when it needs to record a particular program.

Many of the IR receivers also support IR blasters (transmitters). So to do some of the encoder cards. These are the steps to setting up an IR blaster for use by MythTV.

The first step is to make sure that you have a copy of LIRC that supports the IR receiver/transmitter that you will be using. You can take a look at the Remote Controls section (above) for notes on how to build LIRC for a number of remote control receivers but, essentially, this process begins by checking to see if LIRC already has support for the receiver/transmitter built in. You can check whether it does with the following command:

     lircd --driver=?

This will give a list of drivers that are built into the lircd that is installed on the system. If you see the one you need (e.g. "tira" for the Tira-2, "irman" for the Ira, or "iguanaIR" for the Iguana Works product), you are probably in business and you can skip ahead to the irrecord step, below. Otherwise, if you don't see the required driver in the list, or you know for sure that IR blasting with your receiver (e.g. the TopSeed) requires a patch to the LIRC source code, you'll need to download the latest LIRC software from http://www.lirc.org/software.html and build LIRC.

And, note that even if you do see the driver in the list, you still may need to download the latest LIRC because some of the devices that you'll want to control (e.g. the Pace DC50X DTA) may use remote control features that are not available in earlier releases of LIRC (such as XMP, which is only in 0.8.6). If that's the case, download and build the latest version with support for your IR device included.

Once you've downloaded the software, you can uncompress it and unpack it, then build LIRC with the appropriate driver enabled (here we show irman):

     cd lirc
     tar -xvzf lirc-0.8.6.tar.gz
     cd lirc-0.8.6
     ./configure --with-driver=irman
     make

To install the new lircd, become super user and do the install:

     sudo make install

This should put the new lircd in /usr/local/sbin while keeping the original in /usr/sbin -- handy if you need to fall back on the original lircd.

The next step is exactly like one of the steps that must be done to set up a remote control to control Mythbuntu. Begin by making sure that lircd is not running (if you are not doing this for the first time) and then record the STB/DTA's remote's buttons as follows (picking the appropriate invocation of irrecord, depending on which IR receiver you are using):

     [sudo /etc/init.d/lirc stop]
     sudo irrecord -f -H tira -d /dev/ttyUSB0 Tira-2_myremote.conf
     sudo irrecord -f -H irman -d /dev/ttyS0 Ira_myremote.conf
     sudo irrecord -f -n -H iguanaIR -d /dev/iguanaIR/0 Iguana_myremote.conf
     sudo irrecord -f -d /dev/lirc0 MCE_myremote.conf

When you run irrecord, you should follow its instructions. There are notes in the Remote Controls section (above), that you should read about how to record a remote. Be sure to carry out the instructions, as described, because failure to do so will lead to the remote not being set up correctly.

Note that the original MCE receiver doesn't do a very good job of catching the remote codes from many remote controls. If it doesn't, you will most likely get a config file that is recorded in raw mode. In all probability, this file will be junk but you never know. You can analyse it with irrecord to see if there is anything good in it like this:

     irrecord -a MCE_myremote.conf > MCE_myremote-codes.conf

In fact, for some of the DTA remotes that use newer transmission protocols (e.g. Pace DC50X), none of the IR receivers do a very good job of catching their codes. You may get a raw file that cannot be analysed by irrecord or you may get what looks like a good config file but is actually filled with bad or duplicate codes.

In other cases (e.g. Motorola DCT700), the raw file may look good and even appear to work but one or two keys, for example the zero key, will not be received by the DTA or STB. This may make channel changing a challenge.

Many of these devices use the newer XMP protocol from UEI. Rumors are that the a**holes at the cable company (you know who you are) deliberately picked this protocol because it is a b***ard to record and thereby thwarts attempts by owners of non-cable-company DVRs to use their DVR to record the cable company's content. Conspiracy theory or truth? Who knows? But, they are right about one thing. Capturing the protocol is a b***ard.

For these remotes, you may have to start with one of the generic config files:

     http://lirc.sourceforge.net/remotes/generic/

Here is an example of how to do it with the Pace DC50X, using a serial receiver, after downloading the XMP (renamed to XMP.conf) generic file:

     cp XMP.conf Ira_myremote
     sudo irrecord -n -H irman -d /dev/ttyS0 Ira_myremote

After you capture the remote's keys, the Ira_myremote file will be left untouched and new file named Ira_myremote.conf will be created with the captured keys.

Good luck. In truth, the problem undoubtedly lies with irrecord. Despite the fact that the prototype XMP file clearly says "flags XMP", irrecord does not seem to take this fact into account and the protocol does not get captured properly. Nor does using the raw flag yield much joy. If irrecord "thinks it knows" what the protocol is, it doesn't record a raw file regardless of the flag being set. And, we've never seen it not "think it knows" all about the XMP protocol, despite the fact that it has no clue....

If you can't get irrecord to capture your remote's codes, you can look around on the Internet. There are plenty of smart people out there who hate the cable company as much or more than you do. If you're in luck, they'll have figured out your remote's codes and posted them on a Web page, somewhere. Essentially, all you need are the key codes for the ten digits and the Enter key, so that Myth TV can change channels on the DTA/STB. Here, for example, are the codes for the dreaded Pace DC50X:

/etc/lirc/lircd.conf:

     # contributed by Mike Silliman
     #
     # brand: Comcast Branded Motorola DTA100 and Pace DC50X
     # model no. of remote control: Unknown, Comcast Label
     # devices being controlled by this remote: Pace DC50X
     #
     # Protocol: XMP-R
     # Device: 62.16
     #
     # Although this remote uses the XMP protocol, this config should still
     # work with lirc 0.8.5 or earlier because we've defined raw codes herein.
     begin remote
        name             PaceDC50X
        flags            RAW_CODES
        eps              30
        aeps             100
     gap              80412
         begin raw_codes
             name One
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 2656 210 763
             210 763 210 763 210 894
             210 763 210 763 210 80413
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 1578 210 1841
             210 763 210 763 210 894
             210 763 210 763 210
             name Two
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 2524 210 763
             210 763 210 763 210 1026
             210 763 210 763 210 80413
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 1446 210 1841
             210 763 210 763 210 1026
             210 763 210 763 210
             name Three
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 2393 210 763
             210 763 210 763 210 1157
             210 763 210 763 210 80413
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 1315 210 1841
             210 763 210 763 210 1157
             210 763 210 763 210
             name Four
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 2261 210 763
             210 763 210 763 210 1315
             210 763 210 763 210 80413
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 1157 210 1841
             210 763 210 763 210 1315
             210 763 210 763 210
             name Five
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 2130 210 763
             210 763 210 763 210 1446
             210 763 210 763 210 80413
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 1026 210 1841
             210 763 210 763 210 1446
             210 763 210 763 210
             name Six
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 1972 210 763
             210 763 210 763 210 1578
             210 763 210 763 210 80413
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 894 210 1841
             210 763 210 763 210 1578
             210 763 210 763 210
             name Seven
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 1841 210 763
             210 763 210 763 210 1709
             210 763 210 763 210 80413
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 763 210 1841
             210 763 210 763 210 1709
             210 763 210 763 210
             name Eight
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 1709 210 763
             210 763 210 763 210 1841
             210 763 210 763 210 80413
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 2787 210 1841
             210 763 210 763 210 1841
             210 763 210 763 210
             name Nine
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 1578 210 763
             210 763 210 763 210 1972
             210 763 210 763 210 80413
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 2656 210 1841
             210 763 210 763 210 1972
             210 763 210 763 210
             name Zero
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 2787 210 763
             210 763 210 763 210 763
             210 763 210 763 210 80413
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 1709 210 1841
             210 763 210 763 210 763
             210 763 210 763 210
             name Enter
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 1841 210 763
             210 763 210 1026 210 1446
             210 763 210 763 210 80413
             210 894 210 1709 210 763
             210 2787 210 1315 210 1315
             210 1157 210 2656 210 13805
             210 894 210 763 210 1841
             210 763 210 1026 210 1446
             210 763 210 763 210
         end raw_codes
     end remote

The raw codes should work with any version of LIRC and any IR blaster. However, you might not experience proper or reliable channel changing using raw codes with some IR blasters and DTAs/STBs (e.g. using the raw codes with the Pinnacle IR blaster and the Pace DC50X often results in a single key press being replicated as two key presses, although using the same raw codes with the MCE or Iguanna IR blaster and the Pace DC50X works fine). If you have a later version of LIRC (i.e. >= 0.8.6) that supports the XMP protocol, you can try a config file that has the generated codes. Using the proper XMP codes seems to work much more reliably, as in this example, once again for the dreaded Pace DC50X:

/etc/lirc/lircd.conf:

     # Please make this file available to others
     #
     # this config file was automatically generated
     # using lirc-0.8.6-CVS(default) on Mon Jan 11 21:34:36 2010
     #
     # contributed by Kirk Bocek
     #
     # brand: Comcast Branded Motorola DTA100 and Pace DC50X
     # model no. of remote control: Unknown, Comcast Label
     # devices being controlled by this remote: Motorola DTA100 & Pace DC50X
     #
     # These are a couple of the cheap digital converters being provided by
     # Comcast as part of their analog shutdown. DTA100 information here:
     # 
     # http://www.motorola.com/Business/US-EN/Business+Product+and+Services/
     #   TV+Video+Distribution/Customer+Premises+Equipment+%28Set-tops%29/
     #   All-Digital+QAM+Set-tops/DTA100_US-EN
     #
     # This remote also has power and volume buttons. You can program these
     # to control your TV. But these DTAs do have internal volume and mute
     # controls. The power button, however, is only for your TV and has no
     # effect on the DTA.
     #
     # Because this remote uses the XMP protocol, this config requires
     # lirc 0.8.6 or later.
     #
     # Generated by starting with the generic XMP protocol configuration:
     # http://lirc.sourceforge.net/remotes/generic/XMP
     # and then using irrecord to add the keys.
     #
     # V.2 - Added Volume Up and Volume Down
     #
     begin remote
     #  name             MotorolaDTA100
        name             PaceDC50X
        bits             24
        flags            XMP
        eps              20
        aeps             300
     one              0    137
     zero             250  710
     ptrail           250
     pre_data_bits    32
     pre_data         0x170F443E
     post_data_bits   8
     post_data        0x0
     pre              250  12921
     gap              81698
     toggle_bit_mask  0x0
         begin codes
             Info                         0x170026
             One                          0x1E0001
             Two                          0x1D0002
             Three                        0x1C0003
             Four                         0x1B0004
             Five                         0x1A0005
             Six                          0x190006
             Seven                        0x180007
             Eight                        0x170008
             Nine                         0x160009
             Zero                         0x1F0000
             Enter                        0x180025
             Last                         0x190051
             ChannelUp                    0x12000D
             ChannelDown                  0x11000E
             Mute                         0x13000C
             VolumeUp                     0x15000A
             VolumeDown                   0x14000B
             Language                     0x150082
         end codes
     end remote

Here is a working config file that can be used with the Motorola DCT700 (or QIP2500) that is preferred by the "other" cable company (or, so they think of themselves):

/etc/lirc/lircd.conf:

     # Contributed by lisat at Launchpad.
     #
     # Modified DCT2000 configuration for use with Verizon-
     # branded Motorola QIP2500 STB and DCT700 DTA.
     #
     # This config should work with lirc 0.8.5 or earlier because
     # we've defined raw codes herein.
     begin remote
        name             DCT700
        flags            RAW_CODES
        eps              30
        aeps             100
     ptrail           520
     repeat           0  0
     gap              100000
         begin raw_codes
     #          Note that numbers, particularly zero, are special.  If you
     #          record the remote with irrecord, you will not get a reliable
     #          sequence for IR blasting.  Quite possibly you will be able to
     #          receive all of the codes from the remote but the trailing
     #          "42050 9000 2250 500", which has been added to all of the
     #          following numeric codes, is often required to make IR blasting
     #          work reliably and repeatedly (a key requirement, when
     #          unattended channel changing is involved).
                name One
                9000 4400 550 4450 550 2150
                550 2200 550 2200 550 2150
                550 2200 550 2200 550 2150
                550 2200 550 2200 550 2150
                550 2200 550 4400 550 4450
                550 4400 550 4450 550 42050
                9000 2250 500
             name Two
             9000 4400 550 2200 550 4400
             550 2200 550 2150 550 2200
             550 2200 550 2150 550 2200
             550 2200 550 2150 550 2200
             550 2200 550 2150 550 4450
             550 4400 550 4450 500 42050
             9000 2250 500
             name Three
             9000 4400 550 4450 550 4400
             550 2200 550 2150 550 2200
             550 2200 550 2150 550 2200
             550 2200 550 2150 550 2200
             550 2200 550 4400 550 2200
             550 4400 550 4450 500 42050
             9000 2250 500
             name Four
             9000 4400 550 2200 550 2150
             550 4450 550 2150 550 2200
             550 2200 550 2150 550 2200
             550 2200 550 2150 550 2200
             550 2200 550 2150 550 2200
             550 4400 550 4450 550 42050
             9000 2250 500
             name Five
             9000 4450 550 4400 550 2200
             550 4400 550 2200 550 2150
             550 2200 550 2200 550 2150
             550 2200 550 2200 550 2150
             550 2200 550 4400 550 4450
             550 2200 500 4450 550 42050
             9000 2250 500
             name Six
             9000 4500 550 2150 550 4450
             550 4450 550 2200 500 2200
             550 2200 550 2200 550 2150
             550 2200 550 2200 550 2200
             500 2200 550 2200 550 4450
             500 2200 550 4450 550 42050
             9000 2250 500
             name Seven
             9000 4450 550 4450 550 4450
             500 4450 550 2200 550 2200
             550 2150 550 2200 550 2200
             550 2200 500 2200 550 2200
             550 2200 500 4450 550 2200
             550 2200 550 4450 500 42050
             9000 2250 500
             name Eight
             9000 4400 550 2200 550 2150
             550 2200 550 4400 550 2200
             550 2200 550 2150 550 2200
             550 2200 550 2150 550 2200
             550 2200 550 2150 550 2200
             550 2200 550 4400 550 42050
             9000 2250 500
             name Nine
             9050 4450 550 4450 550 2150
             550 2200 550 4450 550 2150
             550 2200 550 2200 550 2200
             500 2200 550 2200 550 2200
             500 2200 550 4450 550 4450
             550 4450 500 2200 550 42050
             9000 2250 500
             name Zero
             9000 4400 550 2200 550 2200
             550 2150 550 2200 550 2200
             550 2150 550 2200 550 2200
             550 2150 550 2200 550 2200
             550 2150 550 2200 550 2200
             550 2150 550 2200 550 42050
             9000 2250 500
             name Enter  # Same as OK
             9050 4400 550 4400 550 2200
             550 2200 550 2150 550 4450
             550 2150 550 2200 550 2200
             550 2150 550 2200 550 2200
             550 2150 550 2200 550 4400
             550 4450 550 4400 550
         end raw_codes
     end remote

These raw codes should work with any version of LIRC and any IR blaster.

Once you have the config file for the STB's or DTA's remote, you can either concatenate it to Myth TV's remote information in /etc/lirc/lircd.conf or, if you modified /etc/init.d/lirc to honor the information in hardware.conf, you can set up one config file for Myth TV's remote and one for the STB/DTA. I prefer the later solution, as this snippet from /etc/lirc/hardware.conf shows:

     # /etc/lirc/hardware.conf
     #
     #Chosen Remote Control
     REMOTE="SamsungLN32A450"
     REMOTE_MODULES=""
     REMOTE_DRIVER="iguanaIR"
     REMOTE_DEVICE="/dev/iguanaIR/0"
     REMOTE_LIRCD_CONF="/etc/lirc/IguanaIR_SamsungLN32A450.conf"
     REMOTE_LIRCD_ARGS=""
     #Chosen IR Transmitter
     TRANSMITTER="PaceDC50X"
     TRANSMITTER_MODULES=""
     TRANSMITTER_DRIVER="iguanaIR"
     TRANSMITTER_DEVICE="/dev/iguanaIR/0"
     TRANSMITTER_LIRCD_CONF="/etc/lirc/XMP_PaceDC50X.conf"
     TRANSMITTER_LIRCD_ARGS=""

Note that this configuration has both a receiver and a transmitter and uses two drivers (albeit both the same one). As shown here, /etc/init.d/lirc will start up two instances of lirc and create two pipes, /dev/lircd and /dev/lircd1. When you run irsend, you will need to specify the second pipe for the transmitter. Myth TV (and other applications) should use the first pipe by default.

For the MCE xceiver, only one copy of LIRC must be run. Furthermore, in some earlier versions of LIRC (e.g. 0.8.3) the lirc_mceusb2 module must be used instead of lirc_mceusb to drive the xceiver. You can find all of the details about which versions of the MCE remote will also allow IR blasting and which kernel module to use at:

     http://www.mythtv.org/wiki/MCE_Remote

This snippet from /etc/lirc/hardware.conf shows how to set things up (again with the modified /etc/init.d/lirc):

     # /etc/lirc/hardware.conf
     #
     #Chosen Remote Control
     REMOTE="Windows Media Center Remotes"
     REMOTE_MODULES="lirc_dev lirc_mceusb"
     REMOTE_DRIVER=""
     REMOTE_DEVICE="/dev/lirc0"
     REMOTE_LIRCD_CONF="/etc/lirc/MCEUSB.conf"
     REMOTE_LIRCD_ARGS=""
     #Chosen IR Transmitter
     TRANSMITTER="PaceDC50X"
     TRANSMITTER_MODULES=""
     TRANSMITTER_DRIVER=""
     TRANSMITTER_DEVICE=""
     TRANSMITTER_LIRCD_CONF="/etc/lirc/Raw_PaceDC50X.conf"
     TRANSMITTER_LIRCD_ARGS=""

When using irsend, there is no need to specify the second pipe, since there is only one.

Now that LIRC is configured correctly, start it up. If your remote was working before, it should still work (duh).

Incidentally, even slight errors in the config file can cause LIRC to fail silently so be careful. Be especially careful with comments because comment handling leaves a bit to be desired. Inside raw_codes, if the comment character doesn't appear in column 1 or if it doesn't appear on a line that has a command on it, it will silently break the config file and LIRC won't see any of your remotes. Nice, huh? Here's a few examples:

     #         This comment is good
               # This comment breaks the config file
               name Enter  # This comment is OK

To test blasting, you can send commands to the IR blaster as follows:

     sudo irsend set_transmitters 1 2 3 4
     sudo irsend send_once PaceDC50X One

If you compiled your own version of LIRC and you kept the original, you will probably want to use:

     sudo /usr/local/sbin/irsend set_transmitters 1 2 3 4
     sudo /usr/local/sbin/irsend send_once PaceDC50X One

OK, so since humans can't see IR radiation, how do we know if the IR blaster is working? Excellent question. One you'd like to have answered before you tape the IR blaster and the IR receiver together, in your version of a homemade optocoupler, with a half a pound of black tape. The answer is simple. Get your digital camera and turn it on so that its ready to take pictures. Point it at a white wall and depress the shutter release part way. Do you see a circular orange-ish glow bouncing back from the wall in the camera's viewfinder? That's the auto-focus IR range finder's light. If you can see it, you'll be able to see the light from the IR blaster too.

Aim the camera directly down the bore-sight of the IR blaster at its typical working distance. While looking at the IR blaster through the camera's viewfinder, run irsend send_once. You should see a momemtary glow from the IR blaster as it transmits the chosen code. This indicates that all is working correctly. You can also use this method to decide which IR blaster to actually select (instead of selecting them all), before you proceed to writing your STB/DTA control script.

Once you're sure the IR blaster is working, fashion an optocoupler from the IR blaster and the STB/DTA's remote IR receiver (if it has one). Usually, a short piece of tube, say 3/4", of the correct diameter can be employed to hold the blaster and receiver in close proximity to each other, so that the light from the blaster impinges directly on the face of the receiver. When you've arranged them in a suitable configuration, the whole thing can be taped up with black electrical tape, thereby excluding any extraneous light.

If your STB/DTA doesn't have a remote IR receiver, you'll need to position the IR blaster in front of its IR receiver, wherever that is on the STB/DTA box. The double sided tape, supplied with the IR blaster, can be used for this task. Or, black electrical tape may prove helpful.

You may have to experiment with the best location for the IR blaster so that it changes channels reliably on the DTA/STB. In the case of one DTA that we know of (Motorola DCT700), positioning the IR blaster 4-6 inches away from front of the DTA/STB actually makes it work better. Clearly some experimentation may be in order.

The next thing required is a script that can send channel change commands to the IR blaster. You'll need a script that accepts the numeric channel number that Myth sends when changing channels and then sends the appropriate keys to the correct blaster. The name of this script will be entered into the MythTV configuration page that connects the lineup (source) to an input (encoder card) so that MythTV can use it to change channels on the STB/DTA whenever it needs to record something.

The requirement to have a separate script for each IR blaster is annoying. And, we've seen lots of channel changer scripts in Internetland that require you to edit the remote name, LIRC pipe name, etc. into the script before you use it. This too is annoying.

The following script can be used to change channels on any IR blaster (by adding a symlink to it with the blaster number in the linked name) while configuring itself from the information in /etc/lirc/hardware.conf. In short, it is pretty much automagic. Install the following script somewhere convenient (I use /etc/lirc):

/etc/lirc/IRChangeChannel:

     #! /bin/sh
     # Shell script used to send channel change commands to a set top box (STB)
     # or digital transport adapter (DTA) via LIRC.
     #
     # This script is commonly used by applications such as Myth TV to change
     # the channels on a STB/DTA when the STB/DTA must be used to convert the
     # channels that a subscriber can see to a single channel (e.g. when
     # digital channels are to be viewed by the application on channel 3 with
     # an analog decoder card).
     #
     # The application invokes this script and passes the channel number to it
     # as the first parameter.  This script deconstructs the channel number and
     # decides what command sequence the STB/DTA's remote would have to send in
     # order to change to that channel (typically its the channel number,
     # followed by the Enter button).  It sends the channel change commands to
     # the STB/DTA through the IR blaster that was started by lircd.  The
     # information necessary to do this is obtained from the lircd config file
     # /etc/lirc/hardware.conf.
     #
     # If you need to send commands to a different IR emitter than number 1,
     # you can alias this script and use the aliases to send to any emitter
     # from 1 thru 4.  You must set up the aliases as follows:
     #
     #   ln -s IRChangeChannel IR1ChangeChannel
     #   ln -s IRChangeChannel IR2ChangeChannel
     #   ln -s IRChangeChannel IR3ChangeChannel
     #   ln -s IRChangeChannel IR4ChangeChannel
     #
     # You can then send commands to the alternate emitters as follows:
     #
     #   /path/to/scripts/IR1ChangeChannel 12
     #   /path/to/scripts/IR2ChangeChannel 22
     #        .
     #        .
     #        .
     #
     # Because of the nature of the way that the program name is determined,
     # you must use some kind of path prefix on the name (i.e. at the very
     # least, use "./IR3ChangeChannel 44").
     #
     # Note that, unless you are using stereo emitters on the IguanaIR, the two
     # emitters on the stick are IR1 and IR3 (two and four are not used).
     #
     # Some DTAs do not change the channel reliably, every time.  Or, they do it
     # fine with one IR blaster and not another.  In this case, if they typically
     # miss some digits and do nothing because of it (i.e. stay on the same
     # channel that they were originally on), you can set CHANGE_TRIES to
     # something other than one (below).  This will cause the script to try
     # changing the channel the number of times given and, hopefully, one will
     # stick.
     ##########################################################################
     # Constants that define how this script works.  Set these up once at
     # install time.
     # Where we load irsend from (depends whether this is a system install or
     # a local build).
     #ew LOAD_PATH=/usr/bin
     LOAD_PATH=/usr/local/bin
     # The delay (in seconds) that we should sleep between each key press (a
     # half a second seems to be a reasonable number).
     KEY_DELAY=0.5
     # The number of times this script should try changing the channel (see
     # above).
     CHANGE_TRIES=1
     # See if we can find the send module in the place where the user told us to
     # look.  If not, we're outta here quick.
     test -f ${LOAD_PATH}/irsend || exit 0
     # The user can symlink to this program to use an emitter other than 1.  We
     # figure this out from our invoking program name.
     Emitter=0
     ProgName=`echo $0 | sed -r s:.+/\([^/]+\)$:\\\1:`
     if [ ! -n "$ProgName" ] || [ "$ProgName" = "IRChangeChannel" ]; then
         Emitter=1
     else
         case "$ProgName" in
             IR1ChangeChannel)
                 Emitter=1
                 ;;
             IR2ChangeChannel)
                 Emitter=2
                 ;;
             IR3ChangeChannel)
                 Emitter=3
                 ;;
             IR4ChangeChannel)
                 Emitter=4
                 ;;
             *)
                 Emitter=1
         esac
     fi
     # Let's get the config file that was used to start lircd with.  It will
     # tell us what remote we're using (hopefully).
     if [ -f /etc/lirc/hardware.conf ]; then
         . /etc/lirc/hardware.conf
     fi
     # We need a remote name.
     if [ -z "$TRANSMITTER" ] || [ "$TRANSMITTER" = "none" ]; then
         exit 0
     fi
     # Figure out where the transmitter is.
     if [ -n "$PIPE_PATH" ] && [ "$PIPE_PATH" != "none" ]; then
         DEV_PATH=$PIPE_PATH
     else
         DEV_PATH="/var/run/lirc"
     fi
     # If there's a transmitter device or driver defined, the lirc init script
     # started a second copy of lircd.
     if [ ! -z "$TRANSMITTER_DEVICE" ] \
         || [ ! -z "$TRANSMITTER_DRIVER" ]; then
         DevArgs="--device=$DEV_PATH/lircd1"
     else
         DevArgs="--device=$DEV_PATH/lircd"
     fi
     # Select the appropriate IR emitter on the device.
     ${LOAD_PATH}/irsend $DevArgs set_transmitters $Emitter
     # Try setting the channel the number of times the user has requested us to
     # do so (some DTAs with some blasters don't get the message the first
     # time).
     Tries=1
     while [ $Tries -le $CHANGE_TRIES ]; do
      # Send the channel number.
      for Digit in $(echo $1 | sed -e 's/./& /g'); do
          case "$Digit" in
              1)
                  Key="One"
                  ;;
              2)
                  Key="Two"
                  ;;
              3)
                  Key="Three"
                  ;;
              4)
                  Key="Four"
                  ;;
              5)
                  Key="Five"
                  ;;
              6)
                  Key="Six"
                  ;;
              7)
                  Key="Seven"
                  ;;
              8)
                  Key="Eight"
                  ;;
              9)
                  Key="Nine"
                  ;;
              *)
                  Key="Zero"
          esac
          ${LOAD_PATH}/irsend $DevArgs send_once $TRANSMITTER $Key
          sleep 0.5
      done
      # Send the enter key.
      ${LOAD_PATH}/irsend --device=/dev/lircd SEND_ONCE $TRANSMITTER Enter
      if [ $Tries -lt $CHANGE_TRIES ]; then
          sleep $KEY_DELAY
      fi
      # Increment the try count, in case we're doing this more than once.
      Tries=`expr $Tries + 1`
     done

Don't forget to set the permissions to execute for everyone. Test the script to see that it changes channels OK. Plug a TV into the STB/DTA, tune it to channel 3, make sure the STB/DTA channel switch is set to 3, and send it a channel change command like this:

     /etc/lirc/IR1ChangeChannel 12

You should see the chosen channel on your TV. Try all of the other digits in your channel numbers, to make sure that all digits work, and try long and short channel numbers. If all of them work, you can cable the STB/DTA up to the input of the appropriate encoder card that you want to use with the DTA/STB.

Proceed to the "Connect source to input" MythTV configuration page. You can get to this page by launching the Mythbuntu Control Center off the desktop menu or, in earlier versions of MythTV, from the frontend, by selecting the Utilities/Setup | Setup | Mythbuntu menus. You must do this on the system that actually has the encoder card installed in it (if you have multiple systems networked to a single backend).

Enter your password to get the Mythbuntu Control Center to launch. From there, pick the MythTV Configuration menu item and then Launch MythTV Setup, once it becomes visible. You will need to shut down the backend to continue.

From the MythTV Setup main menu, pick the Input Connections item. Then, from the list of encoders, pick the encoder card that is physically connected to the STB/DTA. That should bring up the "Connect source to input" page. Under the "External channel change command" field, enter the full path to the change channel script. Make sure the path is absolutely correct because, if you make a typo, MythTV will simply hang for a while and then do nothing (i.e. you won't get any error messges or warnings).

Note that, if you are connecting multiple STB/DTAs to multiple encoder cards, you should set each one up so that it points to the symlinked file name for the appropriate IR blaster that controls the STB/DTA connected to that card. For example, the setup for /dev/video0 might look like this:

     /etc/lirc/IR1ChangeChannel

While the setup for /dev/video1 might look like this:

     /etc/lirc/IR2ChangeChannel

There is no other way to pass the IR emitter number to the channel changer script except by its file name, hence the reason for symlinking aliases to the channel changer script to tell it which IR emitter to change.

Under the "Preset tuner to channel" field, you should enter the channel number that the STB/DTA transmits on (typically it is channel 3). This will cause the encoder card to be set to the

Note that all of the channels in the lineup defined by the video source that is connected to this encoder will be selected by sending the channel number to the STB/DTA via the channel changer script and by presetting the encoder to the chosen channel (e.g. channel 3). If this doesn't work for some of your channels (e.g. you have a mixture of digital channels that can be directly tuned and analog channels that require the STB/DTA), you will need to construct more than one video source (lineup) and assign the separate sources to the disparate encoders.

After you've set up the external channel changer script, you can save the configuration, restart the backend and restart the frontend. From the frontend, pick Watch Live TV. Choose the tuner that you've set up to use the STB/DTA and see if it shows live TV. You should be able to change channels by entering a channel number, followed by Enter or by using the up/down arrows. If you don't see your chosen channel after 3 or 4 seconds, you need to go find out what's wrong with your configuration. Good luck! There are plenty of places for it to go wrong, including where you entered the path name of the external channel changer script. No errors are reported so it helps if you are psychic. If it works, you are basically in business.

Incidentally, some people have pointed out that the "Preset tuner to channel" field doesn't seem to work. If that's the case, you can install the ivtv-utils package and use one of its utilities to pretune the tuner to the correct channel:

     sudo apt-get install ivtv-utils

Add a line something like this to rc.local:

     /etc/rc.local:
     ivtv-tune -c 3 -d /dev/video0 -t us-cable

This should tune the encoder to the correct channel at startup.

Replacing Or Improving On The IR Blaster

Many of us have now been forced by Comcast to add a Pace DC50X in front of their MythTV setup in order to record programs in the extended basic tier that used to be broadcast in the clear. IR blasting to control the Pace DC50X works OK with the original MCE USB receiver as it does with the Iguana IR receiver. Sadly, the MCE USB receiver is no longer available and the performance of the Iguana receiver leaves much to be desired so you may be forced by expediency or common sense to use other IR receivers.

The TopSeed IR Receiver works with the on-board USB ports on some motherboards but not others so you can use it, if it is compatible with your motherboard. Its blaster may or may not work with the DC50X. The Pinnacle Systems PCTV Remote seems to work with all on-board USB ports and is readily available. Unfortunately, its IR blaster does not work reliably with the Pace DC50X.

If you are stuck using the Pace DC50X and you need to use one of the IR receivers (like the Pinnacle) whose blaster doesn't work with it, you can try substituting an optocoupler for the combination of the IR blaster supplied with your IR receiver and the IR receiver supplied with the DC50X. Not only is the likelihood of success much greater when an optocoupler is used but the setup looks much neater.

The typical IR blaster output of an IR receiver is a mono 3.5mm jack with the Tip being the Data signal and the Ring being the Ground. If you care to take the DC50X apart, you will see that the "IR IN" jack on the back is electrically connected to the IR detector on the front and, if you care to take the remote IR receiver that comes with the DTA apart, you'll find that the wires leading into it are labeled, and that, according to this labeling, the stereo 3.5mm plug that it uses has power on the Tip, Data on the Center Ring, and Ground on the Base Ring (furthest from the Tip). Or, you can just take our word for it.

To couple the IR blaster output port to the DC50X input port, we will use, as we noted above, an optocoupler to convert the IR blaster's active high signaling to the active low signaling needed on the DTA's input.

Since the basic problem with the Pace DC50X, that we are trying to solve, is that the power output by the IR blaster is not enough to reliably drive the DTA, we want an optocoupler with a high current transfer ratio. The 4N37 (which is an NPN transistor, optocoupler that comes in a 6-pin DIP package) has a CTR of 100 so it should work well. It is also readily available from sources such as Digi-Key for under a buck.

A 3.5mm mono plug is soldered onto a suitable length of flexible, two-conductor wire (if color coded, the red lead should be soldered to the Tip and the black soldered to the Ring). The other end of the wire is carefully soldered to pin 1 (Tip) and pin 2 (Ring) of the optocoupler. A couple of bits of shrink tubing can make the job neat and prevent short circuits.

A 3.5mm stereo plug is soldered onto another suitable length of flexible, two-conductor wire (if color coded, the red lead should be soldered to the First Ring and the black soldered to the Second Ring). The other end of the wire is, likewise, carefully soldered to pin 5 (First Ring) and pin 4 (Second Ring) of the optocoupler. More shrink tubing can be applied for insulation, including a larger piece over the optocoupler itself. Note that the DTA power, from the stereo plug's tip, is not connected.

When you plug the mono jack into the IR receiver and the stereo jack into the DTA (now's a good time to label them), control of the DTA should prove much more reliable.

Setting The Clock

The clock on the Mythbuntu system must be kept synchronized with a source of accurate time, in order for programs to be recorded at the correct start/stop times. Typically, NTP is used for this job. Mythbuntu comes precofigured with NTP installed and running.

To set up NTP properly, you will need to edit the config file and point it at two or three NTP servers. To do so:

     sudoedit /etc/ntp.conf

After the line that says "server ntp.ubuntu.com", you can add a few more servers, like this:

     server ntp.aserver.com

Look at the following list of public NTP servers and pick a couple more stratum 2 servers to synchronize with. Servers, from the list, that are close to you will provide better synchronization:

     http://support.ntp.org/bin/view/Servers/StratumTwoTimeServers

If you have a local clock that is regulated well enough, you can synchronize your Mythbuntu systems to it.

/etc/ntp.conf:

     Here is a complete replacement for /etc/ntp.conf that synchronizes the
     system to a local clock.  Note that the local server is marked as a true
     chimer by the "true" keyword and it is also marked as the preferred server.
     Unfortunately, the "true" keyword seems not to work in the earlier versions
     of NTP (4.2.4) that are installed on some of the earlier Mythbuntu
     versions (e.g. 9.10) so you may have to take other steps (see below).
     Here is the file:
     #
     # /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help.
     # Read by ntpd at startup.
     #
     # For ntpd version 4.2.6.
     #
     #
     # Prohibit general access to this service.
     #
     restrict default ignore
     #
     # Local users may interrogate the ntp server more closely.
     #
     restrict 127.0.0.1
     restrict ::1
     #
     # Permit time synchronization with our local time source but do not
     # permit the source to query or modify the service on this system.
     #
     restrict 192.168.1.1
     #
     # Synchronize this system with our local NTP server.
     #
     server 192.168.1.1 true prefer minpoll 4 maxpoll 5
     #
     # Undisciplined Local Clock.  This is a fake driver intended for backup and
     # when no outside source of synchronized time is available.  The normal,
     # running stratum is usually 3, but in this case we elect to use stratum
     # 10.  Since the server line does not have the prefer keyword, this clock
     # is never used for synchronization, unless no other other synchronization
     # source is available.
     #
     # Actually, this happens way more than you'd think it might so it is
     # important to have this clock defined to keep things ticking along.
     #
     server 127.127.1.0
     fudge  127.127.1.0 stratum 10
     #
     # Drift file.  Put this in a directory which the daemon can write to.  No
     # symbolic links allowed, either, since the daemon updates the file by
     # creating a temporary file in the same directory and then renameing it to
     # the file named.
     #
     # This file is read at startup to give the daemon a leg up on getting
     # running without having to go through the laborious chore of figuring out
     # drift from scratch.
     #
     driftfile /var/lib/ntp/ntp.drift
     #
     # Enable this if you want statistics to be logged.
     #
     #statsdir /var/log/ntp/
     #
     # Statistics to be logged.
     #
     statistics loopstats peerstats clockstats
     filegen loopstats file loopstats type day enable
     filegen peerstats file peerstats type day enable
     filegen clockstats file clockstats type day enable

/etc/init.d/ntpd:

     You may also need to alter the NTP startup script to begin by synchronizing
     the Mythbuntu machine's clock with NTP on the reference clock's machine.
     This is necessary if there can be large amounts of drift between the
     reference clock and the local clock when the Mythbuntu machine is down.  As
     is well known, NTP will not synchronize clocks that are too far apart, hence
     the need to do it manually at startup.  The following is a complete
     replacement for the ntpd script that carries out synchronization at startup
     as well as fixes a few other problems.  You may wish to use it in lieu of the
     script provided by Mythbuntu:
     #!/bin/sh
     ### BEGIN INIT INFO
     # Provides:        ntp
     # Required-Start:  $network $remote_fs $syslog
     # Required-Stop:   $network $remote_fs $syslog
     # Default-Start:   2 3 4 5
     # Default-Stop:    0 1 6
     # Short-Description: Start NTP daemon
     ### END INIT INFO
     PATH=/sbin:/bin:/usr/sbin:/usr/bin
     . /lib/lsb/init-functions
     NAME=ntp
     DAEMON=/usr/sbin/ntpd
     PIDFILE=/var/run/ntpd.pid
     # Use a local clock as the step ticker at startup.
     STEP_TICKER=192.168.1.1
     test -x $DAEMON || exit 5
     if [ -r /etc/default/$NAME ]; then
         . /etc/default/$NAME
     fi
     if [ -e /etc/ntp.conf.dhcp ]; then
         NTPD_OPTS="$NTPD_OPTS -c /etc/ntp.conf.dhcp"
     fi
     # Running as user ntp doesn't cut it.
     # RUNASUSER=ntp
     RUNASUSER=root
     UGID=$(getent passwd $RUNASUSER | cut -f 3,4 -d:) || true
     case $1 in
         start)
             log_daemon_msg "Synchronizing with $STEP_TICKER" "ntpd"
             ntpdate $STEP_TICKER
             log_daemon_msg "Starting NTP server" "ntpd"
             if [ -z "$UGID" ]; then
                 log_failure_msg "user \"$RUNASUSER\" does not exist"
                 exit 1
             fi
             start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE \
                 --startas $DAEMON -- -p $PIDFILE -u $UGID $NTPD_OPTS
             log_end_msg $?
             ;;
         stop)
             log_daemon_msg "Stopping NTP server" "ntpd"
             start-stop-daemon --stop --quiet --oknodo --pidfile $PIDFILE
             log_end_msg $?
             rm -f $PIDFILE
             ;;
         restart|force-reload)
             $0 stop && sleep 2 && $0 start
             ;;
         try-restart)
             if $0 status >/dev/null; then
                 $0 restart
             else
                 exit 0
             fi
             ;;
         reload)
             exit 3
             ;;
         status)
             pidofproc -p $PIDFILE $DAEMON >/dev/null
             status=$?
             if [ $status -eq 0 ]; then
                 log_success_msg "NTP server is running."
             else
                 log_failure_msg "NTP server is not running."
             fi
             exit $status
             ;;
         *)
             echo "Usage: $0 {start|stop|restart|try-restart|force-reload|\
                             status}"
             exit 2
             ;;
     esac

For NTP to work well, the local clock should run fairly closely to the clock that you are trying to synchronize it with. If it does not, you can try adjusting the clock, using the tickadj command. The default value for the tick (usually 10000) can be found by running:

     tickadj

If the clock is constantly running behind, you can cause it to slew ahead a bit, thereby regulating it more closely to the source you are trying to synchronize with. Small deviations from the default value are usually all that is required. For example:

     tickadj 9990

If the clock is constantly running ahead, you can cause it to slew behaind a bit, thereby regulating it more closely to the source you are trying to synchronize with. Once again, small deviations from the default value are usually all that is required. For example:

     tickadj 10010

If you cannot keep the clock on the Mythbuntu machine synchronized using NTP, because the clock you are trying to synchronize against is too poorly regulated or for other reasons, and the "true" keyword does not force NTP on the Mythbuntu machine to use the clock anyway (as is the case on earlier versions of Mythbuntu, such as 9.10), you may have to resort to synchronizing it at regular intervals using ntpdate.

The first step is to stop the NTP daemon from running. Begin by checking to see if it is actually installed and being started as a system service. Unfortunately, the update-rc.d command on Mythbuntu does not provide any "List" option to show whether a system service is set up to be run automatically. To find this out, you can do:

     ls -l /etc/rc.d/ntp

Look at the results of this command. If the symlink to /etc/init.d/ntp starts with 'K', NTP is shutdown at the runlevel given by "rcx". If the symlink starts with 'S', NTP is started at the runlevel given by "rcx". If NTP is started at runlevels 2, 3, 4, or 5, you will need to stop it. To do this, using the dain-bramaged update-rc.d, run:

     sudo /etc/init.d/ntp stop
     sudo rm -f /etc/rc.d/ntp
     sudo update-rc.d ntp stop 20 0 1 2 3 4 5 6 .

However, even this may not be sufficient to stop the ntp daemon. On some versions of Mythbuntu, this daemon is automatically started at boot time, regardless of the symlinks in /etc/init.d. If this is the case with your system, see the additional line to be added to crontab (below).

Incidentally, if you ever need to put NTP back the way it was originally installed, remove the crontab entries for ntpdate (see below) and run:

     sudo rm -f /etc/rc.d/ntp
     sudo update-rc.d ntp stop 20 0 1 6 . start 20 2 3 4 5 .
     sudo /etc/init.d/ntp start

You'll then need to add a line or two to crontab to cause ntpdate to be run often enough to keep the clocks synchronized. Using the editor:

     sudoedit /etc/crontab

Add something like the following:

     # Run ntpdate at regular intervals to synchronize the clock (ntp itself fails
     # in this respect).  Note that some annoying piece of s**t keeps starting the
     # ntp daemon, which prevents ntpdate from working.  So, just before we run
     # ntpdate, we kill the daemon.
     55 * * * * root /etc/init.d/ntp stop 2>&1 >/dev/null
     56 * * * * root /usr/sbin/ntpdate 192.168.1.1 2>&1 >/dev/null

Note that you best ensure that this is working. To do so, you can issue the ntpdate command periodically until you are sure all is well:

     /usr/sbin/ntpdate 192.168.1.1

will windge if the daemon is still running. If so, figure out why and fix it. Its no fun having 56-minute hour shows.

Keeping MythBackend Up And Running

>>>>>>
<<<<<<
MythBackend has a propensity to crash at inopportune moments (e.g. a couple hours after you've just left on a week's vacation). Well, nobody's perfect. Stuff happens. You can't expect to write code that never crashes. But, given Myth's status as a consumer appliance, you wonder why the Mythbuntu bozos didn't bother to include this watchdog for MythBackend in the distro. As it is now, you have to install it yourself.

This section was distilled from:

     http://www.mythtv.org/wiki/index.php/Using_pcsk_to_Supervise_mythbackend

Obtain the latest PCSK from http://www.nix.hu/projects/pcsk/. Uncompress and unpack the distro and build it. For example:

     mkdir pcsk
     cd pcsk
     wget http://downloads.nix.hu/downloads/pcsk/pcsk-0.0.5.tar.bz2
     tar xjf pcsk-0.0.5.tar.bz2
     cd pcsk-0.0.5
     make
     sudo make install

Create the following script (from Mythbuntu 8.04LTS) in your pcsk directory (see below for a Mythbuntu 9.04 script). I called mine mythtv-backend.pcsk:

     #! /bin/sh
     ### BEGIN INIT INFO
     # Provides:          mythtv-backend
     # Required-Start:    $local_fs $remote_fs $network
     # Required-Stop:     $local_fs
     # Default-Start:     50
     # Default-Stop:      S
     # Short-Description: Start/Stop the MythTV server.
     ### END INIT INFO
     #
     # modified mythtv-backend rc script
     # V0.22 by EW  6th Jun 2008:
     #       Updated for Mythbuntu 8.04LTS
     #       Removed mythtv-status
     # v0.21 by DJK 3rd Dec 2007:
     #       Removed -0 option for pcsk
     #               mythbackend seems to catch all signals (even when core
     #               dumping) and still exits 0! so we actually need to restart
     #               it no matter what its exit code was...
     # v0.2  by DJK 28th Nov 2007:
     #       Added pcsk supervision to restart if it dies
     #       Had to lose NICE for now, sorry.  Might be able to use renice
     #         sometime in the future?
     #       Call mythtv-status script for extra details
     #
     PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
     DAEMON=/usr/bin/mythbackend
     NAME="mythbackend"
     DESC="MythTV server"
     # Check that the mythbackend binary exists
     if ! [ -x "$DAEMON" ] ; then
             log_end_msg "Could not find $DAEMON binary"
             exit 1
     fi
     # Check that the pcsk binary exists somewhere in the path (I choose
     # /usr/local/bin)
     if ! PCSKBINARY="`which pcsk`" > /dev/null 2>&1; then
             log_end_msg "Could not find pcsk binary to supervise $NAME.  \
                 Try www.nix.hu/projects/pcsk..."
             exit 1
     fi
     . /lib/lsb/init-functions
     set -e
     prime_firewire()
     {
         if [ "$ENABLE_FIREWIRE" = "TRUE" ]; then
         log_daemon_msg "Priming Firewire "
             su - $USER -c "/usr/bin/mythprime"
         log_end_msg $?
         fi
     }
     USER=mythtv
     USER_HOME=$(grep ^$USER /etc/passwd | awk -F : '{print $6}')
     RUNDIR=/var/run/mythtv
     # mythbackend arguments - I've removed --daemon since pcsk will daemonise
     # it for me
     ARGS="--logfile /var/log/mythtv/mythbackend.log --pidfile $RUNDIR/$NAME.pid"
     EXTRA_ARGS=""
     NICE=0
     # The pid and log files for pcsk to use
     PCSKPIDFILE="$RUNDIR/$NAME-pcsk.pid"
     PCSKLOGFILE="/var/log/mythtv/mythbackend-pcsk.log"
     # Command line options for pcsk:
     # -r: restart the program if it dies
     # -e: log stderr, if there is any
     # -o: log stdout, if there is any
     ## -0: don't restart if the exit code was 0 - not using this at the moment
     # -w3: wait 3 sec before restart (default in original script)
     # -i10: increment each wait between restarts by 10s
     # -c10: restart up to 10 times if the restart is unsuccessful, before giving
     #       up
     # -m60: restart wasn't successful if the program exits within 60 sec
     # -p $PIDFILE: use that file for the pid
     # -l $PCSKLOGFILE: log file to keep track of things - good to set up
     #    logrotate
     PCSKOPTS="-reo -w3 -i10 -c10 -m60 -p $PCSKPIDFILE -l $PCSKLOGFILE"
     # Check for alternate options for mythtv-backend
     if [ -f /etc/default/mythtv-backend ]; then
       . /etc/default/mythtv-backend
     fi
     ARGS="$ARGS $EXTRA_ARGS"
     PCSKARGS="$PCSKOPTS $DAEMON -- $ARGS"
     mkdir -p $RUNDIR
     chown -R $USER $RUNDIR
     unset DISPLAY
     unset SESSION_MANAGER
     #create a symbolic link for mysql.txt so it can't be overwritten
     mkdir -p $USER_HOME/.mythtv
     chown -R $USER $USER_HOME/.mythtv
     if [ ! -e $USER_HOME/.mythtv/mysql.txt ]; then
             ln -s /etc/mythtv/mysql.txt $USER_HOME/.mythtv/mysql.txt
     fi
     case "$1" in
       start)
         # Check if pcsk is already supervising this process by checking for
         # the existance of a pidfile and that it's a currently running process
         PCSKPID=
         DAEMONPID=
         if [ -e "$PCSKPIDFILE" ] ; then
             read PCSKPID < "$PCSKPIDFILE"
             if [ -n "$PCSKPID" ] && [ -d "/proc/$PCSKPID" ] ; then
                 # pcsk is running, what about our daemon?
                 if [ -e "$RUNDIR/$NAME.pid" ] ; then
                     read DAEMONPID < "$RUNDIR/$NAME.pid"
                     if [ -n "$DAEMONPID" ] && [ -d "/proc/$DAEMONPID" ] ; then
                         # daemon is running too
                         log_success_msg "pcsk($NAME) (pid $PCSKPID) is already \
                             running, supervising $NAME (pid $DAEMONPID); \
                             use restart instead."
                         exit 1
                     fi
                     # daemon isn't running at the moment (pcsk might be waiting
                     # to respawn it) anyway, take the opportunity to restart
                     # everything now
                     log_success_msg "pcsk($NAME) (pid $PCSKPID) is running but \
                         $NAME is currently stopped.  Restarting now..."
                     $0 restart
                     exit $?
                 fi
             fi
         fi
         prime_firewire
         log_daemon_msg "Starting $DESC: pcsk($NAME) "
         # NICE gets ignored because pcsk doesn't support it and start-stop-daemon
         # would just nice pcsk, not the daemon.
         # Maybe we could somehow use renice?  Later...
         if ! start-stop-daemon --start --pidfile "$PCSKPIDFILE" \
             --chuid $USER --exec "$PCSKBINARY" -- $PCSKARGS ; then
             log_end_msg "failed (start-stop-daemon exited with code $?)"
             exit 1
         fi
         log_end_msg $?
         ;;
       stop)
         log_daemon_msg "Stopping $DESC: pcsk($NAME) "
         start-stop-daemon --stop --oknodo --pidfile "$PCSKPIDFILE" \
             --chuid $USER --retry 5 --exec "$PCSKBINARY" -- $PCSKARGS
         log_end_msg $?
         [ -e "$PCSKPIDFILE" ] && rm -f "$PCSKPIDFILE"
         [ -e "$RUNDIR/$NAME.pid" ] && rm -f "$RUNDIR/$NAME.pid"
         ;;
       restart)
         $0 stop
         sleep 3
         $0 start
         ;;
       force-reload)
         log_daemon_msg "force-reload not supported, restarting instead..."
         $0 restart
         ;;
       status)
         # We have an advantage in this mess that we know what the pidfiles
         # (and therefore pids) are.  Poor-man's status can be had by checking
         # for the existance of a pidfile and then that it's a currently running
         # process by looking for that directory in /proc
         PCSKPID=
         DAEMONPID=
         if [ -e "$PCSKPIDFILE" ] ; then
             read PCSKPID < "$PCSKPIDFILE"
             if [ -n "$PCSKPID" ] && [ -d "/proc/$PCSKPID" ] ; then
                 echo "pcsk($NAME) (pid $PCSKPID) is running..."
             else
                 echo "pcsk($NAME) is dead but pid file exists"
             fi
         else
             echo "pcsk($NAME) is stopped"
         fi
         if [ -e "$RUNDIR/$NAME.pid" ] ; then
             read DAEMONPID < "$RUNDIR/$NAME.pid"
             if [ -n "$DAEMONPID" ] && [ -d "/proc/$DAEMONPID" ] ; then
                 echo "$NAME (pid $DAEMONPID) is running..."
             else
                 echo "$NAME is dead but pid file exists"
             fi
         else
             echo "$NAME is stopped"
         fi
         ;;
       *)
         echo "Usage: $0 {start|stop|restart|status|force-reload(unsupported)}" \
             >&2
         exit 2
         ;;
     esac
     exit 0

The mythtv-backend script has been updated for Mythbuntu 9.04. Here is an updated version of the script for Mythbuntu 9.04:

     #! /bin/sh
     ### BEGIN INIT INFO
     # Provides:          mythtv-backend
     # Required-Start:    $local_fs $remote_fs $network
     # Required-Stop:     $local_fs
     # Default-Start:     2 3 4 5
     # Default-Stop:      0 1 6
     # Short-Description: Start/Stop the MythTV server.
     ### END INIT INFO
     #
     # modified mythtv-backend rc script
     # V0.23 by EW  22th Sep 2009:
     #       Updated for Mythbuntu 9.04
     # V0.22 by EW  6th Jun 2008:
     #       Updated for Mythbuntu 8.04LTS
     #       Removed mythtv-status
     # v0.21 by DJK 3rd Dec 2007:
     #       Removed -0 option for pcsk
     #               mythbackend seems to catch all signals (even when core
     #               dumping) and still exits 0! so we actually need to restart
     #               it no matter what its exit code was...
     # v0.2  by DJK 28th Nov 2007:
     #       Added pcsk supervision to restart if it dies
     #       Had to lose NICE for now, sorry.  Might be able to use renice
     #       sometime in the future?
     #       Call mythtv-status script for extra details
     #
     PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
     DAEMON=/usr/bin/mythbackend
     NAME="mythbackend"
     DESC="MythTV server"
     . /lib/lsb/init-functions
     # Check that the mythbackend binary exists
     if ! [ -x "$DAEMON" ] ; then
         log_failure_msg "Could not find $DAEMON binary"
         log_end_msg 1
         exit 1
     fi
     # Check that the pcsk binary exists somewhere in the path (I choose
     # /usr/local/bin)
     if ! PCSKBINARY="`which pcsk`" > /dev/null 2>&1; then
         log_failure_msg "Could not find pcsk binary to supervise $NAME.  \
             Try www.nix.hu/projects/pcsk..."
         log_end_msg 1
         exit 1
     fi
     set -e
     prime_firewire()
     {
         if [ "$ENABLE_FIREWIRE" = "TRUE" ]; then
             log_daemon_msg "Priming Firewire "
             su - $USER -c "/usr/bin/mythprime"
             log_end_msg $?
         fi
     }
     USER=mythtv
     USER_HOME=$(grep ^$USER /etc/passwd | awk -F : '{print $6}')
     RUNDIR=/var/run/mythtv
     # mythbackend arguments - I've removed --daemon since pcsk will daemonise
     # it for me
     ARGS="--logfile /var/log/mythtv/mythbackend.log --pidfile $RUNDIR/$NAME.pid"
     EXTRA_ARGS=""
     NICE=0
     # The pid and log files for pcsk to use
     PCSKPIDFILE="$RUNDIR/$NAME-pcsk.pid"
     PCSKLOGFILE="/var/log/mythtv/mythbackend-pcsk.log"
     # Command line options for pcsk:
     # -r: restart the program if it dies
     # -e: log stderr, if there is any
     # -o: log stdout, if there is any
     ## -0: don't restart if the exit code was 0 - not using this at the moment
     # -w3: wait 3 sec before restart (default in original script)
     # -i10: increment each wait between restarts by 10s
     # -c10: restart up to 10 times if the restart is unsuccessful, before giving
     #       up
     # -m60: restart wasn't successful if the program exits within 60 sec
     # -p $PIDFILE: use that file for the pid
     # -l $PCSKLOGFILE: log file to keep track of things - good to set up
     #    logrotate
     PCSKOPTS="-reo -w3 -i10 -c10 -m60 -p $PCSKPIDFILE -l $PCSKLOGFILE"
     # Check for alternate options for mythtv-backend
     if [ -f /etc/default/mythtv-backend ]; then
       . /etc/default/mythtv-backend
     fi
     ARGS="$ARGS $EXTRA_ARGS"
     PCSKARGS="$PCSKOPTS $DAEMON -- $ARGS"
     mkdir -p $RUNDIR
     chown -R $USER $RUNDIR
     unset DISPLAY
     unset SESSION_MANAGER
     # Check that the MythTV home directory exists.
     if [ ! -d $USER_HOME ]; then
         log_failure_msg "MythTV home directory, $USER_HOME does not exist."
         exit 1
     fi
     #create a symbolic link for mysql.txt so it can't be overwritten
     mkdir -p $USER_HOME/.mythtv
     chown -R $USER $USER_HOME/.mythtv
     if [ ! -e $USER_HOME/.mythtv/mysql.txt ]; then
         ln -s /etc/mythtv/mysql.txt $USER_HOME/.mythtv/mysql.txt
     fi
     #create config.xml for bindings
     if [ ! -e $USER_HOME/.mythtv/config.xml ]; then
         ln -s /etc/mythtv/config.xml $USER_HOME/.mythtv/config.xml
     fi
     case "$1" in
       start)
           # Check if pcsk is already supervising this process by checking for
           # the existance of a pidfile and that it's a currently running
           # process
           PCSKPID=
           DAEMONPID=
           if [ -e "$PCSKPIDFILE" ] ; then
               read PCSKPID < "$PCSKPIDFILE"
               if [ -n "$PCSKPID" ] && [ -d "/proc/$PCSKPID" ] ; then
                   # pcsk is running, what about our daemon?
                   if [ -e "$RUNDIR/$NAME.pid" ] ; then
                       read DAEMONPID < "$RUNDIR/$NAME.pid"
                       if [ -n "$DAEMONPID" ] && [ -d "/proc/$DAEMONPID" ] ; then
                           # daemon is running too
                           log_success_msg "pcsk($NAME) (pid $PCSKPID) is \
                               already running, supervising $NAME \
                               (pid $DAEMONPID); use restart instead."
                           exit 1
                       fi
                       # daemon isn't running at the moment (pcsk might be waiting
                       # to respawn it).  Anyway, take the opportunity to restart
                       # everything now
                       log_success_msg "pcsk($NAME) (pid $PCSKPID) is running \
                           but $NAME is currently stopped.  Restarting now..."
                       $0 restart
                       exit $?
                   fi
               fi
           fi
           prime_firewire
           log_daemon_msg "Starting $DESC: pcsk($NAME) "
           # NICE gets ignored because pcsk doesn't support it and
           # start-stop-daemon would just nice pcsk, not the daemon.
           # Maybe we could somehow use renice?  Later...
           if ! start-stop-daemon --start --pidfile "$PCSKPIDFILE" --chuid $USER \
               --exec "$PCSKBINARY" -- $PCSKARGS ; then
               log_failure_msg "failed (start-stop-daemon exited with code $?)"
               log_end_msg 1
               exit 1
           fi
           log_end_msg $?
           ;;
       stop)
           log_daemon_msg "Stopping $DESC: pcsk($NAME) "
           start-stop-daemon --stop --oknodo --pidfile "$PCSKPIDFILE" \
               --chuid $USER --retry 5 --exec "$PCSKBINARY" -- $PCSKARGS
           log_end_msg $?
           [ -e "$PCSKPIDFILE" ] && rm -f "$PCSKPIDFILE"
           [ -e "$RUNDIR/$NAME.pid" ] && rm -f "$RUNDIR/$NAME.pid"
           ;;
       restart|force-reload)
           log_daemon_msg "Restarting $DESC: $NAME "
           $0 stop
           sleep 3
           $0 start
           log_end_msg $?
           ;;
       status)
           # We have an advantage in this mess that we know what the pidfiles
           # (and therefore pids) are.  Poor-man's status can be had by checking
           # for the existance of a pidfile and then that it's a currently
           # running process by looking for that directory in /proc
           PCSKPID=
           DAEMONPID=
           if [ -e "$PCSKPIDFILE" ] ; then
               read PCSKPID < "$PCSKPIDFILE"
               if [ -n "$PCSKPID" ] && [ -d "/proc/$PCSKPID" ] ; then
                   echo "pcsk($NAME) (pid $PCSKPID) is running..."
               else
                   echo "pcsk($NAME) is dead but pid file exists"
               fi
           else
               echo "pcsk($NAME) is stopped"
           fi
           if [ -e "$RUNDIR/$NAME.pid" ] ; then
               read DAEMONPID < "$RUNDIR/$NAME.pid"
               if [ -n "$DAEMONPID" ] && [ -d "/proc/$DAEMONPID" ] ; then
                   echo "$NAME (pid $DAEMONPID) is running..."
               else
                   echo "$NAME is dead but pid file exists"
               fi
           else
               echo "$NAME is stopped"
           fi
           ;;
       *)
           N=/etc/init.d/$NAME
           echo "Usage: $N {start|stop|restart|force-reload|status}" >&2
           exit 2
           ;;
     esac
     exit 0

Once you've created the script, stop the backend, copy the script to the /etc/init.d directory, rename the original script to get it out of the way and then symlink the new script as the backend startup script:

     sudo /etc/init.d/mythtv-backend stop
     sudo cp mythtv-backend.pcsk /etc/init.d/mythtv-backend.pcsk
     cd /etc/init.d
     sudo chmod ugo+x mythtv-backend.pcsk
     sudo mv mythtv-backend mythtv-backend.orig
     sudo ln -s mythtv-backend.pcsk mythtv-backend
     sudo /etc/init.d/mythtv-backend start

Finally, you'll probably want to update the logrotate config file for mythtv-backend (/etc/logrotate.d/mythtv-backend) to rotate the log file created by pcsk too, by adding the following lines to it:

     /var/log/mythtv/mythbackend-pcsk.log {
         daily
         rotate 7
         notifempty
         copytruncate
     }

Backing Up the MythTV Database

The MySQL database (named mythconverg) that is used to store all of the information used by MythTV is very important. Without it, you ain't got nothin'. MythTV's backend and frontend won't run, you won't know what shows are recorded, no upcoming shows will be recorded, you won't be able to find any of your movies on your video server, etc. Heck, if you don't look out the window, you won't even be able to tell what the weather is like.

So, it should be pretty clear that having a regular backup of this database is very, very important.

The good news is that Mythbuntu, out of the can, comes with a regular backup procedure installed. The bad news is: that it only runs once a week; that it doesn't notify you of success or failure; that it only backs itself up to the local hard disk (where the backup will get destroyed right along with the database when the hard disk goes south).

So, if you're paranoid like us, you might want to tweak the backup process a bit to make it more robust. We altered the backup script to create and keep six daily backups as well as a couple months worth of weekly epoch backups, FTP the latest backup to a remote location, and send email when the backup succeeds.

Here is a copy of the altered backup script, which can be installed in the /etc/cron.daily directory (although, see the following "Scheduling Jobs When You Want Them To Run" section) instead of /etc/cron.weekly:

/etc/cron.daily/mythtv-database:

     #!/bin/bash
     #
     # /etc/cron.daily/mythtv-database script - check and backup mythconverg tables
     #
     # Copyright 2005/12/02 2006/10/08 Paul Andreassen
     #
     # Modified 2009/12/08 by Eric Wilde
     #           Switch to daily operation. Create weekly epoch backups as well
     #           as daily backups (this lets us keep multiple weeks of epoch
     #           backups, as well as a full week of daily backups). Email backup
     #           status, if requested. FTP backup to another server, if requested.
     #           Fix documentation.
     #
     # Modified 2012/06/07 by Eric Wilde
     #           Take advantage of the new database backup script, if it is
     #           available.  Better error discovery and reporting.
     #
     # Note that the new database backup script (as of MythTV 0.25) is dain
     # bramaged when it comes to database parameter handling.  Its behavior is
     # to check for a "config.xml" file in the ".mythtv" directory of the logged
     # in user.  Since the backup script is typically run periodically by
     # dropping it into the "cron.daily" or "cron.weekly" directory, it is run
     # under the user "root".
     #
     # The default installation of Mythbuntu makes a symlink to "/etc/config.xml"
     # from "/root/.mythtv/config.xml" so that, when the backup script runs, it
     # finds "/etc/config.xml".  Unfortunately, the default installation of
     # Mythbuntu installs an empty "/etc/config.xml".  The database parameter
     # handling in the backup script finds the empty file and gives up looking
     # further, despite the fact that it hasn't found the database name,
     # database user name, or anything else needed to backup the database.
     #
     # What it should do is carry on looking for parameters in the
     # "/etc/mythtv/mysql.txt" file but it does not.  If you will be running
     # this script from either the "cron.daily" or "cron.weekly" directory, the
     # easiest fix for this problem is to delete the symlink to the bogus empty
     # config file, like this:
     #
     #   sudo rm -f /root/.mythtv/config.xml
     #
     # Should you lose the mythconverg, MySQL database and you are running a
     # pre-0.22 version of MythTV (i.e. one that doesn't have the database backup
     # script), begin by deleting what's left of the database, if anything.
     #
     # Beware that performing this step will remove the entire database.  You
     # will lose all of your settings and will need to re-run the
     # /usr/share/mythtv/sql/mc.sql script to set up the database structure
     # before running the restore.
     #
     # To delete the database, do:
     #
     #   mysql -u mythtv -p 'drop database mythconverg'
     #
     # To restore (assuming that you've dropped the database), do:
     #
     #   mysql -u mythtv -p 'create database mythconverg'
     #   /usr/share/mythtv/sql/mc.sql
     #   zcat /var/backups/mythconverg.sql.gz | mysql -u mythtv -p mythconverg
     #
     # For more information on how to drop the database and create a new database,
     # see:
     #
        http://www.mythtv.org/docs/mythtv-HOWTO-23.html#dropdb
        http://www.mythtv.org/docs/mythtv-HOWTO-6.html#setupdb
     #
     # If you need to restore the mythconverg, MySQL database under a post-0.21
     # (i.e. 0.22 and up) version of MythTV, do this:
     #
     #   ./mythconverg_restore.pl --hostname=localhost \
     #       --drop_database --create_database \
     #       --directory=/var/backups --filename=mythconverg.sql.gz
     #
     set -e -u
     # Get the mythconverg database parameters.
     if [ -f /etc/mythtv/mysql.txt ]; then
         . /etc/mythtv/mysql.txt
     fi
     # Set the options and parameters used to backup the database.
     DBNAME="mythconverg"
     BACKDIR="/var/backups"
     DEBIAN="--defaults-extra-file=/etc/mysql/debian.cnf"
     OPTIONS="--all --complete-insert --extended-insert --quick --quote-names \
         --lock-tables"
     SAVEEPOCHS=8
     EMAILSTATUS="root"
     FTPHOST="myotherserver"
     FTPUSER="mythtv"
     FTPPASSWD="abigsecret"
     # If the mysql.txt file for MythTV sets the database name, use it instead of
     # the default.
     if [ "x$DBName" != "x" ] ; then
         DBNAME=$DBName
     fi
     # Figure out which kind of a backup (daily or epoch) we're doing.  Daily is
     # M-Sa, epoch is Su.
     DayNum=`date +%w`
     if [ "x$DayNum" != "x0" ] ; then
         BackupFile="${DBNAME}-daily.sql"
         SAVEEPOCHS=6
     else
         BackupFile="${DBNAME}.sql"
     fi
     BackupPath="${BACKDIR}/${BackupFile}.gz"
     # Check the database for consistency.
     /usr/bin/mysqlcheck $DEBIAN -s $DBNAME
     # Save some copies of the backup. If we're doing the daily backup, we'll
     # always keep 6 copies (M-Sa).  If we're doing the weekly (epoch) backup,
     # we'll save as many as the user asked for.
     /usr/bin/savelog -c $SAVEEPOCHS -l -n -q $BackupPath
     # Dump and zip the database backup.  Its either a daily or epoch backup,
     # depending on which day of the week it is.
     #
     # If the backup script exists, we'll use it because, presumably, it is
     # better.  Otherwise, we just do a straight dump.  Basically, they both
     # end up running the mysqldump command.
     if [ -f /usr/share/mythtv/mythconverg_backup.pl ]; then
         /usr/share/mythtv/mythconverg_backup.pl --hostname=localhost \
             --dbname=${DBNAME} --directory=${BACKDIR} \
             --filename=${BackupFile}
     else
         /usr/bin/mysqldump $DEBIAN $OPTIONS $DBNAME | gzip > $BackupPath
     fi
     # In order to see if the backup succeeded, we test to see if a non-zero
     # file was created.  Since savelog will have moved up any previous files,
     # there should be no file with the unadorned backup file name before the
     # backup starts.  Thus, if it creates a file and fills it with some bytes
     # its a pretty good bet that it worked.
     if [ ! -s $BackupPath ]; then
         # If we're not emailing status to anyone, we're all done.  Otherwise,
         # send a failure email message to the appropriate user.
         if [ ! "x$EMAILSTATUS" != "x" ] || [ ! -f /usr/bin/mail ]; then
             exit 1
         fi
      HostName=`hostname`
      /usr/bin/mail -s "Message from MythTV, failed database backup" \
          root <<-ENDMSG

The $DBNAME database on $HostName faile to be backed up to $BackupPath
ENDMSG

      exit 1

fi

      Add a note to the log.
     /usr/bin/logger -p daemon.info -i -t${0#*/} "$DBNAME checked and backed up."
     # FTP the backup somewhere safe, just in case the local disk goes south.
     if [ "x$FTPHOST" != "x" ] && [ "x$FTPUSER" != "x" ]; then
         echo -e "user ${FTPUSER} ${FTPPASSWD}\\nbin\\nput ${BackupPath} \
             ${BackupFile}.gz" | ftp -n $FTPHOST
     fi
     # If we're not emailing status to anyone, we're all done.  Otherwise, send an
     # email message to the appropriate user.
     if [ ! "x$EMAILSTATUS" != "x" ] || [ ! -f /usr/bin/mail ]; then
         exit 0
     fi
     HostName=`hostname`
     /usr/bin/mail -s "Message from MythTV, database backup" root <<-ENDMSG
     The $DBNAME database on $HostName has been successfully backed up
     to $BackupPath
     ENDMSG
     # End of file.

Note that you should remove the original mythtv-database script from the /etc/cron.weekly directory so that it doesn't run once a week and conflict with the running of this script. You can simply delete it or move it to some other directory, if you feel the need to keep it.

If you are running on a later version of MythTV (i.e. 0.22 or greater), you also need to remove the symlink in /root/.mythtv, like this:

     sudo rm -f /root/.mythtv/config.xml

To have the script email a completion message to you when it runs, set the EMAILSTATUS variable to the email address that you wish to send the message to. In the example, we've set EMAILSTATUS to "root". If you don't wish to send email anywhere, set EMAILSTATUS to "".

To have the script FTP a copy of the database to another server, you first need to set up a userid on that server. We use another Linux server and set the user's login script to /sbin/nologin so that nobody can actually login on that userid. The userid should, however, be created with a home directory so that FTP has somewhere to drop the files.

The name of the server should be set in the FTPHOST variable (in this case we've used "myotherserver") and the userid and password should be set in the FTPUSER and FTPPASSWD variables (in this case we've used "mythtv" and "abigsecret"). By setting FTPHOST and FTPUSER to something other than "", we cause the script to copy the database backup file to another server, where it will be safe if anything happens to Mythbuntu. The files will be copied to the home directory of the "mythtv" user on that server.

We then use the following logrotate file to rotate the copied files once a week and thereby keep a number of copies on the backup server:

/etc/logrotate.d/mythtv-database:

     /home/mythtv/mythconverg.sql.gz {
         missingok
         notifempty
         nocreate
         rotate 8
     }

In this case, we're keeping eight copies of the backup file and rotating once a week so we have eight weeks of backups.

>>>>>>
Scheduling Jobs When You Want Them To Run


Since Ubuntu, the platform which Mythbuntu is built upon, is primarily intended to be a laptop and personal workstation product, it has features which are meant to

/etc/stability

     mythtv-database

Rebooting

Move anacron stuff to:

     04:07 hourly
     04:17 daily
     04:27 weekly
     04:37 monthly

Reduce the xfs_fsr time to 6600 from 7200.

/etc/stability

     sysreboot

))))))
#!/bin/sh
#
# Shell script to reboot the system at regular intervals to heal all of # the Myth infelicities like recordings that never end, encoders that # don't get reset properly, lockups, etc., etc. #
/sbin/shutdown -r now
((((((

     /sbin/shutdown -r now
     -rwxr-x---

<<<<<<

Displaying MythTV Status at Login

>>>>>>
<<<<<<
By default, Mythbuntu installs an init script in /etc/init.d, called mythtv-status, and a similarly-named cron file in /etc/cron.d. The purpose of these two files are to cause current MythTV status to be written to the message of the day file (/var/run/motd) at regular intervals (every 10 minutes).

Unfortunately, the script, as installed, is broken. It fails to update the message of the day file and, if you enable sendmail for mail delivery, generates a windge email every cycle. Furthermore, the motd.new file that it creates isn't removed on shutdown, leading to the message of the day file being corrupted, if it is restarted. So, if you want actual status in your message of the day file, or don't want your mailbox filled up with 144 idiot messages every day, or want to be able to update the message of the day file, you need to fix the script. Here's our take on it:

     #!/bin/sh 
     #
     # Copyright (c) 2007 Javier Fernandez-Sanguino <jfs@debian.org>
     #
     # This is free software; you may redistribute it and/or modify
     # it under the terms of the GNU General Public License as
     # published by the Free Software Foundation; either version 2,
     # or (at your option) any later version.
     #
     # This is distributed in the hope that it will be useful, but
     # WITHOUT ANY WARRANTY; without even the implied warranty of
     # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     # GNU General Public License for more details.
     #
     # You should have received a copy of the GNU General Public License with
     # the Debian operating system, in /usr/share/common-licenses/GPL;  if
     # not, write to the Free Software Foundation, Inc., 59 Temple Place,
     # Suite 330, Boston, MA 02111-1307 USA
     #
     ### BEGIN INIT INFO
     # Provides:          mythtv-status
     # Required-Start:    $mythtv-backend
     # Required-Stop:     
     # Should-Start:      $named
     # Should-Stop:       
     # Default-Start:     2 3 4 5
     # Default-Stop:      0 1 6
     # Short-Description: Update the MOTD with the MythTV status
     # Description:       Update the MOTD with the MythTV status
     ### END INIT INFO
     PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
     DAEMON=/usr/bin/mythtv-status # Introduce the server's location here
     NAME=mythtv-status            # Introduce the short server's name here
     DESC="MythTV Status"          # Introduce a short description here
     test -x $DAEMON || exit 0
     . /lib/lsb/init-functions
     # Include defaults if available
     if [ -f /etc/default/$NAME ] ; then
     . /etc/default/$NAME
     fi
     # Use this if you want the user to explicitly set 'RUN' in 
     # /etc/default/
     if [ "x$RUN" != "xyes" ] ; then
     log_failure_msg "$NAME disabled, please adjust the configuration to \
         your needs "
     log_failure_msg "and then set RUN to 'yes' in /etc/default/$NAME to \
         enable it."
     exit
     fi
     set -e
     case "$1" in
     start|reload|refresh|restart|force-reload)
       log_daemon_msg "Updating $DESC" "$NAME"
       [ ! -f /var/run/motd.orig ] && cp /var/run/motd /var/run/motd.orig
     $DAEMON $ARGS -h $HOST >/var/run/motd.new 2>/dev/null
     if [ -f /var/run/motd.new ]; then
       cat /var/run/motd.orig /var/run/motd.new >/var/run/motd 2>/dev/null
       touch "/var/run/$NAME" 
     else
       if [ -f /var/run/motd.orig ]; then
         cp /var/run/motd.orig /var/run/motd
       else
         rm -f /var/run/motd 2>/dev/null
       fi
      rm -f "/var/run/$NAME" 2>/dev/null || true

fi
log_end_msg 0
;;
stop)
log_daemon_msg "Stopping $DESC" "$NAME" [ -f /var/run/motd.orig ] && cp /var/run/motd.orig /var/run/motd rm -f /var/run/motd.orig 2>/dev/null rm -f "/var/run/$NAME" 2>/dev/null || true log_end_msg 0
;;
status)
if [ -f "/var/run/$NAME" ]; then

      log_success_msg "$NAME is running"
      exit 0
    else
      log_failure_msg "$NAME is not running"
      exit 1

fi
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|reload|refresh|status}" >&2 exit 1
;;
esac

     exit 0

Freeing Up Storage

No matter how big your storage pools are, it seems that the recorded content always expands to fit the space available. If you are like us, you never manage to get enough time to watch everything you want to watch so that, eventually, you are bound to start running out of space for new recordings. When the time comes, you could just buy some larger hard drives or you could bite the bullet and clean up the disks instead.

In this section, we describe two scripts that can help you make the decision as to which recording files are orphaned from the database, using up space for nothing, and can simply be deleted, which remaining programs should be watched first to free up the most space immediately, and which programs are so old that you'll likely never watch them.

Obviously, orphaned recording files are the low hanging fruit, since nobody even knows that they exist. Despite its best efforts to keep track of things, sometimes orphaned recordings are created when MythTV loses the database pointer to a recording file in a storage group, especially when storage groups are spread across multiple systems. This occurs most often when database updates are done on the master backend without the benefit of communication with the secondary backends (e.g. when a network connection goes down).

For example, MythTV will occasionally ask you if you want to delete a database entry (i.e. for a recorded program) despite the fact that the file associated with it cannot be found. The reason may well be that MythTV querried the remote, secondary backend that owns the file but the secondary backend didn't respond. The clever MythTV code then assumes that the file doesn't exist (not that we can't talk now because the network is down). If you allow it to proceed with the database delete, an orphaned file will be created.

On other occasions, power failures, system failures, etc., may lead to orphaned files with no database entries. Regardless of how they are created, orphaned files occupy space, thereby reducing the amount of recording capacity available and leading to a cluttered storage groups. When you only have three or four terabytes of storage left for recording, it's not a good thing (tm). MythTV has no idea that these files even exist so it's never going to do anything about them.

A special script that just looks for orphans and optionally cleans them up can be installed somewhere on your MythTV backends. This script will also look for associated tumbnail image files that have not been deleted, as well as orphaned image files themselves. A good spot to install it is in /usr/local/bin:

     #!/bin/bash
     #
     # orphan - Shell script to find all orphaned MythTV recordings.
     #
     #
     # Usage
     # -----
     #
     # orphan [-r] storage_path [host] [user] [password]
     #
     # The optional flag parameters, if specified, must come first.  These
     # parameters begin with '-' and are as noted above.
     #
     #      -r                Causes any orphans to be automatically removed.
     #
     #      storage_path      The full path (minus trailing slash) of the
     #                        storage directory that is to be checked for orphan
     #                        recordings.
     #
     #      host              The optional, remote host where the database is
     #                        kept.  If you are running this script on a
     #                        secondary backend, you should supply the hostname
     #                        of the master backend.  The default is no
     #                        hostname, which will cause the the query to be run
     #                        on localhost.
     #
     #      user              The optional user name to connect to the database
     #                        with.  The default, if omitted, is obtained from
     #                        the MythTV "mysql.txt" file.  If this file cannot
     #                        be found, the default is "mythtv".
     #
     #                        Typically, you would need to supply this parameter
     #                        if you are using a remote host for the database
     #                        and the local "mysql.txt" file doesn't exist or
     #                        has an incorrect user name.
     #
     #      password          The optional password for the user chosen.  The
     #                        default, if omitted, is obtained from the MythTV
     #                        "mysql.txt" file.  If this file cannot be found,
     #                        the default is "mythtv" (yeah, like that'll work
     #                        -- you should probably use the password that you
     #                        set when you configured MythTV).
     #
     #                        Typically, you would need to supply this parameter
     #                        if you are using a remote host for the database
     #                        and the local "mysql.txt" file doesn't exist or
     #                        has an incorrect password.
     #
     #
     # Description
     # -----------
     #
     # This script can be used by the user, when they are running out of space,
     # to delete MythTV recordings that are orphaned.  An orphaned recording is
     # one that is found in the recordings storage directory but which is not
     # referenced in the MythTV database.
     #
     # Orphans can be safely deleted so the "-r" flag can be used to
     # automatically remove them, although you may want to run this script
     # without the "-r" flag first, to see what it is thinking of deleting.
     # Otherwise, cleanup can be done maually by the user from the command line.
     #
     #
     # Revision History
     # ----------------
     #
     # E. Wilde    2009Oct6   Initial coding.
     # E. Wilde    2018Jun22  Use mysql.txt, automatically remove orphans, scan
     #                        for orphaned image files.
     #
     ##########################################################################
     #
     # The possible locations of the MythTV "mysql.txt" file, in order of usage.
     #
     MythConfigs=("/etc/mythtv/mysql.txt" \
         "/usr/local/share/mythtv/mysql.txt" \
         "/usr/share/mythtv/mysql.txt" \
         "/usr/local/etc/mythtv/mysql.txt")
     #
     # Default values.  You can change these, if you don't want to have to
     # supply these values on the command line all the time.
     #
     DefUser="mythtv"
     DefPasswd="mythtv"
     #
     # Flags for automatic removal, etc.
     #
     AutoClean="no"
     #
     # Let's see if we can figure out the MythTV database userid and password.
     #
     for MythConfig in "${MythConfigs[@]}"; do
         if [ -f $MythConfig ]; then
             . $MythConfig
          if [ x"$DBUserName" != "x" ]; then
              DefUser=$DBUserName
          fi
          if [ x"$DBPassword" != "x" ]; then
              DefPasswd=$DBPassword
          fi
      fi

done
#
# Next, examine any parameters passed to this script to see if they begin # with a dash, thereby indicating an optional flag. These must occur first # because, as soon as the first parameter without a dash occurs, we're # done.
#
# Also note that single letter flags must occur before multiple letter # flags, in case the single letter flags start with the same letter.
while [ $
!= 0 ]; do

      if [ "${1:0:1}" == "-" ]; then
          case "$1" in
              -r)
                  AutoClean="yes"
                  ;;
          esac
      else
          break
      fi
      shift

done
#
# See if there's a storage path supplied. #
if [ x"$1" == "x" ]; then

      echo Storage directory path omitted
      exit 1

fi

     if [ ! -d $1 ]; then
         echo Storage directory $1 not found
         exit 1
     fi
     #
     # See if there's a hostname supplied.
     #
     if [ x"$2" == "x" ]; then
         Host=""
     else
         Host=" -h$2"
     fi
     #
     # See if there's a userid and password supplied.
     #
     if [ x"$3" == "x" ]; then
         Userid=$DefUser
     else
         Userid=$3
     fi
     if [ x"$4" == "x" ]; then
         Password=$DefPasswd
     else
         Password=$4
     fi
     #
     # Get a listing of all of the recording files in the given directory and
     # see if they're referenced in the database.
     #
     ls -1 $1/.avi $1/.m4v $1/.mkv $1/.mp4 $1/.mpg $1/.nuv 2>&1 | \
         while read Line; do
         #
         # Strip the path name off the recording file name.  Only the file names
         # are stored in the database.  Note that the file names can contain
         # spaces so you need to use double quotes around them.
         #
         File=`echo $Line | sed -ne "s|.$1/\(.\)|\1|p"`
      if [ ! -f "$1/$File" ]; then continue; fi
      #
      # Let's see if we can find the recording in the database.
      #
      Status=`mysql -e "select chanid from recorded where basename='$File';" -N -u$Userid -p$Password$Host mythconverg`
      if [ x"$Status" == "x" ]; then
          #
          # Remove it, if we were asked to do so.
          #
          if [ "x$AutoClean" == "xyes" ]; then
              echo Recording $File is orphaned, removed
              rm -f $1/$File >/dev/null 2>&1
              ls -1 $1/$File.png 2>&1 | while read List; do
                  Image=`echo $List | sed -ne "s|.$1/\(.\)|\1|p"`
                  if [ ! -f "$1/$Image" ]; then continue; fi
                  echo "  Image $Image also removed"
                  rm -f $1/$Image >/dev/null 2>&1
              done
          else
              echo Recording $File is orphaned
          fi
      fi
     done
     #
     # Now that we've (possibly) deleted all of the orphan recording files, get
     # a listing of all of the image files in the given directory and see if
     # their associated recording files are referenced in the database.
     #
     ls -1 $1/.png 2>&1 | while read Line; do
         #
         # Strip the path name off the recording file name.  Only the file names
         # are stored in the database.  Note that the file names can contain
         # spaces so you need to use double quotes around them.
         #
         Image=`echo $Line | sed -ne "s|.$1/\(.*\)|\1|p"`
      if [ ! -f "$1/$Image" ]; then continue; fi
      #
      # Strip the ".png" extension off the file so that we can look for the
      # associated recording file.
      #
      File=`echo $Image | \
          sed -rne "s/^(.\.(avi|m4v|mkv|mp4|mpg|nuv))\\..$/\1/p"`
      #
      # Let's see if we can find the recording in the database.
      #
      Status=`mysql -e "select chanid from recorded where basename='$File';" -N -u$Userid -p$Password$Host mythconverg`
      if [ x"$Status" == "x" ]; then
          #
          # Remove it, if we were asked to do so.
          #
          if [ "x$AutoClean" == "xyes" ]; then
              echo Image $Image is orphaned, removed
              rm -f $1/$Image >/dev/null 2>&1
          else
              echo Image $Image is orphaned
          fi
      fi
     done
     #
     # That's all for Ray Nance.
     #
     exit 0

However, before you proceed with cleaning up all of the orphans, we should note that the contrib directory has a Perl script which can be used to identify orphaned recording files and optionally reinsert them into the database. If you wish to use it to recover orphaned recordings instead of just deleting them, you should unzip it and install it somewhere where it can be run (e.g. /usr/local/bin):

     su
     cp /usr/share/doc/mythtv-backend/contrib/myth.rebuilddatabase.pl.gz
        /usr/local/bin
     cd /usr/local/bin
     gunzip myth.rebuilddatabase.pl.gz
     chmod ugo+ myth.rebuilddatabase.pl

Information about how to run this script can be found at:

     http://www.mythtv.org/wiki/Myth.rebuilddatabase.pl

Further good candidates for cleanup are old recordings that have been hanging around forever and that are large in size (depending on the source, capture method and content type, the file size of a recording on disk can bear little relationship to its length in minutes). If you are ever planning to watch these recordings, watching the largest ones first can be the most productive in terms of reclaiming space. If you aren't going to watch these recordings, seeing them listed as really old could provide you with the incentive needed to delete them.

Even when it comes to recent recordings, watching the largest ones first can give back the most space in the least amount of viewing time. Thus, using a list of recordings ordered by disk size, to assist you with deciding which recordings to watch first, will prove to be the most fruitful approach when space needs to be reclaimed.

Finally, depending on your setting of the number of days to keep deleted recordings before really deleting their recording files, deleted files can hang around for some time before their space is released. By listing all of the deleted files, you can decide to delete them manually, ahead of time, if you really want to reclaim the space sooner.

The cleanup script, shown below, can be used to assist with choosing which orphaned recording files to delete, which recordings to watch first, and which old recordings to simply delete. It can be installed in /usr/local/bin as well:

     #!/bin/bash
     #
     # cleanup - Shell script to help the user clean up MythTV recordings.
     #
     #
     # Usage
     # -----
     #
     # cleanup storage_path [age] [host] [user] [password]
     #
     #      storage_path      The full path (minus trailing slash) of the storage
     #                        directory that is to be checked for orphaned and
     #                        aged recordings.
     #
     #                        Note that you can give a list of storage
     #                        directories to check by enclosing the list in
     #                        double quotes and separating each individual
     #                        path by a space.
     #
     #      age               The optional age in days.  Any recordings that are
     #                        older than this many days should be included in the
     #                        list of recordings to be cleaned up.  The default,
     #                        if omitted, is 365.
     #
     #      host              The optional, remote host where the database is
     #                        kept.  If you are running this script on a
     #                        secondary backend, you should supply the hostname
     #                        of the master backend.  The default is no hostname,
     #                        which will cause the the query to be run on
     #                        localhost.
     #
     #      user              The optional user name to connect to the database
     #                        with.  The default, if omitted, is obtained from
     #                        the MythTV "mysql.txt" file.  If this file cannot
     #                        be found, the default is "mythtv".
     #
     #                        Typically, you would need to supply this parameter
     #                        if you are using a remote host for the database
     #                        and the local "mysql.txt" file doesn't exist or
     #                        has an incorrect user name.
     #
     #      password          The optional password for the user chosen.  The
     #                        default, if omitted, is obtained from the MythTV
     #                        "mysql.txt" file.  If this file cannot be found,
     #                        the default is "mythtv" (yeah, like that'll work
     #                        -- you should probably use the password that you
     #                        set when you configured MythTV).
     #
     #                        Typically, you would need to supply this parameter
     #                        if you are using a remote host for the database
     #                        and the local "mysql.txt" file doesn't exist or
     #                        has an incorrect password.
     #
     #
     # Description
     # -----------
     #
     # This script can be used by the user, when they are running out of space,
     # to decide which MythTV recordings should be cleaned up.  Cleanup must be
     # done maually by the user, either through the MythTV UI or, in the case of
     # orphaned recordings, using the "orphan" script or from the command line.
     #
     # Orphaned recordings are listed first since the user will, presumably,
     # want to delete them right away.  Recordings that are marked as deleted
     # but which have not yet been deleted are listed next -- the user may want
     # to hasten their demise.  Finally, the listing of old programs then
     # follows in order, sorted by size.  The expectation is that the user then
     # watches the largest ones first and deletes the recordings.
     #
     # Given the premise of the preceding paragraph, for orphaned files, the
     # file name is listed.  The user can delete them from the command line with
     # "rm", or they can use the "orphan" script to delete them automatically
     # (this is probably a good idea, since it also cleans up the image turd
     # files that MythTV loves to leave lying around).  For programs that aren't
     # orphaned but that meet the age cutoff, the program name, instead of the
     # file name, is given, along with the program's size, so that the user can
     # find the program in MythTV's recorded programs listing and watch it.
     #
     #
     # Revision History
     # ----------------
     #
     # E. Wilde    2012May7   Initial coding.
     # E. Wilde    2012Oct24  Use mysql.txt, allow multiple paths, prioritize
     #                        orphan reporting.
     # E. Wilde    2018Jun22  Look for deleted recordings.
     #
     ##########################################################################
     #
     # The possible locations of the MythTV "mysql.txt" file, in order of usage.
     #
     MythConfigs=("/etc/mythtv/mysql.txt" \
         "/usr/local/share/mythtv/mysql.txt" \
         "/usr/share/mythtv/mysql.txt" \
         "/usr/local/etc/mythtv/mysql.txt")
     #
     # Default values.  You can change these, if you don't want to have to
     # supply these values on the command line all the time.
     #
     DefAge=365
     DefUser="mythtv"
     DefPasswd="mythtv"
     #
     # Let's see if we can figure out the MythTV database userid and password.
     #
     for MythConfig in "${MythConfigs[@]}"; do
         if [ -f $MythConfig ]; then
             . $MythConfig
          if [ x"$DBUserName" != "x" ]; then
              DefUser=$DBUserName
          fi
          if [ x"$DBPassword" != "x" ]; then
              DefPasswd=$DBPassword
          fi
      fi

done
#
# See if there's a storage path supplied. #
if [ x"$1" == "x" ]; then

      echo Storage directory path omitted
      exit 1

fi

     if [ ! -d $1 ]; then
         echo Storage directory $1 not found
         exit 1
     fi
     #
     # See if there's an age supplied.
     #
     if [ x"$2" == "x" ]; then
         Age=$DefAge
     else
         Age=$2
     fi
     #
     # See if there's a hostname supplied.
     #
     if [ x"$3" == "x" ]; then
         Host=""
     else
         Host=" -h$3"
     fi
     #
     # See if there's a userid and password supplied.
     #
     if [ x"$4" == "x" ]; then
         Userid=$DefUser
     else
         Userid=$4
     fi
     if [ x"$5" == "x" ]; then
         Password=$DefPasswd
     else
         Password=$5
     fi
     #
     # Start with the title.
     #
     echo Recordings stored in: $1
     #
     # Create a temp file that we can use for sorting.
     #
     TmpFile=`mktemp /tmp/CleanupRecorded.XXXXXXXXXX`
     if [ ! $TmpFile ]; then
         echo Unable to create temporary file, sorting not possible
     fi
     #
     # Process all of the paths that we were given.
     #
     for MythPath in $1; do
         #
         # Get a listing of all of the recording files in the given directory,
         # that are older than the time given, and get their information from
         # the database.
         #
         find $MythPath -mtime +$Age \
                 -regex '.\(avi\|m4v\|mkv\|mp4\|mpg\|nuv\)' | \
             while read Line; do
                 #
                 # Strip the path name off the recording file name.  Only the file
                 # names are stored in the database.
                 #
                 File=`echo $Line | sed -ne "s|.$MythPath/\(.*\)|\1|p"`
              if [ ! -f "$MythPath/$File" ]; then continue; fi
              #
              # Let's see if we can find the recording in the database.  If
              # not, it is orphaned.  All of the orphans are listed first
              # since, presumably, the user will want to delete them right
              # away.  Deleted files are listed next.
              #
              Info=`mysql -e "select recgroup, title, starttime, subtitle from recorded where basename='$File';" -N -u$Userid -p$Password$Host mythconverg`
              #
              # Strip off the recording group.
              #
              RecGroup=`echo $Info | sed -ne "s/^\([a-zA-Z0-9]\) .$/\1/p"`
              Info=`echo $Info | sed -ne "s/^[a-zA-Z0-9] \(.\)$/\1/p"`
              #
              # Decide whether the file is orphaned, deleted, or still in
              # play.
              #
              if [ x"$Info" == "x" ]; then
                  echo Recording $File is orphaned
              else
                  FileSize=`stat -c %s $MythPath/$File`
                  if [ x"$RecGroup" == x"Deleted" ]; then
                      echo Recording $File is marked deleted
                      echo "  $FileSize, $Info"
                  else
                      if [ $TmpFile ]; then
                          echo $FileSize, $Info >>$TmpFile
                      else
                          echo $FileSize, $Info
                      fi
                  fi
              fi
          done
      done

#
# If we were able to capture the output, sort it in order of descending # size.
#
if [ $TmpFile ]; then

      sort -nr $TmpFile
      rm -f $TmpFile

fi
#
# That's all for Ray Nance.
#
exit 0

MythTV seems to be able to loose other files and database entries as well as the orphans mentioned above. On one occasion a backend was found to be hoarding deleted files from years ago. This being the case, you might want to check the deleted recordings by hand, using MySQL:

     mysql -uroot -p mythconverg
       select title, starttime, lastmodified, deletepending as dp
         from recorded where recgroup='Deleted' order by lastmodified asc;

This will show you all of the files that are pending deletion. The last modified date indicates when the file was deleted. If that date is a long time ago (MythTV calculates the retention period for deleted files as the delta between today's date and the last modified date), you know that MythTV has lost the deleted file and it ain't never going to get deleted. You can delete it by hand (don't forget to delete any associated image files).

You can also check to see if any of the deleted recordings don't have a recording file in any of the storage groups. If that's the case, you can use MySQL to delete the recording entry:

     mysql -uroot -p mythconverg
       delete from recorded
         where title='xxxx'
           and starttime='yyyy-mm-dd hh:mm:ss'and recgroup='Deleted';

As a matter of fact, if you simply delete a recording's recorded record like this and then run the orphan script (above), with the "-r" flag, all of the deleted recordings that you wish to get rid of will be cleaned up, along with any associated image files, an you'll be in business.

Lastly, as we noted above, what MythTV does with deleted files depends on your setting of the number of days to keep deleted recordings before their recording files are really deleted. If you wish to see all of the pertinent delete paramters, you can select their rows using MySQL:

     mysql -uroot -p mythconverg
       select * from settings where value like '%delete%';

Update Manager -- Not Another Good Idea

Later versions of Mythbuntu come with a version of the Update Manager that is configured to pop up a window and ask the user if they want to perform the updates on the spot. I suppose this could be construed as desirable behavior in some instances but it will come as a huge surprise to anyone using Mythbuntu.

The Update Manager pops up at some random time, when it decides that updates are available or it is time to nag the user, and is given the focus, as a consequence. However, the Myth frontend application remains in the foreground thereby obscuring the Update Manager. This effectively redirects keyboard input to a hidden application which has no idea what to do with it. The viewer is frantically pushing keys on the remote contro, to get their program to pause, rewind, skip commercials, etc., etc. but to no avail. They have no idea that the Update Manager is sucking up all of their key presses and throwing them in the trash, because it is invisible, so they think the system has crashed. Its all pretty comical.

There are two ways to disable the update-manager popup. The first is from the Mythbuntu system, using the gconf-editor application. This secret application allows you to change Gnome desktop settings. You may have to install it (since it is not installed by default) using the package manager or via:

     sudo apt-get install gconf-editor

Once you've installed the editor, you can pick it from the System menu, if it is there, or launch it from a command window via:

     gconf-editor&

The editor window will appear. You should navigate your way through the tree to the apps/update-notifier settings. There you will see a setting named "auto_launch" which has a checkbox for its value. Uncheck that box. Even if the box isn't checked, check it and uncheck it. This will acutally force the setting to be written to the configuration, which it probably wasnt't before. The default behavior (always do whatever is most annoying) needs to be overridden, which it will be when you exit from the editor window.

The alternative method is to run this command, from a SSH terminal session, while you are logged in as the user the normally runs the Myth frontend (this is very important):

     gconftool -s --type bool /apps/update-notifier/auto_launch false

Note that, if you run this command as root or some other user, since the Gnome settings are stored in the user's home directory, the auto launch flag will not have any effect on the session that runs the Myth frontend (i.e. the annoying behavior will still be with us).

However, you may want to run this command while logged in as root, so that when you log in as root (you did remember to set the root password, above, didn't you) you won't be annoyed by the Update Manager either.

You can check that the auto launch flag has been properly set by looking in the home directory of the user. Doing:

     ls -l /home/mythuser/.gconf/apps/update-notifier

Should show something like:

     -rw-r--r-- 1 mythuser mythuser    113 2009-09-11 09:15 %gconf.xml

If you display this file, you should see something like:

     <?xml version="1.0"?>
     <gconf>
       <entry name="auto_launch" mtime="1252674870" type="bool" value="false"/>
     </gconf>

The Update Manager also comes preconfigured to nag the user in other ways, besides the popup that is disabled above. For example, it will periodically pop up a modal dialog box to show the user a list of updates and system upgrades. The dialog box is not hidden but, even if the user can figure out how to move the mouse over the dialog box (mostly, the mouse is hidden, under the Mythbuntu frontend application), you probably don't want them applying the updates or upgrading the system by accident.

The best approach, in our opinion, is to launch the Update Manager from the System menu and the click on the Settings button. From the dialog box that pops up, change the "Automatically check for updates" field to "Never" and the "Notify me of a new Ubuntu version" to "Never". When the windge dialog box that says you must check for updates manually appears, check the box about never showing me this again Once you close this final dialog box and exit the Update Manager, you should experience no further problems.

Useful Software

The Synaptics Package Manager is a GUI-based application which is useful for adding and removing packages to/from your system. The Ubuntu Software Center is not. Many users who upgrade to a later version of Mythbuntu, from an earlier version, will miss the Synaptics Package Manager. The won't find the selling of magazine subscriptions by their package manager, while they are trying to install software, to be an amusing feature. Fortunately, you can easily add the Synaptics Package Manager back in, from the command line, like this:

     sudo apt-get install synaptic

The "Useless and Annoying Software" section details how the Ubuntu Software Center package can be removed, if you don't wish to keep it around (and, why would you).

Using the Synapics Package Manager, you can install all of the useful packages you'll ever need. Here is a list of some of the one's that we've found useful:

     emacs
     vsftpd
     sendmail (if you'd like email delivery)
     mailutils (mail utilities such as "mail")

You can also install these packages using apt-get, as follows:

     sudo apt-get install emacs
     sudo apt-get install vsftpd
     sudo apt-get install sendmail
     sudo apt-get install mailutils

EMACS

If you installed EMACS and you intend to use it for all of your editing needs, probably the very first thing you will want to do is to configure it not to leave turds lying around everywhere. That way, you can then edit files with impunity and not have to worry about cleaning up Stallman's mess everywhere you go. Edit both the ~/.emacs and the /root/.emacs (if you'll do any editing as root). Add, at least:

     (custom-set-variables
     '(make-backup-files nil))
     (custom-set-faces)

Another annoying feature (or should we say, non-feature) is the behavior of the latest EMACS versions whereby filename completion, which used to be bound to the space bar, no longer works. Apparenly, the whiners convinced the developers (in a rare display of political correctness stupidity) that an existing feature, which has been around forever, should be turned off, by default, to accomodate a small group of really annoying people who are dumb enough to want to put blanks in their file names. God help us. The Macintosh winkies are taking over.

At least we aren't so clueless to not know how to fix default behavior that we don't like by editing the config file. Heaven help us if those few idiots who actually use blanks in their file names should have to figure that one out. Better to f**k the rest of us. Well, if you don't like it, try adding the following to the EMACS config files mentioned above:

     (define-key minibuffer-local-filename-completion-map
       " " 'minibuffer-complete-word)
     (define-key minibuffer-local-must-match-filename-map
       " " 'minibuffer-complete-word) 

VSFTPD

The VSFTP daemon comes preconfigured for anonymous FTP only. And, the default timeouts don't allow much time for thinking about what you want to send/receive. If you're like us, you want to hack the configuration file (/etc/vsftpd.conf) and set the following:

     local_enable=YES
     write_enable=YES
     local_umask=022
     pasv_promiscuous=YES             # if you want PASV to actually work
     idle_session_timeout=7200        # if you want a couple of hours timeout

Sendmail

If you wish email messages to be delivered from the various automatic subsystems on your Mythbuntu machine, you can install sendmail and the mailutils packages (see above) on the system. Then, you can hack sendmail.mc on the Mythbuntu machine to use your regular SMTP server to relay the mail. Begin by adding a SMART_HOST line at the end of the macro file (probably /etc/mail/sendmail.mc) and aim it at your SMTP server:

     dnl #
     dnl # Smart host (the guy who really delivers the mail)
     dnl #
     define(`SMART_HOST',`pri-host')dnl

Rebuild the sendmail.cf file:

     sudo sendmailconfig

Answer yes to all of the questions. This will restart sendmail at the same time.

You should now be able to send mail to the main mail server from the local Mythbuntu machine (if relaying is denied, you may need to add the Mythbuntu machine's address to relay-domains on the mail server). You also might want to alias the following users in /etc/aliases on the local machine:

     root: joeblow@mydomain.com
     mythuser: joeblow@mydomain.com

Where "mythuser" is the name of the user that Mythbuntu was installed under (i.e. the initial user from setup) and joeblow@mydomain.com is the name of the user whom the mail should delivered to on the smart host.

As long as the aliased name contains a domain name, it will be forwarded by the local sendmail to the SMART_HOST. If the domain name is marked as a local domain on the main mail server, the mail will get delivered there. Note that you need to rebuild the aliases database and then recycle sendmail on the Mythbuntu machine when you add aliases to /etc/aliases:

     sudo newaliases
     /etc/init.d/sendmail restart

Useless and Annoying Software

Mythbuntu installations are coming with more and more useless packages pre-installed. Why should M$ platforms be the only platforms that come with craplets, crapware and bloatware? Linux (and especially Ubuntu) should get in on the game. Looks like we're taking this idea to heart.

One particularly useless as well as annoying piece of crapware is the Ubuntu Software Center. Not only is this an especially lame attempt at a package manager but it also tries to sell you magazine subscriptions as you go. Who needs this junk? The Synaptics Package Manager (see the "Useful Software" section) works quite well, thank-you very much. To get rid of the Ubuntu Software Center, you can enter this command on the command line:

     sudo apt-get purge software-center

Another really annoying "feature" is Zeroconf and the daemon that implements it, AVAHI. This feature is a misguided attempt to make all of your computers work like Macs, with their plug 'n pray Bonjour protocol. Just plug your computer into a network port and it will figure everything out. An idiot could do it. Sadly, if you're an idiot, you won't be using Mythbuntu since it is difficult to operate itself and way above the idiot level, so software for idiots like Zeroconf just gets in the way.

Unfortunately, for our purposes and especially when we're running a master backend, we need to know the IP address of each machine. We can't have some well-meaning but misguided piece of crapware making up IP addresses for us. But, that's just what AVAHI does. If your DHCP server is a wee bit slow to respond, AVAHI will make up an incorrect IP address for you and then nothing will work. Or, if you forget to assign a static IP address, same thing. Hours of debugging fun will then follow, since your network will appear to be working but nothing will be where you think it is. And how about this? If your network connection goes down, even for a few seconds, AVAHI steps in, makes up an IP address and then all of your other network addresses stop working when the network comes back. Who dreams this stuff up?

To get rid of Zeroconf, it is simply necessary to get rid of AVAHI:

     apt-get purge avahi-autoipd avahi-daemon

Once you're done, you can yo-yo the network down/up. On earlier versions of Mythbuntu, this was easy, simply requiring a few commands to be typed on the console. With the later versions of Mythbuntu, that use upstart, this theoretically can be accomplished with:

     sudo stop networking
     sudo start networking

Although, under Mythbuntu 12.04LTS, this method doesn't work and seems to leave networking sort of in limbo (nice work, guys -- that upstart thingy is a real winner). Of course, the ultimate test is to reboot the system, which works even when upstart doesn't. Either way, listing the routes on the system should show that everything is working OK:

     /sbin/route

You should see something like this (with no mention of link-local or any 169.254.x.x addresses):

     Kernel IP routing table
     Destination     Gateway        Genmask         Flags Metric Ref   Use Iface
     default         192.168.1.1 0.0.0.0         UG    100    0       0 eth0
     192.168.1.0     *              255.255.255.0   U     0      0       0 eth0

CUPS or the Common Unix Printing System is a fine system that does an excellent job of spooling printed output to all sorts of printers. Its just not something that most people need to have installed on their media computers. If you don't think you'll be wanting to print anything from your Mythbuntu system, you may wish to uninstall CUPS like this:

     sudo apt-get purge cups

These packages auto-install a number of packages which may not be needed after the useless packages have been purged. You can remove them, once you've removed all of the useless packages, by running:

     sudo apt-get autoremove

MythWeather

MythWeather can be installed on the later versions of Mythbuntu by selecting it from the list of plug-in applications from the Mythbuntu configuration application (either run this app from the System menu choice or run it by selecting Mythbuntu setup from the frontend setup menu. Once MythWeather is installed, setup should be easy (or so you think). A good synopsis of the vanilla part of setup is given here:

     http://www.mythtv.org/wiki/MythWeather

Fortunately, all of the code that extracts weather data from remote sites via HTTP is written in Perl so that it can be easily modified. Unfortunately, it is quite badly written. If any of the extracted weather data changes in the slightest, the Perl code craps out and the MythWeather display either hangs or shows a blank screen.

The worst offender is the NWS XML extraction module that is used to obtain current weather information from the National Weather Service -- probably the one script you're most likely to want to use. Consequently, if you want to see the current weather, you'll probably have to patch the extraction module as follows (all changes are marked with #ew):

/usr/share/mythtv/mythweather/scripts/us_nws/nwsxml.pl:

     #! /usr/bin/perl -w
     use strict;
     use XML::Simple;
     use LWP::Simple;
     use Data::Dumper;
     use Getopt::Std;
     use NWSLocation;
     our ($opt_v, $opt_t, $opt_T, $opt_l, $opt_u, $opt_d); 
     my $name = 'NWS-XML';
     my $version = 0.2;
     my $author = 'Lucien Dunning';
     my $email = 'ldunning@gmail.com';
     my $updateTimeout = 15*60;
     my $retrieveTimeout = 30;
     my @types = ('cclocation', 'station_id', 'latitude', 'longitude',
             'observation_time', 'observation_time_rfc822', 'weather',
             'temperature_string', 'temp', 'relative_humidity', 'wind_string',
             'wind_dir', 'wind_degrees', 'wind_speed', 'wind_gust',
             'pressure_string', 'pressure', 'dewpoint_string', 'dewpoint',
             'heat_index_string', 'heat_index', 'windchill_string', 'windchill',
             'visibility', 'weather_icon', 'appt', 'wind_spdgst');
     my $dir = "./";
     getopts('Tvtlu:d:');
     if (defined $opt_v) {
         print "$name,$version,$author,$email\n";
         exit 0;
     }
     if (defined $opt_T) {
         print "$updateTimeout,$retrieveTimeout\n";
         exit 0;
     }
     if (defined $opt_l) {
         my $search = shift;
         NWSLocation::AddLocSearch($search);
         NWSLocation::AddStateSearch($search);
         NWSLocation::AddStationIdSearch($search);
         my $results = doSearch();
         my $result;
         while($result = shift @$results) {
             if ($result->{latitude} ne "NA" && $result->{longitude} ne "NA") {
                 print "$result->{station_id}::";
                 print "$result->{station_name}, $result->{state}\n";
             }
         }
      exit 0;
     }
     if (defined $opt_t) {
         foreach (@types) {print; print "\n";}
         exit 0;
     }
     if (defined $opt_d) {
         $dir = $opt_d;
     }
     # we get here, we're doing an actual retrieval, everything must be defined
     my $loc = shift;
     if (!(defined $opt_u && defined $loc && !$loc eq "")) {
         die "Invalid usage";
     }
     my $units = $opt_u;
     my $base_url = 'http://www.weather.gov/data/current_obs/';
     my $response = get $base_url . $loc . '.xml';
     die unless defined $response;
     my $xml = XMLin($response);
     foreach (@types) {
         my $label;
         my $key;
      $label = $_;
      if (/temp$/ || /dewpoint$/ || /heat_index$/ || /windchill$/) {
          $key = $ . 'f' if $units =~ /ENG/;
          $key = $ . 'c' if $units =~ /SI/;
      }
      elsif (/pressure$/) {
          $key = $ . 'in' if $units =~ /ENG/;
          $key = $ . 'mb' if $units =~ /SI/;
      }
      elsif (/wind_speed/) {
          if ($units =~ /ENG/) {
              $key = 'wind_mph';
          } else {
              $key = 'wind_kph';
              $xml->{$key} = int($xml->{'wind_mph'} * 1.609344 + .5);
          }
      } elsif (/wind_gust/) {
          if ($units =~ /ENG/ || $xml->{'wind_gust_mph'} eq 'NA') {
              $key = 'wind_gust_mph';
          } else {
              $key = 'wind_gust_kph';
              $xml->{$key} = int($xml->{'wind_gust_mph'} * 1.609344 + .5);
          }
      } elsif (/visibility/) {
          if ($units =~ /ENG/) {
              $key = 'visibility_mi';
          } else {
              $key = 'visibility_km';
              $xml->{$key} = int($xml->{'visibility_mi'} * 1.609344 + .5);
          }
      } elsif (/weather_icon/) {
          $key = 'weather_icon';
          $xml->{$key} = 'unknown.png';
          local FH;
          open(FH, "icons") or die "Cannot open icons";
          while(my $line = <FH>) {
              chomp $line;
              if ($line =~ /$xml->{'icon_url_name'}::/) {
                  $line =~ s/.:://;
                  $xml->{$key} = $line;
                  last;
              }
          }
      } elsif (/cclocation/) {
          $key = 'location';   
      } elsif (/appt$/) {
  #ew        if ($xml->{windchill_f} eq 'NA') {
          if (!defined($xml->{windchill_f}) || $xml->{windchill_f} eq 'NA') { #ew
              $key = 'heat_index_f' if ($units =~ /ENG/); 
              $key = 'heat_index_c' if ($units =~ /SI/);
          } else { 
              $key = 'windchill_f' if ($units =~ /ENG/); 
              $key = 'windchill_c' if ($units =~ /SI/);
          };
      
      } elsif (/wind_spdgst/) {
          # relying on this being after speed and gust
          $key = "wind_spdgst";
          if ($units =~ /ENG/ ) {
              if (defined($xml->{"wind_gust_mph"})) { #ew
                  $xml->{$key} = "$xml->{wind_mph} ($xml->{wind_gust_mph})"; #ew
              } else { #ew
                  $xml->{$key} = "$xml->{wind_mph} ($xml->{wind_mph})"; #ew
                  } #ew
          } else {
              if (defined($xml->{"wind_gust_kph"})) { #ew
                  $xml->{$key} = "$xml->{wind_kph} ($xml->{wind_gust_kph})"; #ew
              } else { #ew
                  $xml->{$key} = "$xml->{wind_kph} ($xml->{wind_kph})"; #ew
                  } #ew
          }
      } else {
          $key = $label;
      }
      if (defined($xml->{$key})) { #ew
          printf $label . "::" . $xml->{$key}. "\n";
      } #ew
      else { #ew
          if ($label =~ /string/i) { #ew
              printf $label . "::none\n"; #ew
          } #ew
          else { #ew
              printf $label . "::" . #ew
                  (($units =~ /ENG/) ? $xml->{"temp_f"} : $xml->{"temp_c"}) . #ew
                  "\n"; #ew
          } #ew
      } #ew

}

Once you install this copy of the script in the scripts directory:

     /usr/share/mythtv/mythweather/scripts/us_nws

You should make sure the permissions on nwsxml.pl look like this:

     -rwxr-xr-x 1 root root   4868 2009-09-11 21:51 nwsxml.pl

This will allow MythWeather to execute the script to extract weather data from the NWS. You should now be able to include the Current Conditions page in the list of pages to be shown by MythWeather.

Adjusting Samba To Fit In With Your Network

Samba server comes pre-installed on MythTV and set up to share the default recordings, videos and music directories. To our thinking, the choices made for these shares are badly made. Firstly, the workgroup "MSHOME" is chosen as the domain to belong to. Secondly, I don't really care if the media directories are shared.

The following Samba configuration may be more of use to you:

>>>>>>
/etc/samba/smb.conf:

     [global]
     workgroup = WORKGROUP
     server string = %h server (Samba, Mythbuntu)
     log file = /var/log/samba/log.%m
     max log size = 1000
     syslog = 0
     panic action = /usr/share/samba/panic-action %d
     dns proxy = no
     security = share
     [Root]
     comment = Root Directory
     path = /
     public = no
     browseable = yes
     writeable = yes
     write list = @joeblow

Once you've made these changes to smb.conf, don't forget to recycle Samba for them to take effect:

     sudo /etc/init.d/samba restart

Or, for later versions of Mythbuntu (e.g. 12.04) that use init, recycle it like this:

     stop smbd
     stop nmbd
     start nmbd
     start smbd

Also, you may want to add a user or two so that they can access the shared directory:

     smbpasswd -a joeblow

Supply an appropriate password (remember, this needn't be the user's login password).
<<<<<<

UPS Monitoring with NUT

The quick command to set the UPS battery date, after changing batteries is:

     /bin/upsrw -s battery.date=mm/dd/yy -u username -p password \
       upsname@localhost

This presupposes that the username and password are set in upsd.users and that "actions = set" are specified for the user. Also, upsd and the appropriate UPS driver must be up and running for the UPS in question.

If you are running a version of NUT that does not set the battery.date variable correctly for the APC SmartUPS, you can do it manually.

First you must make sure that you have a copy of "screen" installed on the system in question (use "apt-get install screen"). You must also make sure that the UPS driver is not running. Then, assuming that you have the UPS connected to /dev/ttyS0, do the following (note that there are no carriage returns used for any of the commands sent to the UPS):

     su
     /etc/init.d/nut stop
     screen /dev/ttyS0 2400,cs8
     Y
     (UPS echoes "SM")
     x
     (UPS echoes current date)
     -
     (UPS echoes nothing, possibly including the "-", i.e. really nothing)
     mm/dd/yy
     (after about 5 seconds, UPS echoes "|", indicating EEPROM is changed;
      some versions echo "OK", instead)
     x
     (UPS echoes the new date)
     R
     (UPS echoes "BYE")
     <Ctrl-a>\
     (answer yes to exit screen)
     /etc/init.d/nut start

Similarly, if you are running a version of NUT that does not set the UPS identifier correctly for the APC SmartUPS, you can set an up-to-eight-character identifier manually, using "screen" and assuming that you have the UPS connected to /dev/ttyS0, as follows:

     su
     /etc/init.d/nut stop
     screen /dev/ttyS0 2400,cs8
     Y
     (UPS echoes "SM")
     c
     (UPS echoes current UPS ID, probably UPS_IDEN for a new UPS)
     -
     (UPS echoes nothing, possibly including the "-", i.e. really nothing)
     upsname<Enter>
     (after about 5 seconds, UPS echoes "|", indicating EEPROM is changed;
      some versions echo "OK", instead)
     (on some UPS, you may have to press <Enter> twice)
     c
     (UPS echoes the new UPS ID)
     R
     (UPS echoes "BYE")
     <Ctrl-a>\
     (answer yes to exit screen)
     /etc/init.d/nut start

A full description of the APC SmartUPS protocol can be found at:

     http://www.apcupsd.com/manual/manual.html

Also, if you want to get rid of the "Change the battery" message and the red light on the UPS panel, you can force the battery test to be rerun immediately. However, before you do this, wait for three or four hours after the new battery is installed to give the UPS time to charge it first. Then, run the battery test, which will reset everything, if the new battery is OK. To do this, use:

     /bin/upscmd -u username -p password upsname@localhost test.battery.start

The battery test should run (you'll see all of the messages it usually generates) for a few seconds and all will be well.

To do a complete install, begin by installing the latest version of NUT using the Package Manager or Ubuntu Software Center. You will need these packages (plus any dependencies):

     nut
     nut-cgi

You can also install these packages using apt-get, as follows:

     sudo apt-get install nut
     sudo apt-get install nut-cgi

Since Ubuntu uses udev, we need to hack one of the udev rules to give permission on the appropriate serial port. The best place is in a separate rules file that you make up just for this purpose (that way, subsequent releases of NUT won't monkey with your rules for the serial port). We suggest calling the file "52_nut-ttyups.rules. It should be created in the /etc/udev/rules.d directory. You should add something like the following to that file, depending on which serial port you need to use:

     # udev rules for NUT serial drivers
     # Special case for the UPS devices
     KERNEL=="ttyS1", GROUP="nut", MODE="0660"

/etc/nut/ups.conf:

     Copy the file ups.conf.sample and hack it to set up the machine/UPS
     configuration, per the instructions in the INSTALL file.  For an APC
     SmartUPS, the following config information applies:
     [fusion-reactor]
          driver = apcsmart
          port = /dev/ttyS0

/etc/nut/upsd.conf:

     On older versions of NUT, copy the file upsd.conf.sample and replace the
     existing rules with:
     ACL all 0.0.0.0/0
     ACL localhost 127.0.0.1/32
     ACL homeworld 192.168.1.0/24
     ACCEPT homeworld
     ACCEPT localhost
     REJECT all
     On newer versions of NUT (e.g. the version that comes with Mythbuntu 9.04),
     copy the upsd.conf.sample file and replace the LISTEN directives with:
     LISTEN 127.0.0.1
     LISTEN 192.168.1.123 3493
     You should use the actual IP address of the machine where NUT is being
     installed in place of 192.168.1.123 (above).  If the machine has two or more
     NICs and you want NUT to listen on all of them, add additional LISTEN
     directives for the IP address of each of them.
     Note that, if you have an older config file and are upgrading to a newer
     version of NUT, you will need to remove all of the ACL, ACCEPT and REJECT
     rules and simply use LISTEN.  Apparently, the designers have decided that NUT
     should get out of the security business and leave everything to the firewall.
     Consequently, the rules are no longer accepted and LISTEN is simply used to
     tell NUT which port to listen on.

/etc/nut/upsd.users:

     Copy the file upsd.users.sample. Add a user that will allow upsmon on the
     local host to shut down the machine if the power goes south as well as do
     periodic battery tests:
     [lmmonitor]
         password = ItsASecret
         allowfrom = localhost
         instcmds = test.battery.start
         actions = set
         upsmon master

/etc/nut/upsmon.conf:

     Copy the file upsmon.conf.sample. Change the group ownership to the nut user
     and give it group permissions:
     chgrp ups /etc/nut/upsmon.conf
     chmod g+rw /etc/nut/upsmon.conf
     Make the following changes to the file to begin monitoring the UPS:
     NOTIFYCMD /etc/nut/notify
     RUN_AS_USER nut
     MONITOR fusion-reactor@localhost 1 lmmonitor ItsASecret master
     NOTIFYFLAG COMMBAD  SYSLOG+EXEC
     NOTIFYFLAG COMMOK   SYSLOG+EXEC
     NOTIFYFLAG FSD      SYSLOG+EXEC
     NOTIFYFLAG LOWBATT  SYSLOG+EXEC
     NOTIFYFLAG NOCOMM   SYSLOG+EXEC
     NOTIFYFLAG ONBATT   SYSLOG+WALL+EXEC
     NOTIFYFLAG ONLINE   SYSLOG+WALL+EXEC
     NOTIFYFLAG REPLBATT SYSLOG+EXEC
     NOTIFYFLAG SHUTDOWN SYSLOG+WALL+EXEC
     NOTIFYFLAG OVERTEMP SYSLOG+EXEC
     If you want to monitor UPS temperature and you've applied the proper hacks
     (or the temperature hacks are included in your version of the source), add
     the following:
     # --------------------------------------------------------------------------
     # UPSOVERTEMP - Temperature (in Celcius) which is too high for operation
     #
     # upsmon will check all UPS that return temperature information against
     # this value.  If the UPS temperature exceeds this value, an OVERTEMP
     # notification will be generated.
     #
     # Note that certain UPS are renown for cooking and even burning up
     # batteries (some reports of spectacular battery fires have been received).
     # From actual observed log data, it appears that prior to burning up the
     # batteries, the UPS internal temperature rises significantly.  Hence,
     # monitoring the UPS temperature can be a valuable tool towards detecting
     # battery cooking, before the UPS burns the place down (the UPS is supposed
     # to solve problems, not cause them, isn't it).
     #
     # Once again, typical observed internal temperatures are in the 40 to 50
     # degree Celcius range.  Observed temperatures of 80 degrees Celcius prior
     # to an actual battery failure are indicative of pending failure.  Thus, to
     # be safe, the the UPSOVERTEMP value should be set in the 60-70 degree
     # range.
     UPSOVERTEMP 60.0

/etc/nut/notify:

     Create the following script to send event notifications to root, via email,
     whenever the UPS has something important to say.  Note that the indentation
     in front of "ENDMSG" can be tabs only.  If your lame-ass text editor sticks
     spaces in there, the shell script will get a syntax error.  Set the
     UPS_BOXES variable to your list of UPS boxes.  Here is the script:
     #!/bin/sh
     # A shell script that can be used by the UPS power monitor to send messages
     # to root when power failures occur.
     #
     # If you would like to log all of the UPS events that take place in the log
     # file too, define the location of the log file.  Otherwise, if the
     # LOG_PATH is set to an empty string, no log entries are written.
     # Define the log path and the boxes we're logging.
     LOG_PATH="/var/log/upslog"
     UPS_BOXES="fusion-reactor bevatron"
     # Write the event to the log, if there is one.
     if [ x"$LOG_PATH" != x ]; then
         timestamp=`date "+%Y/%m/%d %H:%M:%S"`
         for LogBox in $UPS_BOXES; do
             echo $UPSNAME | grep -q $LogBox
             matval=$?
             if [ $matval = 0 ] ; then
                 echo $timestamp EVENT: $1 >> ${LOG_PATH}.$LogBox
             fi
         done
     fi
     # Some events we only log.
     if ([ x"$NOTIFYTYPE" != xONBATT ]) && ([ x"$NOTIFYTYPE" != xONLINE ]) \
         && ([ x"$NOTIFYTYPE" != xREPLBATT ]) \
         && ([ x"$NOTIFYTYPE" != xSHUTDOWN ]) \
         && ([ x"$NOTIFYTYPE" != xOVERTEMP ]); then
         exit 0
     fi
     # Email the message to root so that they can see everything that's going
     # on.  After all, if you're omnipotent, you need to know everything.
     HostName=`hostname`
     if [ x"$NOTIFYTYPE" != xSHUTDOWN ]; then
         /usr/bin/mail -s "Message from the UPS" root <<-ENDMSG
             The power monitor on $HostName has generated the following message:
             $1
             ENDMSG
     else
         /usr/bin/mail -s "Urgent message from the UPS" root <<-ENDMSG
             The power monitor on $HostName has generated the following message:
             $1
             ENDMSG
     fi
     Note that, in the above script, the two sets of lines between
     "/usr/bin/mail -s ... <<-ENDMSG" and up to and including the line with
     "ENDMSG" must either not be indented at all or only indented with actual tab
     characters (not blanks).  If they are not, the script will fail.
     Also, don't forget to add execute permissions to the script after you create
     it:
     su
     chmod ugo+x /etc/nut/notify
     Then, it wouldn't hurt try it out after you've got it all set up.  For
     example:
     UPSNAME=bevatron; export UPSNAME
     NOTIFYTYPE=ONLINE; export NOTIFYTYPE
     /etc/nut/notify "This is a test"
     Check that root receives the message and that the message gets logged to
     bevatron's log file.

/etc/nut/hosts.conf:

     Copy the file hosts.conf.sample.  Add all of the machines that you want to be
     able to monitor from the Web.  Also add the name of the logfile, if logged
     events will be displayed:
     MONITOR fusion-reactor@localhost "pri-host UPS"
     LOGFILE /var/log/upslog.fusion-reactor

/etc/nut/ftplogs:

     If you'd like to build a consolidated graph of all your UPS activity and have
     a centralized server where logfiles can be copied for this purpose, you
     should create the file /etc/nut/ftplogs:
     #! /bin/sh
     #
     # ftplogs - Script to ftp the UPS logs to the primary server at regular
     #           intervals.
     #
     # This script is used both by cron, to send the current UPS logs to the
     # primary server, every 15 minutes, and by logrotate, to send the freshly
     # rotated UPS logs to the primary server whenever UPS logs are rotated.
     #
     #
     # Define the log path and the boxes we're logging.
     #
     PRI_SERVER="pri-host"                   # Primary server name
     LOG_PATH="/var/log/upslog"              # Local log path
     PRI_LOG_PATH="/var/log/upslog"          # Log path on primary server
     UPS_BOXES="bevatron"
     #
     # If we were passed a logfile name, send it to the primary server directly.
     #
     if test x"$1" != x; then
         echo -e "user nut ItsASecret\\nput ${LOG_PATH}.$1 ${PRI_LOG_PATH}.$1" \
             | ftp -n $PRI_SERVER
     #
     # For all of the UPS on this system, send the logs to the primary.
     #
     else
        for LogBox in $UPS_BOXES; do
            echo -e "user nut ItsASecret\\nput ${LOG_PATH}.$LogBox \
                ${PRI_LOG_PATH}.$LogBox" | ftp -n $PRI_SERVER
        done

fi

     Note that on some machines /bin/sh is an alias for /bin/dash and that dash,
     apparently, doesn't have to follow the rules too closely for shells.  So, you
     may find that dash is broken when it comes to echo and "echo -e" doesn't
     work.  If this is the case (First of all, why do we need another half dozen
     shells, anyway?  Isn't two or three already way too many?  And, who the f**k
     gives a rat's butt about POSIX compatibility?  What I giva a f**k about is
     "working", especially old scripts, that used to work fine, "still working".
     So, nice going a**holes.), you'll probably be a lot happier with /bin/bash
     instead of /bin/sh.
     You should pick a user that is valid on the server, use the right password
     for that user and set the server name to the correct name for the central
     server (make sure this server name appears in either /etc/hosts on the local
     Mythbuntu machine or can be resolved through DNS).  Add the script to your
     cron table so that it runs at regular intervals (e.g. every 15 minutes), as
     shown below.
     Also, on that server, you should create a couple of empty log files with the
     correct permissions so that FTP can overwrite them without getting permission
     denied:
     su
     touch /var/log/upslog.bevatron /var/log/upslog.bevatron.1
     chown root:ups /var/log/upslog.bevatron
     chmod g+w /var/log/upslog.bevatron

/etc/logrotate.d/nut:

     Add the new UPS' logfile to the logrotate config file:
     /var/log/upslog.bevatron {
         notifempty
         missingok
         create 0664 root ups
         copytruncate
         postrotate
             echo HEADER: Bevatron >/var/log/upslog.bevatron
             /etc/nut/ftplogs bevatron.1
         endscript
     }

/etc/crontab:

     If you want the UPS batteries to be tested at regular intervals, you can add
     a line to crontab to do that.  Every couple of months is a good interval.
     If you care, schedule the times for the battery test on days when the other
     UPS are not also testing their batteries (you don't want all the machines
     down at once, do you).
     You should also add a line to schedule the push of the logs to a central
     server, if you want to use that feature.
     # Push the UPS logs over to the primary host every 15 minutes.
     05,20,35,50 * * * * root /etc/nut/ftplogs
     # Every two months, have the UPS check its battery.
     00 6 15 1,3,5,7,9,11 * root /bin/upscmd -u lmmonitor -p ItsASecret \
                                 fusion-reactor@localhost test.battery.start
     Note that most UPS will usually come with automatic self-test turned on and
     set to every 14 days.  This means that the UPS will run its battery test
     itself every 14 days, exactly 1209600 seconds after it is turned on.  How
     convenient is that?  If you'd rather the test was done when you decide, in
     your crontab, you should turn off this dubious feature like so:
     /bin/upsrw -s ups.test.interval=0 -u lmmonitor -p ItsASecret \
                fusion-reactor@localhost

/etc/init.d/ups-monitor:

Note that later versions of NUT name the script in init.d "nut" instead of "ups-monitor". Then, they point a symlink of "ups-monitor" at "nut". If you have one of these versions, you should update the "nut" script instead of "ups-monitor".

The installed ups-monitor script does not start logging. If you'd like to use logging, you can add the following:

     upslog_pid=${pid_dir}/upslog.pid
     upslog=/bin/upslog
          .
          .
          .
     start_stop_log () {
       case "$START_UPSLOG" in
         y|Y|yes|YES|Yes)
           case "$1" in
             start)
               timestamp=`date "+%Y/%m/%d %H:%M:%S"`
              for UPSBox in $UPSLOG_BOXES; do
                echo $timestamp EVENT: Starting UPS logging \
                    >> ${UPSLOG_PATH}.$UPSBox
                chgrp $UPSLOG_GROUP ${UPSLOG_PATH}.$UPSBox
                chmod g=rw ${UPSLOG_PATH}.$UPSBox
                $upslog ${UPSBox}@localhost ${UPSLOG_PATH}.$UPSBox \
                  $UPSLOG_INTERVAL \
                  "%TIME @Y/@m/@d @H:@M:@S% %VAR input.voltage% \
                      %VAR output.voltage% %VAR input.frequency% \
                      %VAR battery.charge% %VAR ups.load% [%VAR ups.status%] \
                      %VAR ups.temperature%" \
                  >/dev/null 2>&1
                startval=$?
                if [ $startval = 0 ] ; then
                  touch ${upslog_pid}.$UPSBox
                else
                  return $startval
                fi
              done
              ;;
            stop)
              timestamp=`date "+%Y/%m/%d %H:%M:%S"`
              for UPSBox in $UPSLOG_BOXES; do
                if [ -f /var/lock/subsys/upslog.$UPSBox ]; then
                  LogPID=`ps -eo pid,args | grep upslog | grep $UPSBox \
                      | sed -n 's/^ \([0-9]\).*/\1/p'`
                  if [ x"$LogPID" != x ]; then
                    kill -9 $LogPID
                    stopval=$?
                    echo $timestamp EVENT: Stopping UPS logging \
                        >> ${UPSLOG_PATH}.$UPSBox
                    [ $stopval = 0 ] && rm -f /var/lock/subsys/upslog.$UPSBox
                  fi
                fi
              done
              ;;
          esac
          ;;
        n|N|no|NO|No|*)
          return 1
          ;;
      esac
    }
         .
         .
         .
     case "$1" in
      start)
        log_daemon_msg "Starting $DESC"
        check_var_directory
        start_stop_server start && log_progress_msg "upsd"
        start_stop_client start && log_progress_msg "upsmon"
        start_stop_log start && log_progress_msg "upslog"
        log_end_msg 0
        ;;
      stop)
        log_daemon_msg "Stopping $DESC"
        start_stop_log stop && log_progress_msg "upslog"
        start_stop_client stop && log_progress_msg "upsmon"
        start_stop_server stop && log_progress_msg "upsd"
        log_end_msg 0
        ;;

Once you've made any changes to ups-monitor for logging, if it wasn't already installed by apt-get, install it using the dain-bramaged update-rc.d script. The following should work:

     update-rc.d nut defaults

or maybe:

     update-rc.d ups-monitor defaults

/etc/nut/nut.conf:

     In a never-ending attempt to justify the five or six config files needed by
     this package, they've added another config file (Yeah!) only this time its
     used by the startup script in init.d to tell it which other config files to
     use.  Consequently, if this file is present and is needed by the startup
     script (either nut or ups-monitor, in init.d), you should edit to get NUT
     working because the default value in it disables NUT, out of the box.
     Change MODE to either "netserver" or "standalone" (they both work the same)
     like this:
     MODE=netserver

/etc/default/nut:

     You will have to hack the default settings so that upsd and upsmon are
     started:
     START_UPSD=yes
     START_UPSMON=yes
     If you want to use the logging features added to ups-monitor (above), add
     these lines:
     # start upslog
     START_UPSLOG=yes
     # set upslog specific options. use "man upslog" for more info
     UPSLOG_OPTIONS=""
     # a list of UPS to log, separated by a space
     UPSLOG_BOXES="Bevatron"
     # logging directory (including filename prefix)
     UPSLOG_PATH="/var/log/upslog"
     # the log interval (in seconds)
     UPSLOG_INTERVAL=30
     # group to use for log files
     UPSLOG_GROUP=nut

Increasing Storage Capacity

If you chose the XFS file system for any of your video storage volumes (a wise choice) and you wish to expand these volumes to a bigger disk (e.g. you wish to replace a 1TB disk with a 2TB disk), you should follow the steps outlined immediately below. On the other hand, if you chose the ext3 file system for any of your video storage volumes (you had your reasons, I'm sure), you should follow the steps shown at the end of this section. Otherwise, if the system files and video storage directory are all on one disk (single disk system), or you wish to expand the system disk of a system with more than disk, expanding such a system's disk is covered in the next section.

Note that the duration of the copy operation that is used to expand a volume depends on the amount of data on it (duh) so you may wish to clean up all of the old stuff that you were thinking of deleting, before you proceed. On the other hand, if you could do that, you probably wouldn't need bigger disks in the first place....

Begin by getting yourself a copy of Knoppix (the CD works perfectly fine):

     http://knopper.net/knoppix/index-en.html

And burning the ISO image onto a CD (or DVD, if you took that route).

Next, configure the machine who's disk is to be expanded with the old disk and new disk attached and a CD/DVD drive added, if necessary. In this example, we're presuming the original drive is on SATA0 and the new drive is on SATA1, which should map to /dev/sda and /dev/sdb respectively, when Knoppix is booted.

Put the Knoppix CD into the CD/DVD drive and boot it. Once Knoppix comes up (you're booting from a CD, remember, so be patient), open up a console window and become super user. To do this, simply type the "su" command. There's no password (how refreshing).

Before proceeding, you should check that the original and new drives are installed where you expect them to be. You can check this with:

     su
     /sbin/fdisk -lu /dev/sda
     /sbin/fdisk -lu /dev/sdb

or

     su
     /sbin/fdisk -lu

or, if you have disks that are larger than 2TB, you might want to use:

     su
     /sbin/parted -l

The first drive should show a valid partition table with one Linux partition, usually type "83" or, for GNU partitions, type "ee", while the second drive should have no partition table. Also, note each drive's size to ensure that the old and new drives are cabled where you expect them to be. Since, we're going to be wiping out all data on the new drive, in a minute, it pays to make sure you've got the right target in your sights.

If you have a regular format hard drive that is less than or equal to 2GB in size, you should now format the new drive using fdisk:

     su
     /sbin/fdisk -u /dev/sdb
       n                         (To create a new partition)
       p                         (As a primary partition)
       1                         (Partition 1)
       <cr>                      (To accept the first sector as the start)
       <cr>                      (To accept the last sector as the end)
       w                         (Write the partition table to the disk)

You can check your work with:

     su
     /sbin/fdisk -lu /dev/sdb

You should see something like this:

     Disk /dev/sdb: 2000.4 GB, 2000398934016 bytes
     81 heads, 63 sectors/track, 765633 cylinders, total 3907029168 sectors
     Units = sectors of 1 * 512 = 512 bytes
     Sector size (logical/physical): 512 bytes / 4096 bytes
     I/O size (minimum/optimal): 4096 bytes / 4096 bytes
     Disk identifier: 0x59da471f
     Device Boot      Start         End      Blocks   Id  System
  /dev/sdb1            2048  3907029167  1953513560   83  Linux

If you have one of the newer 1.5 or 2 TB, advanced format hard drives (e.g. from Western Digital or Samsung), you need to pay particular attention to how you create the partitions on the drive so that they are always aligned on a 4K boundary. If you don't do this, performance will suffer heavily.

Since we are only creating a single partition, fdisk defaults to creating the partition starting at sector 63 (it keeps the first 63 sectors, from 0-62, for the partiton table and boot information). In the case of advanced format hard drives, this is a very unfortunate choice. Luckily for us, for an advanced format hard drive, later versions of fdisk default to creating the partition starting at sector 2048 (it keeps the first 2047 sectors, from 0-2047, for the partiton table and expanded boot information), so you can just allow fdisk to do it's thing. There is no need to override the starting sector number, just take the default.

However, if that's not to your liking and you wish to override the default choice (we don't advise it), you can partition the disk something like this:

     su
     /sbin/fdisk -u /dev/sdc
       n                         (To create a new partition)
       p                         (As a primary partition)
       1                         (Partition 1)
       64                        (Start the partition on a 4K boundary [i.e. 0
                                   mod 8].
       <cr>                      (To accept the last sector as the end)
       w                         (Write the partition table to the disk)

You can check your work with:

     su
     /sbin/fdisk -lu /dev/sdb

You should see something like this:

     Disk /dev/sdb: 2000.3 GB, 2000398934016 bytes
     255 heads, 63 sectors/track, 243201 cylinders, total 3907029168
     Units = sectors of 1 * 512 = 512 bytes
     Device Boot      Start         End      Blocks   Id  System
  /dev/sdb1              64  3907029167  1953514552   83  Linux

or maybe something like this:

     Disk /dev/sdb: 2000.4 GB, 2000398934016 bytes
     81 heads, 63 sectors/track, 765633 cylinders, total 3907029168 sectors
     Units = sectors of 1 * 512 = 512 bytes
     Sector size (logical/physical): 512 bytes / 4096 bytes
     I/O size (minimum/optimal): 4096 bytes / 4096 bytes
     Disk identifier: 0x83a7c849
     Device Boot      Start         End      Blocks   Id  System
  /dev/sdb1            2048  3907029167  1953513560   83  Linux

If the new disk is bigger than 2TB, you must use parted to format the new disk because it is the only partition editor that is able to support disks larger than 2TB. Additionally, if you have a disk that is larger than 2TB, it is almost guaranteed to be an advanced format disk, so you must make sure to choose a starting sector for the partition that observes the 4K block boundary, to avoid severe performance hits. Also, to ensure compatibility with boot loaders that require more than 62 sectors following the partition table, it is smart to always start the first partition at sector 2048. Since parted has a parameter that automatically figures out what is the optimal alignment for a partition, based on disk geometry, we can just pick 2048 by default and it will tell us if that number won't work. So, run it like this:

     su
     /sbin/parted -a optimal /dev/sdb
       mklabel gpt
       mkpart primary xfs 2048s 100%  (use "ext2" for ext2/ext3)
       print
       quit

The print command should show something like this:

     Model: ATA WDC WD40EZRZ-00G (scsi)
     Disk /dev/sdc: 4001GB
     Sector size (logical/physical): 512B/4096B
     Partition Table: gpt
     Number  Start   End     Size    File system  Name     Flags
      1      1049kB  4001GB  4001GB               primary

We used the "s" after "2048" to tell parted that the first number was a starting sector number, not a size in megabytes. We used the "%" after "100" to tell parted that the ending number was 100% of the disk, in other words the last physical sector.

After creating a new partition table, regardless of which type you choose, you should ask the kernel to reread the partition table:

     su
     partprobe

If the original drive contains an ext2/ext3 file system, you should proceed to copy its data as outlined farther along in this section. Otherwise, verify that it does indeed contain an XFS file system with this command:

     df -T /dev/sda1

Once you've verified that the file system type is "xfs", the data on it should be copied to the new drive, as shown:

     su
     xfs_copy -d /dev/sda1 /dev/sdb1

Note that, if you have one of the advanced format hard drives (e.g. the newer drives from Western Digital or Samsung), you should first check that the block size of the original XFS file system is a multiple of 4096. Usually, it will be, because XFS chooses the page size of the OS as the block size and, under Linux, this is 4096. To check, you can dump the XFS superblock like this:

     xfs_db -c "sb 0" -c print -r /dev/sdb1 | grep blocksize

If the block size is not a multiple of 4096, there does not appear to be any way to alter it while doing xfs_copy so the only option appears to be to start from scratch with a brand new XFS file system on the target volume and copy the files with a regular copy command such as "cp" or "lftp mirror".

The copy will take quite a while, depending on the size of the original partition and how full it is (if you were smart and deleted all of the junk shows off the original partition, it will be faster). Incidentally, it will format the new partition with XFS, so there is no need to do this ahead of time.

Once the copy completes, the new disk will contain a copy of the original disk, but the new XFS file system will be same size as the original (bummer).

The next step requires that you mount the new file system. Knoppix thoughtfully provides predefined mount points in the "/media" directory for each of the attached devices that it finds. So, do:

     su
     mount /dev/sdb1 /media/sdb1

You can check that the mounted file system looks like the original with:

     ls -l /media/sdb1

If you're happy with the new file system (we will take care of any problems with file ownership discrepancies below so you can ignore them for the time being), you can increase its size to fill the entire partition (nice) with:

     su
     xfs_growfs /media/sdb1

Once that's done, unmount the new file system:

     su
     umount /media/sdb1

Not replacing an XFS drive? For ext3 file systems, you can use whatever copy method you usually use to copy a smaller disk to a larger disk. The brute force approach would be to use Knoppix, as is described above, but when you come to the part about using xfs_copy, do the following instead. Make the file system that you wish to use for the partition with mkfs or, to be more precisely, mkfs.ext3:

     su
     /sbin/mkfs.ext3 -b 4096 -j -L / -T news /dev/sdb1

Since the file system will only hold static data, there's no real reason to have fsck check it at boot time. This is especially relevant because for the large file systems that are found on 1 or 2TB disks, checking the file system could take a very, very long time (i.e. hours and hours). If you have several large disks on your video server and all of the file systems happen to get coincidentally checked, booting your system could easily take half a day. You will most certainly want to turn off this dubious feature with:

     su
     /sbin/tune2fs -c 0 -i 0 /dev/sdb1

Note that, in this example, we labeled the file system "/". You may wish to use some other label, chosen to match what's on the original drive. Be especially careful about this if your system boots with the "LABEL=" parameter in the GRUB configuration and/or mounts partitions using the "LABEL=" parameter in /etc/fstab.

The next step requires that you've mounted the old and new file systems. We have been assuming all along that you connected the old disk on /dev/sda and the new disk on /dev/sdb. If you are lucky, you can read the newly-created partition table without rebooting:

     su
     partprobe

Otherwise, you will need to reboot. Lately, partprobe has always worked for us. Before, not so much. Your mileage may vary.

Knoppix thoughtfully provides predefined mount points in the "/media" directory for each of the attached devices that it finds. So, do:

     su
     mount /dev/sda1 /media/sda1
     mount /dev/sdb1 /media/sdb1

Now, copy the original drive to the new drive:

     su
     cp --preserve=all -R /media/sda1/* /media/sdb1

Once you are done copying the files, unmount the old and new file systems:

     su
     umount /media/sda1
     umount /media/sdb1

Regardless of the type of file system that you choose, if you experience problems with device names changing whenever your system reboots, as we mentioned in the "File System Table" section, you can use UUIDs to mount your disk partitions.

When you set up fstab to use UUIDs, you must make doubly-sure that you change the UUIDs therein, whenever you make any disk changes. Even if you only reformat a partition, it will get a new UUID and you must update fstab. This is a big change from before when you just recabled a new drive and were off to the races. Failure to change the UUIDs in fstab, before you try to boot the newly-configured system, will likely render it unbootable. You will them be faced with booting Knoppix from a CD/DVD and correcting fstab, using leafpad, from there.

Since you've just added a new disk, pay attention to how your fstab is set up. If it does use UUIDs, go back to the "File System Table" section and read the part about discovering the UUIDs for your disk partitions and make a note of the new UUIDs.

The correct procedure to follow, when a UUID changes, is to edit fstab with the planned new UUID before you shut down the running system. That way, you can use your regular text editor on the system. Once the system is shut down, make the hardware change (e.g. install the new disk) and then reboot the system. As we said above, failure to remove the old UUID from fstab will likely result in your system failing to boot.

Mind you, if anything goes wrong with the hardware swap, etc. you could be faced with this same scenario so an alternative method is to just remove the line that mounts the old UUID from fstab (a comment works). This is probably the best method, if the disk in question isn't critical (i.e. the system disk). When you reboot the system, it will come up without the disk mounted but at least it will come up.

Once the system is booted, you can edit fstab with the correct UUID and then try auto-mounting everything (this way, if fstab is broken, your system will still be up and running and you'll have a chance to fix things):

     su
     mount -a -v

All done partitioning, copying and editing fstab? Shut down Knoppix and recable the new disk to replace the original. Boot the machine with the production OS, with the new disk installed, and see how it works.

Since copying file systems with cp, as shown above, can be pretty slow, you may opt to copy your ext3 file system using a smart copy program like Acronis. Many of these programs know how to analyze the file system directory structure and copy the files much more quickly than cp (and for sure, ftp) does. A significant improvement in copy time may result.

There's only one wrinkle, though. They may not know how to set up all of the flags in the file system directory properly. So, although all of the data is copied properly, your file system will fail to pass fsck's checks when you try to boot with the new disk (this is presuming that fsck is even run against the new file system). If this happens, you can usually heal the new file system with:

     su
     fsck /dev/sda1 -- -a

You may be doing this in single user mode, if the system fails to boot properly because the failing file system cannot be mounted.

An alternative to connecting the new disk to your running system and copying the files directly works well for expanding data-only drives. In this case, one may not wish to shut down a production system the whole time that the new drive is being set up. Instead, one can mount the new drive on a separate test or work system and copy the files using a network file copy program such as rsync or lftp, to set up the new drive ahead of time, while the production system is still running.

Cable the new drive up to the test/work system (we're assuming that it ends up on /dev/sdb, for the purposes of these notes), boot the OS of your choice (Knoppix anyone?) and proceed with building the new partition table as described above. After creating a new partition table, regardless of which type you choose, you should ask the kernel to reread the partition table:

     su
     partprobe

If you are creating an ext2/ext3 partition, the following command can be used to format and label it:

     su
     /sbin/mkfs.ext3 -b 4096 -j -L / -T news /dev/sdb1

However, if the drive is a data-only drive, you'll probably be setting it up as an XFS drive. In this case, you'll need to establish the file system directly instead of depending on xfs_copy to do it for you (as we did above). The XFS format command looks like this:

     su
     /sbin/mkfs.xfs -b size=4096 -L / /dev/sdb1

For an advanced format drive that uses 4096 byte physical sectors, you'll probably want to use something like this command:

     su
     /sbin/mkfs.xfs -b size=4096 -s size=4096 -L / /dev/sdb1

If there isn't already a mount point that you can use for the new file system on your test/work system, you should create one something like this:

     su
     mkdir /mnt/sdb1mr

Then, you can mount the new file system and change to the root directory:

     su
     mount /dev/sdb1 /mnt/sdb1mr
     cd /mnt/sdb1mr

We like to use lftp to mirror the data-only partition from the production system to the new data-only file system on the test/work system. This might go something like this:

     su
     lftp -u joeblow sftp://el-producto
     <super-secret-pw>
     mirror /mnt/sdb1 /mnt/sdb1mr

The mirror will run for a while (depending on how many gig o'bytes are to be copied).

If you built the new storage drive on a separate Knoppix system and would like to copy its content over to the Knoppix system before installing it into production, you have a small problem on your hands. Knoppix comes with ncftp instead of lftp. What can we say? Ncftp ain't lftp. Good luck mirroring directories from your production system to your build system with ncftp. We tried it....

There is, however, a solution. You can start up ssh on Knopix and then use lftp on the other system (i.e. the production system itself) to mirror existing video directories to the build system. On the Knoppix system, do:

     su
     /etc/init.d/ssh start
     passwd
       (enter the new, super-secret root password)
       (enter the new, super-secret root password, again)
     ifconfig  (you'll need the IP address below)

On the system that has the original video files, do:

     lftp -u root sftp://192.168.1.123   (get the DHCP address for the system
                                         running Knoppix, from ipconfig, as
                                         shown above)
     mirror -R /local/source/dir /remote/dest/dir

In this case, your remote destination directory will probably be something like /media/sdb1 on the Knoppix system. You will need the super-secret password that you created for root, in the previous step.

Once the mirroring is done, you can swap the new drive into the production system during a lull in the action.

However, if you wait too long and the production system keeps running, adding new recordings and deleting old ones, there is the possibility that a number of files on the original partition won't be mirrored, either because they were locked during the original mirror from the production system, or they were added/deleted after the mirror was done. It ain't the end of the world. Once the new drive is in production, you can just mount up the old drive on the test/work system and reverse mirror any missing files. First, on the test/work system, where the original drive is now installed on /dev/sdb:

     su
     mkdir /mnt/sdb1or
     mount /dev/sdb1 /mnt/sdb1or

From the el-producto system, where the mirrored drive is now installed on /dev/sdb and mounted on /mnt/sdb1, do:

     su
     lftp -ujoeblow test-oh-mundo
     <super-secret-pw>
     mirror --only-missing /mnt/sdb1or /mnt/sdb1

A slicker alternative to using lftp, if the old and the new drives can both be cabled up to your test/work system, is to use rsync, since it will avoid the need to run the "cleanup" script (as noted below) to clean up any deleted recording files, etc. -- that is any files that were deleted since the inital copy was made.

Assuming that the old drive is mounted on /media/sda1 and that the new drive is mounted on /media/sdb1, do the following:

     su
     rsync -av --delete -n /media/sda1/ /media/sdb1

This will produce a dry-run, which will show you all of the files that are about to be deleted and copied. If you are happy with the list, you can omit the "-n" from the command line:

     su
     rsync -av --delete /media/sda1/ /media/sdb1

If you run itno any trouble with permissions on the copied files, if necessary, you can set the permissions on the new file system and its contents more or less as follows (take a look at the original file system for anything special but this should work):

     su
     find /mnt/sdb1 -mindepth 1 -exec chown mythtv:mythtv \{\} \;
     find /mnt/sdb1 -mindepth 1 -type d -exec chmod u=rwx,g=rwxs,o=rx \{\} \;
     find /mnt/sdb1 -mindepth 1 -type f -exec chmod ug=rw,o=r \{\} \;

It might also be a good idea to run the "cleanup" script, which can be found in the "Freeing Up Storage" section above, to perform an orphan check for any files that got deleted by Myth after you mirrored the storage directory but before the system was shut down and restarted with the new data-only file system installed. This script should be run something like this:

#>>>>>>

     .../scripts/cleanup /mnt/sdb1 0 localhost root its-a-secret >cleanup.lst

Look in the cleanup.lst file for any files marked "Orphaned" and manually delete them.

Your migration to the new data-only storage disk should be complete.

Increasing the Capacity of a Single Disk System

A single disk system usually has two or more partitions on its only disk (at the very least, a swap partition and a system partition). Expanding the storage capacity of the video storage partition (or the system partition, if the videos are stored along with the system files on the system partition) is basically like expanding a single partition volume, except that there are a couple of extra steps before you get started, and you must carry out the appropriate type of copy for each of the partitions, not just a single partition.

The extra steps are necessitated by the fact that the single disk system must have a bootable disk and the system also needs some swap space on the disk.

To illustrate the complete steps necessary to expand a single disk system, let's take the example of a system that has three partitions, one for /boot, one for swap space, and one for root. Furthermore, let's assume that the /boot partition is formatted using ext3 and the root partition is formatted using XFS.

As we noted in the previous section, the duration of the copy operation that is used to expand a volume depends on the amount of data on it (duh) so you may wish to clean up all of the old stuff that you were thinking of deleting, before you proceed. On the other hand, if you could do that, you probably wouldn't need a bigger disk in the first place....

Again, we begin by getting ourselves a copy of Knoppix (the CD works just swell but later versions will only fit on a DVD):

     http://knopper.net/knoppix/index-en.html

And burning the ISO image onto a CD (or DVD, if you took that route).

Next, configure the single disk machine who's disk is to be expanded with the old disk and new disk attached and a CD/DVD drive added, if necessary. In this example, we're presuming that the original drive is on SATA0 and the new drive is on SATA1, which should map to /dev/sda and /dev/sdb respectively, when Knoppix is booted.

Put the Knoppix CD/DVD into the CD/DVD drive and boot it. Once Knoppix comes up (you're booting from a CD/DVD, remember, so be patient), open up a console window and become super user. To do this, simply type the "su" command. There's no password (how refreshing).

Before proceeding, you should check that the original and new drives are installed where you expect them to be. You can do this by typing:

     /sbin/fdisk -lu

The first drive should show a valid partition table that looks something like this:

     Disk /dev/sda: 640.1 GB, 640135028736 bytes
     255 heads, 63 sectors/track, 77825 cylinders, total 1250263728 sectors
     Units = sectors of 1 * 512 = 512 bytes
     Disk identifier: 0x63c6c105
     Device Boot      Start         End      Blocks   Id  System
  /dev/sda1   *          63      996029      497983+  83  Linux
  /dev/sda2          996030     4996214     2000092+  82  Linux swap / Solaris
  /dev/sda3         4996215  1250263728   622633756   83  Linux

Be sure that the original drive's size and partition information is correct to ensure that it is mounted where you think it is. Also verify that the new drive has nothing on it (or has the expected layout, if you're reusing it). Since, we're going to be wiping out all data on the new drive in a minute, it pays to make sure you've got the right target in your sights.

You can also check the various partitions to see what type of file systems are on each of them. In our example, we'd do:

     /bin/lsblk -f

Alternately, blkid will also tell you which type of file system a block device has mounted, so you can use:

     /sbin/blkid /dev/sda1
     /sbin/blkid /dev/sda3

If you are checking file system types on mounted file systems (e.g. on a system that is in service), you can use:

     df -T /dev/sda1
     df -T /dev/sda3

Make a note of each partition's file system type. We're expecting to see an ext3 file system on /dev/sda1 and an XFS file system on /dev/sda3.

If everything looks good, you can avoid all the trouble of setting up the boot sector with the boot loader by just copying the first few tracks of the source disk directly with dd:

     dd bs=512 count=2048 if=/dev/sda of=/dev/sdb

This will also copy the partition table, which probably won't be correct for the new disk. However, since we are expanding the disk size, usually the only required change to the copied partition table is that the last partition be expanded to fit the new disk. This can be done by deleting the last partition and adding a new partition that uses all of the available space:

     su
     /sbin/fdisk /dev/sdb
       u                         (All sizes are given in sectors, not
                                   cylinders)
       d                         (Delete a partition)
       3                         (Partition 3)
       n                         (To create a new partition)
       p                         (As a primary partition)
       3                         (Partition 3)
       <cr>                      (Accept previous end sector + 1 as the start)
       <cr>                      (To accept the last sector as the end)
       p                         (To verify the partition table)
       w                         (Write the partition table to the disk)

Be sure that the appropriate partition is marked as the boot partition, if it hasn't already been marked that way (it should be).

Alternately, for the advanced format hard drives (e.g. 1.5, 2 TB, or higher drives), one can likely no longer continue in the same old manner, as described above (unless you are copying from one advanced format drive to another, in which case have at it).

When copying from a regular format hard drive (with 512 byte physical sectors) to an advanced format hard drive (with 4096 byte physical secors), you will probably need to create the partition table from scratch because, if the partitions on the drive are not laid out properly and/or the file systems not constructed carefully, you will suffer horrible performance problems. This all but mandates that you lay the partitions out by hand, set the boot loader up manually, set the file systems up ahead of time, and copy all of the files manually. No use of dd or another direct partition copy program to speed up the process is possible.

Note that, with the later versions of Knoppix that we have used (e.g. 7.2), fdisk knows about advanced format hard drives and handles alignment of the partitions on the proper boundaries, if you let it. It should start the first partition on sector 2048 and, if you use end sector numbers like +512M or +4G, calculate the proper end sectors so that the next partition will always begin on the proper boundary. We now begin by creating the partition table as follows:

     su
     /sbin/fdisk /dev/sdb
       u                         (All sizes are given in sectors, not
                                   cylinders)
       n                         (To create a new partition)
       p                         (As a primary partition)
       1                         (Partition 1)
       2048                      (Start the partition on a 4K boundary [i.e.
                                   0 mod 8])
       +512M                     (To define a 512 MB partition)
       n                         (To create a new partition)
       p                         (As a primary partition)
       2                         (Partition 2)
       <cr>                      (To accept the next block as the start)
       +2G                       (To define a 2 GB partition [or use +4G])
       t                         (To set the partition type)
       2                         (Partition 2)
       82                        (Partition type 82, swap space)
       n                         (To create a new partition)
       p                         (As a primary partition)
       3                         (Partition 3)
       <cr>                      (To accept the next block as the start)
       <cr>                      (To accept the last cylinder as the end)
       w                         (Write the partition table to the disk)

This creates a new partition layout that has approximately 500MB for the boot partition, 2GB for swap space, and the remaining disk space for the root partition. Just by way of example, if you were interested in upping the swap space to 4GB from 2GB, you might use +4G instead of +2G for the second partition.

After you've created the new partitions, you can check your work with:

     /sbin/fdisk -lu /dev/sdb

You should see something like this (in this example, we used +4G for the swap space):

     Disk /dev/sdb: 2000.0 GB, 1999988850688 bytes
     255 heads, 63 sectors/track, 243151 cylinders, total 3906228224 sectors
     Units = sectors of 1 * 512 = 512 bytes
     Sector size (logical/physical): 512 bytes / 4096 bytes
     I/O size (minimum/optimal): 512 bytes / 4096 bytes
     Disk identifier: 0x0000144d
     Device Boot      Start         End      Blocks   Id  System
  /dev/sdb1   *        2048     1050623      524288   83  Linux
  /dev/sdb2         1050624     9439231     4194304   82  Linux swap / Solaris
  /dev/sdb3         9439232  3906228223  1948394496   83  Linux

Since we laid out the partition table using sector numbers instead of cylinders, you'll probably see some whining from fdisk about the partitions not starting on a cylinder boundary. Since all of the cylinder/sector numbers have been fake for many years, and since all sector addressing is done using LBAs, it doesn't much matter where the partitions start/end, as long as they all start on a sector whose address is 0 mod 8. So, ignore the warnings from fdisk about cylinder alignment.

Incidentally, if the new disk is bigger than 2TB, you must use parted to format it because parted is the only partition editor that supports disks larger than 2TB. Additionally, if you have a disk that is larger than 2TB, it is guaranteed to be an advanced format disk, so you must make sure to choose a starting sector for each partition that observes the 4K block boundaries, to avoid severe performance hits. Also, to ensure compatibility with boot loaders that require more than 62 sectors following the partition table, it is smart to always start the first partition at sector 2048. Since parted has a parameter that automatically figures out what is the optimal alignment for a partition, based on disk geometry, we can just pick 2048 by default and it will tell us if that number won't work. So, run it like this:

     su
     /sbin/parted -a optimal /dev/sdc
       mklabel gpt
       mkpart primary ext2 2048s 512MiB
       set 1 boot on
       mkpart primary linux-swap 512MiB 4.5GiB
       mkpart primary ext2 4.5GiB 100%
       print
       quit

The print command should show something like this:

     Model: ATA WDC WD4003FZEX-00Z (scsi)
     Disk /dev/sdc: 4001GB
     Sector size (logical/physical): 512B/4096B
     Partition Table: gpt
     Number  Start   End     Size    File system     Name     Flags
      1      1049kB  512MB   511MB                   primary  boot
      2      512MB   4607MB  4096MB  linux-swap(v1)  primary  
      3      4607MB  4001GB  3996GB                  primary

We used the "s" after "2048" to tell parted that the first number for the first partition was a starting sector number, not a size in megabytes. We used the "%" after "100" in the last partition to tell parted that the ending sector number was 100% of the disk, in other words the last physical sector.

Once all of the partitions have been created, you must install the boot loader (Mythbuntu uses GRUB) on the disk. If you have a disk that is 2TB or less and you are not using a GNU Partition Table (i.e. you set the disk up with fdisk), you can avoid the trouble of setting up the boot sector with the boot loader by just copying the first few tracks of the source disk directly with dd.

If you copied the first sectors of an already-bootable disk (which you whould have done if you used "dd bs=512 count=2048 ..." in the first method shown above), you are all set, since you've already copied the loader.

If you had to set up a new partion table from scratch, in order to accomodate an advanced format hard drive, you can still copy the relevant MBR information from the original disk but, since we've already set up the partition table, we must do the copy very carefully to avoid wiping it out:

     dd bs=446 count=1 if=/dev/sda of=/dev/sdb
     dd bs=2 skip=255 seek=255 count=1 if=/dev/sda of=/dev/sdb
     dd bs=512 skip=1 seek=1 count=2047 if=/dev/sda of=/dev/sdb

This copies the first 446 bytes of the first sector (a.k.a. the MBR), which contains the boot loader code. It skips over the next 64 bytes, which contain the partition table. Then, it copies the two-byte magic cookie that defines it as the MBR. Finally, it copies the next 2047 sectors, which contain the GRUB Stage 1.5 code. Once that is done, you should have a bootable disk that is partitioned the way you want it.

You might want to test that the system can boot the disk (admittedly, it won't get far but you should at least see GRUB Stage 1.5 running), before you proceed any further, because, if it didn't work, now is the time to go with Plan B, before you copy any data to the new disk. Note that, if you used the third method outlined above and created a GNU Partition Table, you will nearly always have to use Plan B.

To recap, Plan B is used if you are using a GNU Partition Table (i.e. you set the disk up with parted), dd wiped out the partition table, or GRUB wouldn't boot into Stage 1.5. Plan B consists of installing GRUB from scratch, which is best done using the original OS installation disk, in rescue mode. To use Plan B, you must first copy the files to the /boot partition, as outlined below.

With the partition table defined the way you want it (and regardless of whether the disk is bootable), you can tell Knoppix to reread all of the partition information and define mount points for those partitions that it finds with this command:

     partprobe

The next step is to set up the boot partition. Hopefully, you have a separate boot partition on both the old and the new disks (it makes life so much easier). If so, the following works well to format the boot partition on the new disk with the right file system type and copy all of its data:

     dd bs=64M if=/dev/sda1 of=/dev/sdb1

For bonus points, this also copies the partition label from the old disk so that the GRUB configuration file need not be altered in order to get the system to boot. This is by far and away the easiest way to set up the boot partition. However, it depends on the two partitions being the same size or the new one being slightly larger. If that's not the case, you will need to format the new partition using the appropriate mkfs and then copy all of the old files over to it, after mounting the two partitions (old and new), using the copy command.

All of the ext2/ext3 file systems, as noted in the orginal disk's partitions, that were not set up with dd, must be made in the new disk's corresponding partitions with mkfs. Similarly, swap space must be initialized with mkswap. However, any XFS file systems need not be created ahead of time as their copy operation will take care of that for us. If the direct copy of the /boot partition wasn't used, here's an example of how we'd set up one ext2 or ext3 file system and one swap space, first using mkfs.ext2:

     mkfs.ext2 -L /boot -T news /dev/sdb1
     mkswap -v1 /dev/sdb2

or mkfs.ext3:

     mkfs.ext3 -j -L /boot -T news /dev/sdb1
     mkswap -v1 /dev/sdb2

Once you've done this, copy any files needed for the OS boot sequence to the boot partition. Knoppix thoughtfully provides predefined mount points in the "/media" directory for each of the attached devices that it finds (and even adds mount points for any new partitions created using fdisk when you use partprobe) so you can do:

     mount -r /dev/sda1 /media/sda1
     mount /dev/sdb1 /media/sdb1
     cp -R --preserve=all /media/sda1/* /media/sdb1
     umount /media/sda1
     umount /media/sdb1

Now is the time, if you are going with GRUB Plan B, to set up the boot loader (as noted above, if you set up the boot sector, etc. using one of the direct copy methods, you can omit this step). There are so many ways of doing this that it is beyond the scope of these notes. Hopefully, you won't have to do it this way but, if you do, there are plenty of notes on the Internet that give the details. Find them and read them first. Just to make sure that you do it correctly, the basic steps should look something like this:

  1. Boot with your system's Installation CD and get into rescue mode.
  2. If you are asked if you want to look for an existing Linux installation, you can skip this step. This will get you to the console prompt a lot quicker.
  3. Once the console prompt appears, type "grub".
  4. Set GRUB's root device to the partition containing the boot directory by typing "root (hd1,0)". In our case, this would be /dev/sdb1. But, you may not want to live dangerously and trust that GRUB (which uses a truly strange numbering scheme for boot devices) will pick the right device to whack. In that case, you could uncable your original disk and leave only the new disk cabled. Then, you'd set GRUB's root device using "root (hd0,0)".
  5. Write GRUB to the hard drive with "setup (hd1)" or "setup (hd0)".
  6. Bail out by typing "quit".

Note that you may be able to do all of this with Knoppix and skip the rescue disk, depending on how compatible your system is with the Knoppix version of GRUB.

The data on an original XFS partition should now be copied to the new drive. This is done with:

     xfs_copy -d /dev/sda3 /dev/sdb3

The copy will take quite a while, depending on the size of the original partition and how full it is (if you were smart and deleted all of the junk shows off the original partition, it will be faster). Once the copy completes, the new disk will contain an exact copy of the original disk and the new XFS file system will be same size as the original (bummer).

The next step requires that you mount the new file system, using the mount points that Knoppix provides in the "/media" directory:

     mount /dev/sdb3 /media/sdb3

You can check that the mounted file system looks like the original with:

     ls -l /media/sdb3

If you're happy with the new file system, you can increase its size to fill the entire partition (nice) with:

     xfs_growfs /media/sdb3

If, instead of an XFS partition, you have an ext2/ext3 partition, you can copy it with dd as follows:

     dd bs=64M if=/dev/sda3 of=/dev/sdb3

We know that we didn't discuss the direct copying of the entire old disk with dd but some people might try it, since it frequently works. If you did this and just copied the whole hard disk with dd, and the ext2/ext3 partition that you're expanding is the last on the drive, you can expand it, after the copy, like this:

     fdisk /dev/sdb
       u                                   (All sizes are given in sectors, not
                                             cylinders)
       d                                   (Delete a partition)
       3                                   (Partition 3)
       n                                   (To create a new partition)
       p                                   (As a primary partition)
       3                                   (Partition 3)
       <cr>                                (Accept prev end sector + 1 as start)
       <cr>                                (Accept last sector as the end)
       p                                   (To verify the partition table)
       w                                   (Write partition table to the disk)
     partprobe

Since none of the data in the old partition is touched when the partition is deleted or put back, it is all still there when the new partition is created.

If you wish, you can check your work:

     mount /dev/sdb3 /media/sdb3
     ls                                    (look around to see if it is OK)
     umount /dev/sdb3 /media/sdb3

All that remains is to expand the size of the file system to fill the new, bigger partition:

     fsck -n /dev/sdb3                     (only for ext3
     tune2fs -O^has_journal /dev/sdb3        file systems)
     e2fsck -f /dev/sdb3                   (nothing works without it)
     resize2fs /dev/sdb3                   (resize the file system to fit the
                                             partition)
     fsck -n /dev/sdb3                     (again? yes again)
     tune2fs -j /dev/sdb3                  (only for ext3 file systems)
     tune2fs -c 0 -i 0 /dev/sdb3           (turn off auto fsck)
     sync

If GRUB was set up to boot using the UUID of the boot partition, you may need to alter the GRUB configuration file on the /boot partition and then reinstall GRUB, if you created a new /boot partition, since its UUID will have changed. See the Recovering GRUB section below.

If your system is set up to mount partitions using UUIDs, you may have to alter /etc/fstab and change the UUID of the file system to mount on "/", depending on how you constructed and copied it.

You can find the UUID of the partition in question, in either case, using:

     /sbin/blkid /dev/sdb3

You can use vim under Knoppix, or it also has a visual editor called leaf. After mounting the appropriate partition, you can run leaf from a root console window, so that you can edit all files, like this:

     leaf &

Once that's done, unmount the new file system:

     umount /media/sdb3

Shut down Knoppix and recable the new disk to replace the original. Boot the machine with the new disk installed and see how it works. If your system will not boot, probably because the UUID of the new disk does not match the UUID in GRUB's boot configuration, see the Recovering GRUB section for help with how to recover a bootable system.

Cloning a System

You probably went to a lot of work to set up your one or more Myth TV systems, over time. Now, you wish to add another machine that's exactly the same as one of your existing system. Or, you wish to replace the hardware of one of your systems with newer (perhaps working) hardware. Either way, a useful way to speed the new system's setup is to clone an already-working system that is just like or close to how you want the new system to look.

Obtain the appropriate hardware to build a clone that looks identical to or at least close to the original system that is to be cloned. Linux has a much better sense of humor than other operating systems with respect to hardware so it will try to boot up the cloned version of the OS on a new system, despite the fact that the new hardware may be different. But, you may discover that your working system doesn't include the newer or different device drivers need to support the new hardware, so sticking as closely as possible to the original configuration may be the best idea.

You can, of course, use a larger hard drive and then, once the system is cloned, go through the steps (outlined above) to expand the hard drive in place. This should work perfectly well.

Begin by getting yourself a copy of Knoppix (the CD works perfectly fine):

     http://knopper.net/knoppix/index-en.html

And burning the ISO image onto a CD (or DVD, if you took that route).

You now need to shut down the machine to be cloned and remove its system disk. Cable it up as the second drive (with the new system's new, blank drive cabled as the first). If need be, add a temporary CD/DVD drive. In this example, we're presuming the drive to be cloned is on SATA1 and the new machine's drive is on SATA0, which should map to /dev/sdb and /dev/sda respectively, when Knoppix is booted (NOTE that the original and new drives are in reverse order (i.e. new is /dev/sda and original is /dev/sdb). Please don't do anything foolish like copying a new, zeroed drive over your original machine's good disk).

Put the Knoppix CD into the CD/DVD drive and boot it. Once Knoppix comes up (you're booting from a CD, remember, so be patient), open up a console window and become super user. To do this, simply type the "su" command. There's no password (how refreshing).

Before proceeding, you should check that the original and new drives are installed where you expect them to be. You can check this with:

     su
     /sbin/fdisk -lu /dev/sda
     /sbin/fdisk -lu /dev/sdb

or

     su
     /sbin/fdisk -lu

or, if you have disks that are larger than 2TB, you might want to use:

     su
     /sbin/parted -l

The drive on /dev/sdb should show a valid partition table with three Linux partitions (assuming a typical setup), usually type "83" or, for GNU partitions, type "ee", while the drive on /dev/sda should have no partition table. Also, if you are cloning to a larger drive, note each drive's size to ensure that the old and new drives are cabled where you expect them to be. Check this very carefully. Since, we're going to be wiping out all data on the new drive, in a minute, it pays to make sure you've got the right target in your sights. Double check to make sure you're copying the original drive to the right destination.

We use dd to copy everything on the original hard drive to the new system's drive, thereby cloning the partition layout, etc. If you're sure that the source drive is on /dev/sdb and the new, empty drive is on /dev/sda, proceed with the copy:

     su
     dd bs=64M if=/dev/sdb of=/dev/sda

The copy will take some time. We recently spent about five hours copying a 2TB drive on a modern motherboard (i.e. SATA3). Your mileage may vary.

Once the copy is done, you should have an exact duplicate of the original system's drive on /dev/sda. Remove the original drive and put it back in the original system. You can bring it back online at this point, since we are done with it.

Now, before you proceed to bring up the cloned system, and it and the original system start fighting each other for resources, start the clone without plugging in it's network cable and make some changes from the console of the new machine first.

This may require some tricky finger work on your part. When MythTV starts up without a network connection, it immediately brings up the language choice and backend configuration page. If you cancel this page, the frontend exits and is immediately restarted. You don't get any chance to do anything else. Presumably, some genius thought that this would be a smart idea (it's not). Anyway, as the frontend exits, and before it restarts, you've got a split second when you can click the right mouse button. A menu will pop up which is not overwritten by the frontend screen. From that menu, you can pick "terminal", under the "system" menu choice. Then, the Shift-Tab combo will always switch to the command shell (even if it is hidden) and bring it to the foreground. In this manner, you can do some real work, as well as launching your favorite editor. If you run as root, you can use the editor to edit the system files that must be changed to get things working (hint: "sudo /usr/bin/emacs23 &").

Begin by obtaining the MAC address of the new system's NIC. You should be able to get this using "dmesg | grep eth" (see the section Networking Your Way for more notes on this subject). However, if the proper device driver for the NIC fails to start or recognize the NIC, you will need to either obtain a pre-built copy and install it or build and install it from source.

Either way, once you have a working network driver, it should initialize the NIC and tell you what its MAC address is. Use this information to edit the following files and insert the new MAC address therein (the section Networking Your Way, above, describes this in great detail):

     /etc/udev/rules.d/70-persistent-net.rules
     /etc/network/interfaces

While you're editing /etc/network/interfaces, also change the IP address of the clone to something different than the original's address therein.

Then, give the cloned system a new name by editing:

     /etc/hostname
     /etc/hosts  (add the clone, keeping the original too)

You should then find all of the other configuration files that mention the original's name or IP address to the clone's name/address. You can find them by doing:

     su
     find /etc -exec grep -H orig-IP-addr \{\} \;
     find /etc -exec grep -H orig-hostname \{\} \;

Some suggestions are:

     /etc/samba/smb.conf
     /etc/nut/upsd.conf
     /etc/mail/local-host-names
     /etc/nut/hosts.conf

At this point, you should be able to boot up the clone and it will not collide with the original. MythTV might even work, after a fashion.

The MythTV backend has, the last time we checked, over three hundred configuration settings for its backend and frontend machines. In order for the clone to work properly, it needs to have these settings cloned, as well. To do this, begin by running mysqldump on the master backend to unload all of the settings, for the original system, into a file:

     mysqldump -uroot -p mythconverg settings --where="hostname='orighost'" \
       > Settings_CloneHost.sql

Use your favorite text editor to get rid of everything in the resultant file except for the line that begins "INSERT INTO `settings` VALUES...". This line contains all of the settings for the original system. Use the replace command to replace every occurence of the original machine's name with the clone's name.

Also, search for the IP address of the original system and replace it with the new IP address of the clone. This should be in a row that has the "value" key value set to "BackendServerIP". If you skip this step, the frontend will have trouble restarting, after you stop viewing a program (among other things).

Save the edited, one-line file and run the following:

     mysql -uroot -p mythconverg
       source Settings_CloneHost.sql

This will add all of the settings for the new system.

If you are using the same capture card configuration on the cloned system as the original, you can use the same approach to set them up on the clone:

     mysqldump -uroot -p mythconverg capturecard --where="hostname='orighost'" \
       > Settings_CloneCaptureCard.sql
     mysqldump -uroot -p mythconverg cardinput --lock-tables=false --where=\
       "cardid in (select cardid from capturecard where hostname='orighost')" \
       >> Settings_CloneCaptureCard.sql

Once again, use your favorite text editor to get rid of everything in the resultant file except for the two lines that begin with "INSERT INTO `settings` VALUES...". These two lines contain all of the capture card settings and input source mappings for the original system. Use them to set up new capture cards on the cloned machine (Hint: pick new, higher cardids and cardinputids that are above the highest capture cards currently defined on the master backend). When you're done editing, you can feed the edited file into the database like this:

     mysql -uroot -p mythconverg
       source Settings_CloneCaptureCard.sql

If your reason for cloning the old system was to eventually replace it or upgrade it, you may want to reorder the encoders on it so that they take priority over those on the old system. This will allow you to run the old system as a backup, until you're sure the new system is working (for example) but it won't do any further recording, etc.

You can figure out the capture card recording order with this command:

     mysql -uroot -p mythconverg
       select cardid, displayname, schedorder from cardinput order by cardid asc;

Here's an example of how to order some encoders (note, we're doing them in reverse order):

     mysql -uroot -p mythconverg
       update cardinput set schedorder=15, livetvorder=15 where cardid=8;
       update cardinput set schedorder=14, livetvorder=14 where cardid=7;
       update cardinput set schedorder=13, livetvorder=13 where cardid=15;
       update cardinput set schedorder=12, livetvorder=12 where cardid=12;
       update cardinput set schedorder=11, livetvorder=11 where cardid=6;
       update cardinput set schedorder=10, livetvorder=10 where cardid=5;
       update cardinput set schedorder=9, livetvorder=9 where cardid=4;
       update cardinput set schedorder=8, livetvorder=8 where cardid=3;
       update cardinput set schedorder=7, livetvorder=7 where cardid=11;
       update cardinput set schedorder=6, livetvorder=6 where cardid=10;
       update cardinput set schedorder=5, livetvorder=5 where cardid=9;
       update cardinput set schedorder=4, livetvorder=4 where cardid=14;
       update cardinput set schedorder=3, livetvorder=3 where cardid=13;
       update cardinput set schedorder=2, livetvorder=2 where cardid=2;
       update cardinput set schedorder=1, livetvorder=1 where cardid=1;

You might also want to rename the encoders so that the new recording order is reflected by them, something like this:

     mysql -uroot -p mythconverg
       update cardinput set displayname='OldGuy - HDTV 5' where cardid=7;
       update cardinput set displayname='OldGuy - Analog 3' where cardid=8;
       update cardinput set displayname='NewGuy - HDTV 3' where cardid=13;
       update cardinput set displayname='NewGuy - HDTV 4' where cardid=14;
       update cardinput set displayname='NewGuy - Analog 2' where cardid=15;

If you have any programs which are recorded by a preferred encoder, you can update them so that they'll now be recorded using one of the encoders on the new system. First, let's see if there are any shows that use the old encoders, for example, like this:

     mysql -uroot -p mythconverg
       select title from record where prefinput=7 or prefinput=8;

This should show something like this, if there are any shows with preferred inputs:

     +-------------------------+
     | title                   |
     +-------------------------+
     | Ellen                   |
     | The Late Show           |
     | New Amsterdam           |
     | This Is Us              |
     | Lifetime Saturday Movie |
     | Lifetime Sunday Movie   |
     +-------------------------+
     6 rows in set (0.00 sec)

You can change the preferred encoder for these shows so that they'll now be recorded by the new system, something like this:

     mysql -uroot -p mythconverg
       update record set prefinput=13 where prefinput=7;
         Query OK, 4 rows affected (0.00 sec)
         Rows matched: 4  Changed: 4  Warnings: 0
       update record set prefinput=15 where prefinput=8;
         Query OK, 2 rows affected (0.00 sec)
         Rows matched: 2  Changed: 2  Warnings: 0

You should now add one or more storage groups for the cloned system. To figure out what to add, list the existing storage groups:

     mysql -uroot -p mythconverg
       select * from storagegroup;

At the very least, you should see default storage groups for each of your existing systems:

     +----+-----------+----------+------------+
     | id | groupname | hostname | dirname    |
     +----+-----------+----------+------------+
     |  7 | Default   | bigguy   | /MythTV/   |
     |  8 | Default   | bigguy   | /mnt/sdb1/ |
     |  9 | Default   | bigguy   | /mnt/sdc1/ |
     | 10 | Default   | otherguy | /MythTV/   |
     | 11 | Default   | oldguy   | /MythTV/   |
     +----+-----------+----------+------------+
     5 rows in set (0.00 sec)

Using the information from above, add at least the Default storage group, and possibly others, for the new system:

     mysql -uroot -p mythconverg
       insert into storagegroup values(12,'Default','newguy','/MythTV/');

Your storage groups should now look something like this:

     +----+-----------+----------+------------+
     | id | groupname | hostname | dirname    |
     +----+-----------+----------+------------+
     |  7 | Default   | bigguy   | /MythTV/   |
     |  8 | Default   | bigguy   | /mnt/sdb1/ |
     |  9 | Default   | bigguy   | /mnt/sdc1/ |
     | 10 | Default   | otherguy | /MythTV/   |
     | 11 | Default   | oldguy   | /MythTV/   |
     | 12 | Default   | newguy   | /MythTV/   |
     +----+-----------+----------+------------+
     6 rows in set (0.00 sec)

If you mirrored all of the recordings from the old system onto the new system, and you'd like them to be served from the new system, you can update their recorded status so they'll be served from there. You can first find out which recordings need to be switched over with a command similar to this:

     mysql -uroot -p mythconverg
       select hostname, title from recorded where hostname='oldguy';

You'll see something like this:

     +----------+-------------------------+
     | hostname | title                   |
     +----------+-------------------------+
     | oldguy   | America's Test Kitchen  |
     | oldguy   | This Morning            |
     | oldguy   | Manifest                |
     | oldguy   | Manifest                |
     | oldguy   | Nightly Business Report |
     | oldguy   | Nightly Business Report |
     | oldguy   | This Morning            |
     | oldguy   | The Orville             |
     +----------+-------------------------+
     8 rows in set (0.01 sec)

Then, use the following SQL command to make the switch:

     mysql -uroot -p mythconverg
       update recorded set hostname='newguy' where hostname='oldguy';

Adding a New System

The easiest way to add a new system is to follow the steps above, in "Cloning a System", to clone an existing system and then keep the new one as well as the original one.

Recovering GRUB

GRUB pretty much wins hands down for the most inscrutable configuration file of any product (sendmail comes second). So, if you are faced with having to recover GRUB (because your system won't boot), your best option is by far and away to use the Ubuntu boot repair tool.

Simply boot up the Mythbuntu install disk (making sure that you have a working Internet connection) and, when it is finished booting, select the "Try Mythbuntu" selection. This will eventually bring up the desktop.

Once you are looking at the desktop, under the Applications/Accessories/ Terminal menu choice, launch a terminal window. Type the following commands into the terminal window:

     sudo apt-add-repository ppa:yannubuntu/boot-repair
     sudo apt-get update
     sudo apt-get install -y boot-repair
     sudo boot-repair

You can disregard the whining by apt-get when you run update (truly, an idiot message that reads "..., run apt-get update to fix these problems", when you are running apt-get update is way beyond idiotic). Select the "Recommended repair" choice and follow the tool's instructions. Hopefully, when it's done you're good to go.

Alternately, if boot-repair doesn't work, or you want to do it yourself, or you don't have an Internet connection whereby you can install boot-repair, you can follow the steps above to fire up a terminal window, and then do the repairs from the command line. From the command window, proceed as follows:

     sudo fdisk -l

This will list all of the disk partitions. Figure out which of the partions is the actual boot partition. If you only have two partitions on the system disk (e.g. "/" and swap), then your boot partition is "/". If you have a separate boot partition (e.g. "/boot"), then your boot partition is "/boot". Mount the boot partition:

     sudo mkdir /mnt/bootdisk
     sudo mount /dev/sdxx /mnt/bootdisk

Replace "sdxx" with the name of your boot partition.

If you know how to use vi, you can edit your GRUB configuration file using it. Or, if you do have an Internet connection and you want to use gedit, you can install it like this:

     sudo apt-get install gedit

Using whatever text editor you choose (you can even boot another operating system such as Knoppix and edit the GRUB config file with it), edit the GRUB config file (grub.cfg). Make sure that you are editing the one under /mnt/bootdisk, not the one that comes with the trial Mythbuntu. Bear in mind that you only want to monkey with this file as little as possible. Probably, you will only need to alter one or two menu entries, and then only to change the UUIDs of the various boot partitions. If you search for your old disk's UUIDs, you'll see what needs to be changed. More likely than not, you'll only need to change the first or second menu entries (although, if your system has been upgraded, there may be more, which point to prior versions of Ubuntu). A typical menu entry should look like this:

     menuentry 'Ubuntu, with Linux 3.2.0-24-generic' --class ubuntu \
       --class gnu-linux --class gnu --class os {
         recordfail
         gfxmode $linux_gfx_mode
         insmod gzio
         insmod part_msdos
         insmod ext2
         set root='(hd0,msdos1)'
         search --no-floppy --fs-uuid \
           --set=root 5c5f0c51-55cc-47e3-b77e-ca400b46af9b
         linux /vmlinuz-3.2.0-24-generic \
           root=UUID=325cef3c-97ce-47de-f7ff-e4ff0a2101f0 \
           ro quiet splash $vt_handoff
         initrd /initrd.img-3.2.0-24-generic
       }

The UUID of your separate boot partition follows the "--set=root" parameter of the search command, if you are using a separate boot partition. Otherwise, this is the UUID of your system partition. If you are using a separate boot partition, the path names like "/vmlinuz..." and "/initrd..." start with "/". Otherwise, they will start with "/boot/". The "root=UUID=" parameter of the linux command is the UUID of your system partition.

These are usually the only things that you will need to edit. If you think that you need to change "(hd0,msdos1)", you probably shouldn't. If you are now trying to boot Mythbuntu from a GPT instead of MSDOS partition table, you should read these three notes on how to do it:

     https://www.anchor.com.au/blog/2012/10/\
       the-difference-between-booting-mbr-and-gpt-with-grub/
     http://www.wensley.org.uk/gpt
     http://www.rodsbooks.com/gdisk/booting.html

Once you have done making changes to grub.cfg, you can reinstall GRUB onto your system disk, pointing it at the appropriate spot in the mounted partition:

     sudo grub-install --boot-directory=/mnt/bootdisk/boot /dev/sdx

or

     sudo grub-install --boot-directory=/mnt/bootdisk /dev/sdx

You should now be able to boot the system from the new or moved disk.

Performance and Tuning

If you've chosen XFS for any of your system or storage volumes, fragmentation can be a problem which noticably affects performance. Luckily, there are a couple of relatively easy steps that can be taken.

The first is to see how bad fragmentation is. This is done using the xfs_db command. For example, on a storage volume, you'd do something like this:

     sudo xfs_db -c frag -r /dev/sdb1

On a combinded system/storage volume that is contained in the third partition on your disk, you might try something like this:

     sudo xfs_db -c frag -r /dev/sda3

Its time to defrag the system if the results of the command look like this:

     actual 209967, ideal 1022, fragmentation factor 99.51%

Numbers like 30-100% will probably impact performance.

Begin by making sure xfs_fsr is installed. It is part of the xfsdump package, which can be installed with:

     sudo apt-get install xfsdump

Of course, you can certainly run the xfs_fsr command at any time you like, by hand. However, the easiest way to ensure that fragmentation does not cause problems is to add commands to your crontab to defragment regularly, at off peak times.

If all of the XFS volumes are storage only (i.e. you run the OS from a separate non-XFS volume and only use the XFS volumes to store recordings, etc.), the following lines in crontab will work well:

     # Let's defrag all of the XFS volumes in mtab.  We'll work on 'em for a
     # couple of hours per night, which should keep them in good shape, since
     # there's not THAT much activity, on a daily basis.  Hopefully, there's
     # not too much going on when we do it.
     00 3  * * *  root  /usr/sbin/xfs_fsr -t 7200 >/dev/null 2>&1

The above command will defragment all of the XFS volumes defined in /etc/mtab for two hours each night. If the defragmentation isn't done at the end of the two hours, it will pick up where it left off the next night.

It is important that you do not run xfs_fsr on your root partition (e.g. /dev/sda3 on a system/storage volume) or on the partition that contains your boot files (e.g. /dev/sda1 on the same volume). Instead, for combined system/storage volumes we use a find command to find all of the files in the MythTV directory (i.e. the directory where recordings are stored) and defrag them one at a time.

     # Since we can't defrag all of the XFS volumes because the OS is on one
     # of them, we'll defrag only the MythTV recording files.  Since the OS
     # rarely changes, this should handle the bulk of it.  Hopefully, there's
     # not too much going on when we do it.
     00 3  * * *  root  /usr/bin/find /MythTV -type f \
                        -exec /usr/sbin/xfs_fsr \{\} \; >/dev/null 2>&1

Unfortunately, there is no way to specify a time limit on this method but, after it has been done once, it should complete in a reasonable length of time, certainly less than a couple of hours.

Updates and Upgrading To A Later Release Of Mythbuntu

Generally, you do not want allow automatic updates to be applied to your system. While a good idea for a desktop or laptop system that is talking to the outside world, updates to an appliance-like system can often be bad news. The update process is not smooth enough or considerate enough of the special MythTV environment to proceed without mishap. Quite often, updates will break device drivers used for network cards, the display and the TV encoders. Any of these kinds of problems could prevent your Mythbuntu system from performing its primary role of recording programs and/or viewing them. When you want to watch the latest episode of Gossip Girl but it turns out that the system only recorded dead air because of some ill-conceived update, you won't be happy.

We suggest doing updates under controlled circumstances, all at once. If there is a block of time when the system isn't doing any work (minimum 8 hours), that's the time to schedule minor updates like patches. For major updates like version upgrades, a minimum of 48 hours is more like it. The problem of finding a window when updates can be applied is exacerbated if the system to be updated is the master backend, since any other secondary backends will rely on it for the database. However, it is very important to find a decent-sized window in which to do the work, since you don't need any time pressures when you're trying to straighten out all of the screw-ups caused by the updates.

Meanwhile, if you are doing kernel updates or a complete system upgrade, prior to beginning the process (i.e. before your update window begins), if your system needs any special network interface drivers, pre-build them, following the instructions in the "NIC Drivers" section, above. You can do this step at any time so why not get it out of the way before the time pressure begins. Since updates or upgrades frequently break the network interface, copy the drivers needed, for the new kernel or each of the intermediate Mythbuntu versions used in the upgrade, onto the system disk now so you won't have to put them on a CD later on. You should put them in the directory where your other special system drivers are stored. We use a subdirectory for each version and name them according to the Mythbuntu release that they apply to. For example:

     Ubuntu-8.10
     Ubuntu-9.04
         .
         .
         .

Incidentally, when you upgrade to Mythbuntu 11.10, the display manager is switched from GDM to LightDM. Unfortunately, although a fresh install of Mythbuntu 11.10 works, the upgrade procedure does not. Instead of making the switch to LightDM seamlessly, GDM is left partially installed, LightDM is not installed properly, and your system is left in a state whereby the display manager won't come up on the primary display. In other words, you're screwed.

What does this mean for you? Well it means that you'd better have a working NIC, that is supported by the default NIC drivers, that are included in Ubuntu-11.10. And, you'd better make sure that the network connection is going to come up automatically, all by itself.

The best way to make this happen is to set the network connection to DHCP before you begin the upgrade. And make sure that SSH is installed, configured and turned on so that you can login. And, if you've got some kind of flake-oh NIC on the motherboard, that requires a special build of the NIC device driver, you should go get a "regular" NIC and plug it in. Make sure it all works by itself, when you reboot the machine.

Because, if you don't, you're going to need to figure out how to boot the standalone Knoppix disk and repair the broken config files when you brick your system. Or, you're going to have to work out how to carry out the repairs from the console on the primary display (press <Ctrl-Alt-F2>, or <Ctrl-Alt-F3>, or <Ctrl-Alt-F4>, or F5, or F6, or whatever works). In either case, the actual steps necessary to repair the system are outlined further on but it will be a lot easier if you can login from a remote system via SSH.

The first step, when doing updates or an upgrade, should be to take a copy of the MySQL database. This database contains all of the information about when recordings should be done, what was recorded, etc., etc. If you lose this database, you are really not going to be happy. Use whatever MySQL backup procedure you feel confident with to get a copy of the "mythconverg" database from /var/lib/mysql.

For upgrades, the second step should be to make an exact copy of the Mythbuntu system's hard drive. You should use a drive that is at least as big as the original drive and copy everything over. If you wish, now would be a good time to upgrade the drive's capacity too. The upgrade should be performed on the copy, not the original. This allows you to back off all of the upgrade changes in one easy step, should the upgrade fail. Believe us, we've had to do this several times so skipping this step should not be an option. You'll be sorry if you do.

It is not possible to upgrade a release of Mythbuntu more than one step at a time. So, for example, if your system is 8.04 and you wish to upgrade to 9.04, you must first upgrade to 8.10. Sorry, that's just the way it is. This becomes an especial pain in the butt if you've waited too long to do the upgrade and the online updates are no longer available and/or you've applied special drivers (particularly the NIC driver) to your system. We'll assume that's the case (if you don't anticipate a problem with the NIC driver, you can simply do online upgrades from the Upgrade Manager under the GUI or from the command line with dpkg).

Begin by downloading the "alternate" distribution ISOs for all of the intermediate versions of Mythbuntu between your current version and the version you wish to upgrade to. You can get the distro for the final version too, if the updates for it aren't available online. Burn all of the ISOs to DVDs.

Boot Mythbuntu using the copy of the system disk that you made above. Apply all of the available online updates to your current Mythbuntu version. Once you've done this (and you reboot), your network may stop working. Don't panic.

The upgrade to the next version of Mythbuntu can be done using the "alternate" distro, despite there being no connection to the Internet. Proceed as follows:

     Insert the CD into the CD/DVD drive of the computer to be upgraded.
     A dialog will be displayed offering you the opportunity to upgrade using that
     CD.
     Follow the on-screen instructions.
     If the upgrade dialog is not displayed for any reason, you may also run the
     following command using Alt+F2:
     sudo gksu "sh /cdrom/cdromupgrade"

Note that, if you used pcsk, as described in "Keeping MythBackend Up And Running", to keep the backend up and running, you may experience a hang during the last stages of the upgrade when the install script for Myth Backend tries to start the mythtv-backend service. If this is the case, open up the console window of the install (checkbox at bottom of install window) and press "Ctrl-C". This will bail out of that step and the install will complain that it didn't work. Don't worry, be happy.

You should be able to fix up the pcsk problem by reaiming the symlink at the original mythtv-backend and the rerunning the backend reconfigure script. Try this:

     sudo rm -f /etc/init.d/mythtv-backend
     sudo ln -s /etc/init.d/mythtv-backend.orig /etc/init.d/mythtv-backend
     sudo dpkg-reconfigure mythtv-database
     sudo rm -f /etc/init.d/mythtv-backend
     sudo ln -s /etc/init.d/mythtv-backend.pcsk /etc/init.d/mythtv-backend

If this doesn't work, you should run the Myth Backend configuration (from the System menu) application and check the basic database connection information under the General menu item. Usually, the IP address of the database server will have to be reentered, if any changes are necessary. You probably should use a specific IP address instead of "localhost". The rest of the configuration information is stored in the database and should not need to be updated.

Incidentally, you may want to do a diff against mythtv-backend.pcsk and mythtv-backend.dpkg-new to see if any of the changes that the upgrade wants to make are actually important.

After you've done the upgrade and rebooted, your network may still not be working. The first step in getting it to work may be to rip out the Network Manager (again) as described in "Networking Your Way" (above) and set up the network the way you really want it. Then, apply the proper, pre-built NIC driver, as described in "NIC Drivers" (above) for the release that you are at. This should get the network working again.

As we noted above, when you upgrade to Mythbuntu 11.10, the display manager is switched from GDM to LightDM and, unfortunately, the switch does not work. When you reboot your system after the upgrade, the if the primary display comes up and flashes continuously, here's what we did to fix the problem.

Either login via SSH from a remote terminal or switch to the console on the primary display (press <Ctrl-Alt-F2>, or <Ctrl-Alt-F3>, or <Ctrl-Alt-F4>, or F5, or F6, or whatever works). Then, do the following:

     su
     stop lightdm
     ps x | grep light
     You may have to do a "kill -9" if there are any lightdm processes still
       running.
     apt-get install --reinstall lightdm
     dpkg-reconfigure lightdm
     Choose lightdm as your greeter.
     apt-get remove unity-greeter
     cd /etc/lightdm
     rm -f unit-greeter.conf
     nano lightdm.conf

When the text editor displays the lightdm.conf file, edit it to look like this:

/etc/lightdm/lightdm.conf:

     [SeatDefaults]
     autologin-guest=false
     autologin-user=AUTOLOGINUSER
     autologin-user-timeout=0
     autologin-session=lightdm-autologin
     user-session=mythbuntu
     allow-guest=false
     greeter-session=lightdm-gtk-greeter

You need to replace "AUTOLOGINUSER" to the name of the user that is normally logged in when the system starts up. This may be the "mythtv" user or it may be the user that you defined (besides root) when the system was initially installed. After you've done that, save the file and carry on. If you are really worried about GDM still starting up (it shouldn't, but you never know) you can do either (or both) of these:

     su
     update-rc.d -f gdm remove
     mv /etc/init/gdm.conf /etc/init/gdm.conf.off

Another thing you can check is that default-display-manager file in the X11 directory is set to lightdm. It should look like this:

/etc/X11/default-display-manager:

     /usr/sbin/lightdm

At this point, you should be able to start lightdm and X-Windows will come up on your primary display. You will either see the desktop or, if MythTV is set to auto start, you'll see it starting up:

     su
     start lightdm

If this doesn't work, you may still need to repair any changes made to the xorg.conf file by the system upgrade. You can begin by trying automatic configuration:

     su
     stop lightdm
     Xorg -configure
     cd /etc/X11
     mv xorg.conf xorg.conf.backup
     mv /root/xorg.conf.new .
     start lightdm

You may need to tweak the configuration file that is generated by configure but it is supposed to match your hardware. If it doesn't (usually because X-Windows cannot probe the monitor to get the EDID), LightDM may not start. A Web page that describes how to fix the problem can be found here:

     http://taggedzi.com/blog/display/ubuntu-11-and-nvidia-173-woes

If worst comes to worst, we keep a generic xorg.conf file that we can use when configure fails. This file is for NVidia graphics chipsets. It ain't much but it may get you up and running:

/etc/X11/xorg.conf.workee:

     Section "Monitor"
         Identifier      "Configured Monitor"
     EndSection
     Section "Screen"
         Identifier      "Default Screen"
         Monitor         "Configured Monitor"
         Device          "Configured Video Device"
         DefaultDepth    24
     EndSection
     Section "Module"
         Load    "glx"
     EndSection
     Section "Device"
         Identifier      "Configured Video Device"
         Driver          "nvidia"
         Option          "NoLogo"  "True"
     EndSection

If you have a different chipset, you'll need to change the video device driver name.

A cycle of all of the steps, beginning with booting Mythbuntu and applying all of the available online updates, ensues. You apply the online updates to the current release to bring it up to snuff and then upgrade it to the next release. Once you've finally arrived at the release that you're trying to get to, move on to the next step.

The upgrade process usually wipes out proprietary device drivers, etc. The NIC driver will already have been installed in the prior steps. You should also fire up the Mythbuntu Config tool (from the System menu) and install any of the recommended proprietary device drivers (e.g. NVidia). However, if you built the latest NVidia driver from scratch because you have a display that is not recognized by the regular, proprietary device driver, you will need to reinstall it because the driver will have been compiled against a kernel that is no more (see, for example, the Newest NVidia Driver section, above).

If you installed any special drivers (e.g. the saa7134-dvb driver, as described in "AVerMedia A180 Capture Card", above), you may need to reinstall them. Follow the steps outlined in the appropriate sections elsewhere. And, note that the names of the various blacklist and config files in /etc/modprobe.d may have changed. The newer versions of Mythbuntu require that the blacklist and config files (except for "options") be suffixed with ".conf". So, beware that the names of the files used to blacklist your special drivers may have changed.

Another feature of the wiping-out-drivers philosophy is that the sound control settings that you very carefully set, using alsamixer, are often wiped out too. If you experience sound problems (e.g. reduced volume) after the upgrade, see the section on "Sound Problems" (above) for tips on how to fix those sound problems.

When you upgrade to a later release of Mythbuntu (i.e. >= 9.04), you should read the section above about "Update Manager -- Not Another Good Idea". Upon upgrading to the later release of Mythbuntu, you will probably find the new behavior of the Update Manager to be a real pain in the butt and want to consult this section about how to turn it off immediately.

Since you'll probably be installing and removing packages as you go, you may want to consult the "Useful Software" and "Useless and Annoying Software" sections to at least figure out how to add the Synaptics Package Manager and remove the Ubuntu Software Center. While you're at it, you might as well install the rest of the useful packages and remove the rest of the annoying packages. All of your previous efforts, in this respect, will have been tossed away during the system upgrade.

And, speaking of butt pain, you may discover that the setup of your desktop has been altered when you upgrade to a later release of Mythbuntu. The most noticeable "feature" will be the disappearance of the desktop toolbar. If this happens, or if you notice any other little infelicities on your desktop, when you upgrade, you should see the "Desktop Problems" section, above, for notes about what to do.

Another "feature" of later releases of Mythbuntu is that the halt and shutdown commands that are invoked by the Myth frontend have been replaced by a shell script that uses dbus to tell HAL that it should shutdown or reboot the system. Too baddy that it only works some of the time. You may want to proceed to the Utilities/Setup/General menu item in the frontend and page forward to the Miscellaneous page where you can set:

     Halt Command: halt
     Reboot Command: reboot

On the other hand, if you really like the concept of using dbus to tell HAL what to do, you should upgrade these two settings for the newly upgraded system, since they will be left as is from before. The new settings are:

     Halt Command: /usr/share/mythtv/myth-halt.sh
     Reboot Command: /usr/share/mythtv/myth-reboot.sh

As with all upgrades to Mythbuntu, the LIRC setup is wiped out so your remote control will no longer work. If you are lucky, your orginal files will be preserved and suffixed with "dpkg-old" or maybe just "old". You can then delete the new files, installed by the upgrade, and replace them by the dpkg-old or old files. Here's what to look at:

     /etc/init.d/lirc
     /etc/lirc/hardware.conf
     /etc/lirc/lircd.conf

The lircd.conf file is made up on the fly by the lirc service script so you can just delete the newly-installed version. The lircd.conf.dpkg-old file can just be deleted too. Meanwhile, you should replace the /etc/init.d/lirc file with the script shown above, and the /etc/lirc/hardware.conf file with the saved one that you found under hardware.conf.old or that you saved elsewhere or that you made up according to instructions above.

Any upgrades to Mythbuntu may cause the MythWeather package to be upgraded too. If this happens, you are likely to lose any changes to the weather information extraction scripts that you made. Consequently, if you've included the Current Conditions page on your Mythbuntu weather page and the extraction script hasn't yet been fixed or if you've added any custom weather information extraction scripts, you may have to go back and reinstall the scripts, as described in the MythWeather section (above).

You should check the mythtv-database script, if you've upgraded it to run daily instead of weekly, to ensure that it is still in the /etc/cron.daily directory. Also, recheck that the upgrade has not added a copy of this script back to the /etc/cron.weekly directory where it will conflict with the running of the script on a daily basis.

If you are mounting sharepoints to support a remote video server (as described below under "Mounting Shares Under Mythbuntu"), you may find that the mounts no longer work. The upgrade will probably leave /etc/fstab as it was so that the mounts are still found in fstab but they will fail because the utilities supplied by the smbfs package will be missing. The upgrade will have removed the smbfs package. Searching for "samba" in the package manager should yield a list. If smbfs is not installed, follow the steps described in "Mounting Shares Under Mythbuntu" to install it and get the mounts working.

Also, if you have any additional drives that were formatted with the XFS file system, and the XFS file system wasn't installed on the system drive, you will probably see a message about "a serious error" upon startup, as the system tries to mount these drives. You can choose to skip the error and then mount the drives later on, with no problems, like this:

     mount /mnt/sdb1

So, what's going on? Because the system drive isn't an XFS drive, the upgrade decided that there was no need to install the xfsprogs package. This package contains the fsck.xfs program which is needed to check XFS drives. Since it was missing, when fsck tried to invoke it to check the XFS drives at startup, the check failed and fsck decided that there was a serious error. However, there's nothing really wrong with the drives, which is why you can mount them later on. The solution is to reinstall the xfsprogs package, like this:

     apt-get install xfsprogs

If you set up UPS monitoring with NUT, it will probably no longer work after a release upgrade. In all probability, any changes to the udev rules will be wiped out by the upgrade, which will disallow NUT from taking control of the UPS devices as it should. Another clever trick of release upgrades is to wipe out changes you've made to startup scripts in /etc/init.d with something "better" or "smarter". You should go over the install instructions in the UPS Monitoring with NUT section (above) to make sure that UPS monitoring is still installed and working correctly.

After you've completed your upgrade and tested everything thoroughly, you should reboot all of the other secondary backends and frontends in your network, if they depend on the upgraded machine as a primary backend. Don't ask me why this is necessary but it is. Some things will appear to be working OK, before the reboot, but others (e.g. sharing encoders across the network) will not work. The reboot seems to cure all.

Using the Latest MythTV Release

The Mythbuntu team provides a package (mythbuntu-repos) that provides a set of repositories which can be easily activated to update the software shipped with Mythbuntu to later versions and/or install additonal packages. The packaging used for the builds in these repositories is identical to that used for content in the Ubuntu archive so the use of these repositories is seamless.

The repository installed by the mythbuntu-repos package contains updates to MythTV that are automatically built each day when there are upstream fixes available. The repository also contains fixes for software written specifically for Mythbuntu such as Mythbuntu Bare, Mythexport and Mythbuntu Log Grabber.

Once the package is installed, you can control how it is deployed from the Mythbuntu Control Center. From the MCC, you can select the MythTV series that you wish to receive updates for, enable or disable updates to the Mythbuntu-specific applicatons, or even disable the use of the repository altogether, if you no longer desire to make use of it in the future.

You typically would use the repository installed by the mythbuntu-repos package if you want to install and keep up to date with a later version of MythTV than the one shipped with your version of Mythbuntu (e.g. on Mythbuntu 10.10, you wish to use MythTV 0.24), if you want to test the development version of MythTV, or if you want to upgrade to a Beta version of MythTV but not keep up with any of the later development updates.

Selecting a MythTV series from the Mythbuntu Control Center will only get you updates for that series. So, for example, if you select MythTV 0.24, you will only receive updates that upstream releases to the 0.24 series. To change to another series (such as 0.25), simply open the Mythbuntu Control Centre again, and modify the Repositories tab to the new series.

To begin, you can install the mythbuntu-repos package from the browser, on the system where it is to be installed, by surfing over to:

     http://www.mythbuntu.org/auto-builds

Once you get to that page, follow the "Install the Mythbuntu-repos package" link. After you've done that, you need to run the software updater (from the desktop/system menu) to install all of the updates that are implied by the series of MythTV that you choose during the install.

Alternately, you can do the following from the command line (in a temporary directory):

     su
     wget http://www.mythbuntu.org/files/mythbuntu-repos.deb
     dpkg -i mythbuntu-repos.deb
     apt-get update
     apt-get upgrade

In this case, when you install the repository, you'll choose the MythTV series that you want installed on your system and then, when you run the upgrade, you'll be upgraded to that series.

At a later date, you can proceed to the Mythbuntu Control Center and select a different series. If you do so, be sure to run the software updater (from the desktop/system menu) to install all of the updates that are implied by the new series of MythTV that you choose.

Caching Updates With Apt-Cacher

If you do decide to judiciously apply updates or patches to your Mythbuntu machines (see the Updates and Upgrading To A Later Release Of Mythbuntu), and you have more than one machine, and you keep all of the machines at the same distribution level, you might want to consider using apt-cacher to cache a local copy of the updates, so that all of your machines do not need to repeatedly download the updates off the Internet.

You should choose a machine which will hold the cache repository and set up apt-cacher there. We usually pick the same machine as the master backend, since it is (by default) visible to all of the other systems and must be running at all times. However, any machine with enough spare disk space to support the cache can be used.

Begin by installing the apt-cacher package thusly:

     sudo apt-get install apt-cacher

Once this is done, edit the apt-cacher configuration file (/etc/apt-cacher/apt-cacher.conf) to set up your specific options. Although you shouldn't have to change much, here are a few things for your consideration.

The default port that apt-cacher runs on is port 3142. You might want to change it if it collides with something else on your system (we can't think what, but ya never know).

By default, all hosts are allowed to use the repository cache. You probably want to lock this down so that only hosts on your local subnet can use it. For example, if your local subnet is 192.168.1, and you want to allow all machines on it and the local host to use the cache, you might set:

     allowed_hosts=192.168.1.0/24, 127.0.1.1

The traditional local host (127.0.0.1) is allowed by default so it is not necessary to add it. Apparently, on Ubuntu boxes, 127.0.1.1 is also considered to be the local host (if this is really true, nice going boneheads -- just what we need is another way of doing the same old thing differently) so, just in case somebody has a go at the cache with that IP address we allow it too.

By default, apt-cacher creates a report on a daily basis on how efficient your cache was. You might think, what's the point, who needs this? If so, you can turn it off:

     generate_reports=0

The part of the configuration that you do have to set up is the path map. This tells apt-cacher where to look for the packages that are to be fetched for its clients and stored in the cache. You'll probably want to include all of the repositories, that are going to be used by the clients, in this list.

We begin making up the list by examining the original /etc/apt/sources.list files on one or more, perhaps all, of the client machines. Here's a sample:

/etc/apt/sources.list:

     deb http://us.archive.ubuntu.com/ubuntu jaunty \
         main restricted universe multiverse
     deb http://us.archive.ubuntu.com/ubuntu jaunty-updates \
         main restricted universe multiverse
     deb http://security.ubuntu.com/ubuntu jaunty-security \
         main restricted universe multiverse
     deb http://archive.canonical.com/ubuntu jaunty partner
     deb-src http://us.archive.ubuntu.com/ubuntu jaunty-updates \
         main restricted universe multiverse
     deb-src http://us.archive.ubuntu.com/ubuntu jaunty \
         main restricted universe multiverse
     deb-src http://security.ubuntu.com/ubuntu jaunty-security \
         main restricted universe multiverse
     deb-src http://archive.canonical.com/ubuntu jaunty partner

There's a lot of commonality in the URLs that are found in this sample file. Essentially, there are three types: the Ubuntu archives; the security archives; and the archives of the bonus packages from Canonical. In the apt-cacher path list, we need to map these URLs to an alias name that the clients can use to reference those archives. The names chosen for the aliases don't matter but it is better to choose something that makes sense to you. Based on the URLs in the original /etc/apt/sources.list, we might set the path list up like this:

     path_map = ubuntu us.archive.ubuntu.com/ubuntu ; \
                security security.ubuntu.com/ubuntu ; \
                canonical archive.canonical.com/ubuntu

Normally, its OK to use the URLs that your system installation chose. But, if you are experiencing performance delays or other problems, now is a good time to choose mirrors that actually work for you. If you need help deciding which ones to use, the list can be found at:

     https://launchpad.net/ubuntu/+archivemirrors

According to the Ubuntu documentation, "if you are unsure which mirror to select the best option is [iso-country-code].archive.ubuntu.com where iso-country-code is the two character country abbreviation of a country near you. For example, if you live in the United States you could choose us.archive.ubuntu.com".

Once you've set up aliases to all of the URLs in the path list, you can access them on the client machines like this:

     repository_cache_machine:port/alias_name

So, for instance, we can access the ubuntu and security repositories through:

     http://myrepository:3142/ubuntu
     http://myrepository:3142/security

Now that we've chosen all the local options, here is a complete listing of a sample apt-cacher configuration file:

/etc/apt-cacher/apt-cacher.conf:

     #################################################################
     # This is the config file for apt-cacher. On most Debian systems
     # you can safely leave the defaults alone.
     #################################################################
     # cache_dir is used to set the location of the local cache. This can
     # become quite large, so make sure it is somewhere with plenty of space.
     cache_dir=/var/cache/apt-cacher
     # The email address of the administrator is displayed in the info page
     # and traffic reports.
     admin_email=root@localhost
     # For the daemon startup settings please edit the file
     # /etc/default/apt-cacher.
     # Daemon port setting, only useful in stand-alone mode. You need to run the
     # daemon as root to use privileged ports (<1024).
     daemon_port=3142
     # optional settings, user and group to run the daemon as. Make sure they have
     # sufficient permissions on the cache and log directories. Comment the
     # settings to run apt-cacher as the native user.
     group=www-data
     user=www-data
     # optional setting, binds the listening daemon to specified IP(s). Use IP
     # ranges for more advanced configuration, see below.
     # daemon_addr=localhost
     # If your apt-cacher machine is directly exposed to the Internet and you are
     # worried about unauthorised machines fetching packages through it, you can
     # specify a list of IPv4 addresses which are allowed to use it and another
     # list of IPv4 addresses which aren't.
     # Localhost (127.0.0.1) is always allowed. Other addresses must be matched
     # by allowed_hosts and not by denied_hosts to be permitted to use the cache.
     # Setting allowed_hosts to "*" means "allow all".
     # Otherwise the format is a comma-separated list containing addresses,
     # optionally with masks (like 10.0.0.0/22), or ranges of addresses (two
     # addresses separated by a hyphen, no masks, like '10.100.0.3-10.100.0.56').
     allowed_hosts=192.168.1.0/24, 127.0.1.1
     denied_hosts=
     # And similarly for IPv6 with allowed_hosts_6 and denied_hosts_6.
     # Note that IPv4-mapped IPv6 addresses (::ffff:w.x.y.z) are truncated to
     # w.x.y.z and are handled as IPv4.
     allowed_hosts_6=fec0::/16
     denied_hosts_6=
     # This thing can be done by Apache but is much simpler here - limit access
     # to Debian mirrors based on server names in the URLs
     #allowed_locations=ftp ftp.uni-kl.de,ftp ftp.nerim.net,debian.tu-bs.de
     # Apt-cacher can generate usage reports every 24 hours if you set this
     # directive to 1. You can view the reports in a web browser by pointing
     # to your cache machine with '/apt-cacher/report' on the end, like this:
     #      http://yourcache.example.com/apt-cacher/report
     # Generating reports is very fast even with many thousands of logfile
     # lines, so you can safely turn this on without creating much 
     # additional system load.
     generate_reports=1
     # Apt-cacher can clean up its cache directory every 24 hours if you set
     # this directive to 1. Cleaning the cache can take some time to run
     # (generally in the order of a few minutes) and removes all package
     # files that are not mentioned in any existing 'Packages' lists. This
     # has the effect of deleting packages that have been superseded by an
     # updated 'Packages' list.
     clean_cache=1
     # Apt-cacher can be used in offline mode which just uses files already
     # cached, but doesn't make any new outgoing connections by setting this to 1.
     offline_mode=0
     # The directory to use for apt-cacher access and error logs.
     # The access log records every request in the format:
     # date-time|client ip address|HIT/MISS/EXPIRED|object size|object name
     # The error log is slightly more free-form, and is also used for debug
     # messages if debug mode is turned on.
     # Note that the old 'logfile' and 'errorfile' directives are
     # deprecated: if you set them explicitly they will be honoured, but it's
     # better to just get rid of them from old config files.
     logdir=/var/log/apt-cacher
     # apt-cacher can use different methods to decide whether package lists need
     # to be updated,
     # A) looking at the age of the cached files
     # B) getting HTTP header from server and comparing that with cached data.
     # This method is more reliable and avoids desynchronisation of data and index
     # files but needs to transfer a few bytes from the server every time somebody
     # requests the files ("apt-get update")
     # Set the following value to the maximum age (in hours) for method A or to 0
     # for method B
     expire_hours=0
     # Apt-cacher can pass all its requests to an external http proxy like
     # Squid, which could be very useful if you are using an ISP that blocks
     # port 80 and requires all web traffic to go through its proxy. The
     # format is 'hostname:port', eg: 'proxy.example.com:8080'.
     #http_proxy=proxy.example.com:8080
     # Use of an external proxy can be turned on or off with this flag.
     # Value should be either 0 (off) or 1 (on).
     use_proxy=0
     # External http proxy sometimes need authentication to get full access. The
     # format is 'username:password'.
     #http_proxy_auth=proxyuser:proxypass
     # Use of external proxy authentication can be turned on or off with this
     # flag.  Value should be either 0 (off) or 1 (on).
     use_proxy_auth=0
     # This sets the interface to use for the upstream connection.
     # Specify an interface name, an IP address or a host name.
     # If unset, the default route is used.
     #interface=
     # Rate limiting sets the maximum bandwidth in bytes per second to use
     # for fetching packages. Syntax is fully defined in 'man wget'.
     # Use 'k' or 'm' to use kilobits or megabits / second: eg, 'limit=25k'.
     # Use 0 or a negative value for no rate limiting.
     limit=0
     # Debug mode makes apt-cacher spew a lot of extra debug junk to the
     # error log (whose location is defined with the 'logdir' directive).
     # Leave this off unless you need it, or your error log will get very
     # big. Acceptable values are 0 or 1.
     debug=0
     # To enable data checksumming, install libberkeleydb-perl and set this option
     # to 1. Then wait until the Packages/Sources files have been refreshed once
     # (and so the database has been built up). You can also nuke them in the
     # cache to trigger the update.  
     # checksum=1
     # Print a 410 (Gone) HTTP message with the specified text when accessed via
     # CGI. Useful to tell users to adapt their sources.list files when the
     # apt-cacher server is being relocated (via apt-get's error messages while
     # running "update")
     #cgi_advise_to_use = Please use http://cacheserver:3142/ as apt-cacher \
     #                    access URL
     #cgi_advise_to_use = Server relocated. To change sources.list, run \
     #                    perl -pe "s,/apt-cacher\??,:3142," \
     #                    -i /etc/apt/sources.list
     # Server mapping - this allows to hide real server names behind virtual paths
     # that appear in the access URL. This method is known from apt-proxy. This is
     # also the only method to use FTP access to the target hosts. The syntax is
     # simple, the part of the beginning to replace, followed by a list of mirror
     # urls, all space separated. Multiple profile are separated by semicolons
     # Note that you need to specify all target servers in the allowed_locations
     # options if you make use of it. Also note that the paths should not overlap
     # each other. FTP access method not supported yet, maybe in the future.
     # path_map = debian ftp ftp.uni-kl.de/pub/linux/debian \
     #            ftp ftp2.de.debian.org/debian ; ubuntu archive.ubuntu.com/ubuntu ; \
     #            security security.debian.org/debian-security \
     #            ftp ftp2.de.debian.org/debian-security
     path_map = ubuntu us.archive.ubuntu.com/ubuntu ; \
                security security.ubuntu.com/ubuntu ; \
                canonical archive.canonical.com/ubuntu
     # Permitted package files - this is a perl regular expression which matches
     # all package-type files (files that are uniquely identified by their
     # filename).  The default is: 
     #package_files_regexp = (?:\.deb|\.rpm|\.dsc|\.tar\.gz|\.diff\.gz|\.udeb|\
     #                       index\.db-.+\.gz|\.jigdo|\.template)$
     # Permitted Index files - this is the perl regular expression which matches
     # all index-type files (files that are uniquely identified by their full path
     # and need to be checked for freshness). 
     # The default is:
     #index_files_regexp = (?:Index|Packages\.gz|Packages\.bz2|Release|\
     #                     Release\.gpg|Sources\.gz|Sources\.bz2|\
     #                     Contents-.+\.gz|pkglist.\.bz2|release|release\..|\
     #                     srclist.*\.bz2|Translation-.+\.bz2)$

Note that, at this point in time, there is a bug that occurs with Translation files. Essentially, it is OK for the client to ask for a translation file that does not exist but when it does so and the file is not found, apt-cacher returns an error code that is incorrect. It doesn't appear to cause any real problems (and there is a fix in the works) but you will notice the errors on your repository cache client machines. You may be tempted to try and fix it by altering the index_files_regexp (in the apt-cacher configuration file) but don't bother. Its a bug in apt-cacher so you won't be able to do so.

We never could understand the reasoning behind this, but, when you install apt-cacher, it is installed deactivated. The startup script is put in the proper place in /etc/init.d and symlinks added for the right run levels. None the less, you still need to activate it manually:

/etc/default/apt-cacher:

     AUTOSTART=1

Once you've done this, you can restart apt-cacher:

     sudo /etc/init.d/apt-cacher restart

The next time you boot the system, it should come up all on its own.

After apt-cacher is successfully set up and running, its time to update all of the repository cache clients so that they will use the local cache instead of the WAN-based repositories. This is done by editing their source list so that it points to the local repository cache. And, the first candidate for this treatment might as well be the machine where the repository cache actually resides so that any packages that it requests will prime the cache.

If the sample sources list, that was shown above, is altered to use the local repository cache, it should now be changed to look something like this:

/etc/apt/sources.list:

     deb http://myrepository:3142/ubuntu jaunty \
         main restricted universe multiverse
     deb http://myrepository:3142/ubuntu jaunty-updates \
         main restricted universe multiverse
     deb http://myrepository:3142/security jaunty-security \
         main restricted universe multiverse
     deb http://myrepository:3142/canonical jaunty partner
     deb-src http://myrepository:3142/ubuntu jaunty-updates \
         main restricted universe multiverse
     deb-src http://myrepository:3142/ubuntu jaunty \
         main restricted universe multiverse
     deb-src http://myrepository:3142/security jaunty-security \
         main restricted universe multiverse
     deb-src http://myrepository:3142/canonical jaunty partner

Go through the configuration files on all of the client machines and update them in a similar fashion. Once that is done, you should be able to apply updates to them, via the local repository cache, in your usual fashion.

If you set up apt-cacher after you've already applied packages to the machine that has the repository cache on it, it is possible that it already has those package files cached in its local repository. If you wish, you can import them to the apt-cacher repository, where they will be available to everyone. One of the ancilliary scripts installed in the /usr/share/apt-cacher directory, that was created when you installed apt-cacher, is apt-cacher-import.pl, which handles this task.

In a misguided attempt at security, the writer of the script forces it to run as the user/group set in /etc/apt-cacher/apt-cacher.conf. Unfortunately, this prevents it from doing anything useful with the local repository (it wants to move all of the packages that it finds from the local repository to the cache), since all of the files in the local repository are owned by whoever installed them (typically root).

Once could change the user/group in /etc/apt-cacher/apt-cacher.conf to root/root temporarily, we suppose, but this defeats the purpose of using a separate user for the cache. If you'd like to keep the separate user/group (www-data, by default) for the cache files, just comment out the code at about line 75 that reads:

     setup_ownership($cfg);

Change it to read:

     # setup_ownership($cfg);

People go way too far overboard with security. If the guy is running as super user, he should be able to do whatever he wants. Peeling his permissions back to something less ain't going to cut it. He's just going to edit your stupid code and do what he wants. Think about that....

Anyway, once you've fixed the code, to import the package files from the system's local repository (/var/cache/apt/archives) to the apt-cacher repository, run:

     sudo /usr/share/apt-cacher/apt-cacher-import.pl /var/cache/apt/archives

The apt-cacher directory (/var/cache/apt-cacher/packages) should now be filled up with all of the packages that were in the apt local repository. At the same time, the local repository should now be empty, since apt-cacher-import.pl moves the packages that it finds to the repository cache.

If you left the directive generate_reports set to 1 in the apt-cacher config file, apt-cacher will generate a report on cache usage every day. You can view the report by pointing your Web browser at the URL:

     http://myrepository:3142/report

Where "myrepository" is the name of the machine that runs apt-cacher.

If you need to regenerate the report at any time other than when it is normally done, run:

     sudo /usr/share/apt-cacher/apt-cacher-report.pl 

Creating A DVD Library

You can create a library of DVDs that can be played by Mythbuntu. This library can be located on the Mythbuntu box itself or placed on a shared video server. See below for the shared video server setup.

To begin with, you should turn your DVDs into ISO images. This can be done with Slysoft's AnyDVD and CloneDVD software. Insert the DVD into a machine that has AnyDVD installed on it. It will remove the copy protection, region encoding and most of the other cruft on the DVD. You can then launch CloneDVD to make a copy of the DVD using the "Clone DVD" feature. Now is the time to delete any tracks you don't want, subtitles, alternate languages, etc. Have CloneDVD write an ISO image to a suitable output directory (you can have it write the ISO image directly to the Mythbuntu box or shared video server, if it is mounted on the cloning machine).

Note that you can use the "Copy DVD Titles" feature to copy only the movie itself or individual TV episodes. This removes the menu and allows the viewer to pick the movie/episode directly (a good thing, considering that the MythTV internal viewer crashes a lot when displaying DVD menus). The output should still be an ISO image (which allows movies like "Bridge on the River Kwai", that have multiple tracks, to be treated as a single file).

If you don't have the cloning program write the output directly to the Mythbuntu box or shared video server, use FTP to copy the ISO image to proper place on the Mythbuntu box or the shared video server. If you don't use the shared video server to hold your movies/episodes, the common location for video files under Mythbuntu is in /var/lib/mythtv/videos.

MythVideo can display directories that are included in the video files tree. If you have DVDs for shows or multiple movies in a series and you'd like to group them together as one logical entry in the MythVideo display, make sub-directories under the top level directory. Give each sub-directory a name that will be recognizable when you browse it with MythVideo and put all of the related ISO images under it. For example:

     /var/lib/mythtv/videos/ANewLeaf.iso
     /var/lib/mythtv/videos/BuffyTheVampireSlayer
     /var/lib/mythtv/videos/BuffyTheVampireSlayer/BVS1-1.iso
     /var/lib/mythtv/videos/BuffyTheVampireSlayer/BVS1-2.iso
     /var/lib/mythtv/videos/BuffyTheVampireSlayer/BVS2-1.iso
          .
          .
          .
     /var/lib/mythtv/videos/TheWindAndTheLion.iso

Compressing DVDs

Once you've created your DVD library and filled up all of the disks with content, you may decide that buying a new hard disk every few weeks isn't such a great idea. Compression may prove to be a more attractive option.

Bear in mind that nobody compresses video files to improve their quality. But, fortunately, most of the content that appears on DVDs is encoded with the MPEG2 algorithm, which uses much more space than the latest encoding algorithms. Re-encoding them with Xvid or H.264, for example, can often lead to a 3 to 1 compression ratio, thereby allowing you to triple your video server's capacity, obviating the need to buy more disks, with little observable degradation in quality.

The mencoder component of the MPlayer package works quite well for compressing DVDs into hiqh-quality AVI files, which can be played by Mythbuntu. You can use the version of MPlayer that comes with your system but it is better to use the latest version and build it yourself. Here are the steps that are necessary to build it.

There are a number of basic tools that are required to build MPlayer. You can install them (or make sure that they are already installed) with apt-get:

     sudo apt-get install build-essential subversion checkinstall yasm git-core

Next, all of the sound and video development libraries must be installed. These can be installed (or checked for installation) with apt-get:

     sudo apt-get install libaa1-dev libasound2-dev libcaca-dev \
       libcdparanoia-dev libdca-dev libdirectfb-dev libggi-target-fbdev \
       libenca-dev libesd0-dev libfontconfig1-dev libfreetype6-dev \
       libfribidi-dev libgif-dev libgl1-mesa-dev libjack-jackd2-dev \
       libmp3lame-dev libmpg123-dev libopenal1 libpulse-dev librtmp-dev \
       libsdl1.2-dev libsvga1-dev libvdpau-dev libxinerama-dev libxv-dev \
       libxvmc-dev libxxf86dga-dev libxxf86vm-dev

The MPlayer Web site has a single tar file that contains many of the useful codecs that make MPlayer work so well. You should download the latest file to your installation directory from:

     http://www.mplayerhq.hu/MPlayer/releases/codecs

If you have a 32-bit system, you should look for the codecs file that is named something like:

     all-20110131.tar.bz2

If you have a 64-bit system, you should look for the codecs file whose name is like:

     essential-amd64-20071007.tar.bz2

In this case, you won't get nearly as many codecs as are in the 32-bit tar file. So sad.

Whichever set of codecs you download, the next step is to extract them and install them where MPlayer can find them:

     cd mplayer-build
     tar xvjf all-20110131.tar.bz2
     su
     mkdir /usr/lib/codecs
     cp all-20110131/* /usr/lib/codecs

Most compression, these days, is done either with the Xvid or x264 (also known as H.264) codecs. If your system does not already have these codecs installed or the versions installed are out of date, you should build them from the latest source and install them separately, before you try to build MPlayer. You should especially make sure that you have the latest source for the x264 codec, if you'll be using it for high quality videos (e.g. those that you won't be watching on an iPod, tablet or laptop with a small screen), since earlier versions of this codec produced some pretty crappy results (in our opinion).

The latest source for building the Xvid codec can be downloaded from http://www.xvid.org/downloads.html. Once you have it, proceed to unpack the source. The last time we looked, the unpacked directory was given an unfortunate choice of names so we like to move the generic "xvidcore" directory to a directory that mirrors the version of the codec that is downloaded:

     cd mplayer-build
     tar -xvjf xvidcore-1.3.2.tar.bz2
     mv xvidcore xvidcore-1.3.2
     cd xvidcore-1.3.2

Now, configure and build the Xvid core, which contains the codec itself:

     cd build/generic
     ./configure --prefix=/usr
     make

To install the Xvid core, do so like this:

     su
     make install

Next, we want to make sure that the system will use the latest Xvid shared library, that you just built and installed. To check if there is an existing Xvid core dynamic library already installed, as well as to check for the newly installed library, do this:

     su
     cd /usr/lib
     ls -l libxvidcore.so.*

If you don't see a symlink to the xvidcore that you installed, that contains only the major version number, you should add it something like this:

     ln -s libxvidcore.so.4.3 libxvidcore.so.4

Before you can build the x264 codec, the newest goat rope in this respect is that the build requires yasm-1.2.0. Too baddie that the most current version of Ubuntu (for example) only includes yasm-1.1.0. Since the assembler probably hasn't changed for the last 20 years, its dubious that this requirement is indeed real but that's the way it is.

Oh, well. Its easiest enough to build. Obtain the source from: http://yasm.tortall.net/Download.html. Switch to the download directory, extract the source, and get ready to configure the build:

     cd yasm-build
     tar -xvzf yasm-1.2.0.tar.gz
     cd yasm-1.2.0

Now, configure and build the assembler:

     ./configure --prefix=/usr
     make

To install the assembler core, do so like this:

     su
     make install

The latest source for building the x264 codec can be downloaded from http://www.videolan.org/developers/x264.html. If you have trouble getting to the FTP directory or you prefer to use HTML, you can look in the snapshots directory, http://download.videolan.org/pub/videolan/x264/snapshots/. Once you have the source, proceed to unpack it:

     cd mplayer-build
     tar -xvjf x264-snapshot-20130906-2245-stable.tar.bz2
     cd x264-snapshot-20130906-2245-stable

Now, configure and build the x264 codec:

     ./configure --prefix=/usr --enable-shared
     make

To install the x264 codec, do so like this:

     su
     make install

Next, we want to make sure that the system will use the latest x264 shared library, that you just built and installed. To check if there is an existing x264 dynamic library already installed, as well as to check for the newly installed library, do this:

     su
     cd /usr/lib
     ls -l libx264.so*

If you don't see a symlink to the libx264 that you installed, that contains only the major version number, you should add it something like this:

     ln -s libx264.so.129 libx264.so

If you anticipate that you'll want live streaming media support in your version of MPlayer (i.e. you won't be just using mencoder to compress files and you may want to look at any of the online media sites), you should get the latest version of Live555, since it is used by MPlayer to handle live streams such as RTP/RTCP, RTSP and SIP. Live streaming protocols are constantly being tuned for performance, so it is always best to have the latest and greatest version.

You can find the latest Live555 source in the public directory on the Live555 Web site:

     http://www.live555.com/liveMedia/public/

The easiest way to get the latest source is to download the live555-latest.tar.gz file. This will be symlinked to the latest version, whatever it is. Once you have the Live555 source, unpack it. We like to move the generic "live" directory to a directory that mirrors the version of the software that is downloaded:

     cd mplayer-build
     tar xvzf live.2011.09.19.tar.gz
     mv live live-2011.09.19
     cd live-2011.09.19

Now, depending on whether you wish to build the 32-bit version, build the makefiles like this:

     ./genMakefiles linux

Or, for the 64-bit version, build the makefiles like this:

     ./genMakefiles linux-64bit

Then make the Live555 server and development files like this:

     make

The Live555 package doesn't include any install procedure. They suggest that you simply copy the entire build tree to /usr/lib. If you think this is a reasonable way to do things, have at it. We prefer to move only the files that are actually necessary (you know, like the way a real install works):

     su
     mkdir /usr/include/liveMedia
     install -m 644 BasicUsageEnvironment/include/.hh /usr/include/liveMedia
     install -m 644 groupsock/include/.hh /usr/include/liveMedia
     install -m 644 groupsock/include/.h /usr/include/liveMedia
     install -m 644 liveMedia/include/.hh /usr/include/liveMedia
     install -m 644 UsageEnvironment/include/*.hh /usr/include/liveMedia
     install -m 644 BasicUsageEnvironment/libBasicUsageEnvironment.a /usr/lib
     install -m 644 groupsock/libgroupsock.a /usr/lib
     install -m 644 liveMedia/libliveMedia.a /usr/lib
     install -m 644 UsageEnvironment/libUsageEnvironment.a /usr/lib
     install mediaServer/live555MediaServer /usr/bin

If you ever need to do a reinstall of a newer version of Live555, you can simply delete all of the files in the "liveMedia" directory and recopy the newer files:

     su
     rm -f /usr/include/liveMedia/
     install -m 644 BasicUsageEnvironment/include/.hh /usr/include/liveMedia
          .
          .
          .
     install mediaServer/live555MediaServer /usr/bin

There is no real version numbering scheme for MPlayer. Rather, you go to the MPlayer site and download the latest stable source from the source code control system. If you go to the MPlayer site (www.mplayerhq.hu) and follow the source download links, you'll eventually end up here:

     http://www.mplayerhq.hu/MPlayer/releases/

Once in this directory, you can download either the checkout or source snapshot (we prefer the source snapshot):

     mplayer-export-snapshot.tar.bz2

After you've downloaded the snapshot, you can unpack it:

     cd mplayer-build
     tar -xvjf mplayer-export-snapshot.tar.bz2

We prefer to then rename the snapshot tar file to the same name as the directory that it unpacks to, just to keep things straight. Then we change to the extracted directory:

     mv mplayer-export-snapshot.tar.bz2 mplayer-export-2013-09-07.tar.bz2
     cd mplayer-export-2013-09-07

The next step is to configure MPlayer so that we can build it. Note that during the configure step, you will also be asked to download the FFmpeg git source. You must allow this by pressing "Enter", when you are asked if you want to do so, otherwise the configure step will not complete. Here is the configure command we use:

     ./configure --prefix=/usr --confdir=/etc/mplayer \
                 --codecsdir=/usr/lib/codecs \
                 --enable-live --extra-cflags="-I /usr/include/liveMedia"

If you didn't build Live555 or keep the system's version of Live555 (or if Live555 is still broken like it used to be), you should use this configure command to disable it:

     ./configure --prefix=/usr --confdir=/etc/mplayer \
                 --codecsdir=/usr/lib/codecs --disable-live

The build is simple:

     make

Likewise, the install is simple:

     su
     make install

#>>>>>>
After
#))))))
make && \
sudo checkinstall -D --install=yes --fstrans=no --pakdir "$HOME/mplayer_build" \

     --pkgname mplayer --backup=no --deldoc=yes --deldesc=yes --delspec=yes --default \
     --pkgversion "2:1.0~svn$(LC_ALL=C svn info 2> /dev/null | \
       grep Revision | cut -d' ' -f2)" && \

make distclean

#((((((

Two pass compression:

     mencoder ISOFiles/Path/movie.iso \
       -nosub -vf pullup,softskip,harddup -nosound \
       -ovc x264 -x264encopts bitrate=2400:subq=1:frameref=1:threads=auto:pass=1 \
       -o /dev/null
     mencoder ISOFiles/Path/movie.iso \
       -nosub -vf pullup,softskip,harddup -oac copy \
       -ovc x264 -x264encopts bitrate=2400:subq=5:8x8dct:frameref=2:bframes=3: \
         b_pyramid=normal:weight_b:partitons=all:me=umh:threads=auto:pass=2 \
       -of avi -o movie.avi

#))))))

Xvid Options - VirtualDub

Filter - deinterlace

     x  interpolate using Yadif
     x  keep top field, interpolate/discard bottom field

Frame Rate

     Source Rate: No Change
     Frame Rate Conversion: Process all frames

Color Depth

     Decompression format: x  4:2:2 TCbCr (YUY2)
     Output format: x  24-bit RGB (888)

Profile (Xvid Home)

     Quantization: MPEG
     Adaptive Quantizer: off
     B-VOPs
       Max Consecutive B-VOPs: 2
       Quantizer ratio: 1.50
       Quantizer offset: 1.00
     Packed bitstream: v

Level

     720 x 576 x 25
     Max frame size (macro blocks): 1620
     Max processing rate (mbps): 40500

Video Buffer Verifier

     Max Buffer Size: 3145728
     Max Bitrate (kbps): 4854.000
     Max Bits over any 1 second interval: 8000000

Aspect Ratio

     Display aspect ratio:  x
       16:9

Encoding Type

     Twopass - 1st pass
       Filename: .\video-pass
       Discard 1st pass:  x
     Twopass - 2nd pass
       I-frame boost (%): 10
       I-frames closer than (frames): 1
         are reduced by (%): 20
       Overflow Control Strength (%): 5
       Max overflow improvement (%): 5
       Max overflow degradation (%): 5
       High bitrate scenes degrade (%): 0
       Low bitrate scenes improve (%): 0
       Target bitrate (kbps): 1200
     Quality Preset: General Purpose

Xvid Options - Mencoder

-vc xvid

For interlaced sources:

     -field-dominance 0 -vf yadif=3,mcedeint=2:1:10,framestep=2

For interlaced sources that start with the bottom frame:

     -field-dominance 1 -vf yadif=3,mcedeint=2:1:10,framestep=2

For telecined sources:

     -vf pullup,softskip,pp=lb

-passlogfile .\video.pass

-xvidencopts

     quant_type=mpeg
     me_quality=6
     noqpel
     nogmc
     notrellis
     nocartoon
     chroma_opt
     hq_ac
     vhq=3
     bvhq=1
     nolumi_mask
     max_bframes=2
     bquant_ratio=150
     bquant_offset=100
     curve_compression_high=0
     curve_compression_low=0
     overflow_control_strength=5
     max_overflow_improvement=5
     max_overflow_degradation=5
     packed
     aspect=16/9  or  autoaspect
     profile=dxnhtntsc
     threads=4
     pass=1
     pass=2
     keyframe_boost=10
     kfthreshold=1
     kfreduction=20
     vbv_bufsize=3145728
     vbv_maxrate=4854000
     bitrate=1200

#<<<<<<

Shared Video Server

You can store videos on any network-attached server that has lots of room, a high-speed network connection and a processor that will be able to keep up with the load of serving packets to the frontends. Typical DVDs average between 4 and 8 gigabytes so you can figure how big the server's disks need to be to hold your collection. For a 2TB drive, you can expect between 200 and 440 DVDs. A nicely-sized video server can be built from four 2TB drives. Even better would be a video server with four 4TB drives, which will let you hold all of your DVDs plus all the episodes of your favorite television shows.

You need to run a recent version of Samba on the server so if you don't have a copy, install it now. Older versions of Samba only support SMBFS, whereas newer versions support CIFS, which is much better. So, although you can mount the older Samba share on Mythbuntu, using smbfs, you may get unexpected I/O errors and other such problems that can cause you grief. Using a newer version of Samba and CIFS should help.

A little farther along in this section, we'll illustrate how to set up a video directory (or high-level directory with mount points for multiple disks) on your video server. The goal is to have a single, top level directory that can be exposed to the outside world as one mount point. You can have multiple directories below it, that will be handled by the MythVideo setup.

In the meantime, let's deal with adding disks to your video server. If you are starting from scratch, or have run out of space and want to add another drive, install the drive in the server and then, if it is 2TB or smaller, format it using fdisk:

     su
     /sbin/fdisk -u /dev/sdc
       n                         (To create a new partition)
       p                         (As a primary partition)
       1                         (Partition 1)
       <cr>                      (To accept the first sector as the start)
       <cr>                      (To accept the last sector as the end)
       w                         (Write the partition table to the disk)

You can check your work with:

     /sbin/fdisk -lu /dev/sdc

You should see something like this:

     Disk /dev/sdc: 2000.4 GB, 2000398934016 bytes
     255 heads, 63 sectors/track, 243201 cylinders, total 3907029168 sectors
     Units = sectors of 1 * 512 = 512 bytes
     Device Boot      Start         End      Blocks   Id  System
  /dev/sdc1              64  3907029167  1953514552   83  Linux

If you have one of the advanced format hard drives (e.g. the newer 1.5 or 2 TB drives from Western Digital or Samsung), you need to pay particular attention to how you create the partitions on the drive so that they are always aligned on a 4K boundary. If you don't do this, performance will suffer heavily.

When creating a single partition, earlier versions of fdisk defaulted to creating the partition starting at sector 63 (they kept the first 63 sectors, from 0-62, for the partiton table and boot information). In the case of advanced format hard drives, this is a very unfortunate choice. Luckily for us, for an advanced format hard drive, later versions of fdisk default to creating the partition starting at sector 2048 (it keeps the first 2047 sectors, from 0-2047, for the partiton table and expanded boot information). But, if you'd like to override the default choice (we don't advise it), you can partition the disk something like this:

     su
     /sbin/fdisk -u /dev/sdc
       n                         (To create a new partition)
       p                         (As a primary partition)
       1                         (Partition 1)
       64                        (Start the partition on a 4K boundary [i.e. 0
                                   mod 8].
       <cr>                      (To accept the last sector as the end)
       w                         (Write the partition table to the disk)

As we said, later versions of fdisk start the first partition at sector 2048, to allow room for the larger boot loaders that are installed by GRUB. If that's the case for your version of fdisk, there is no need to override the starting sector number, just take the default.

You can check your work with:

     /sbin/fdisk -lu /dev/sdc

You should see something like this:

     Disk /dev/sdc: 2000.4 GB, 2000398934016 bytes
     255 heads, 63 sectors/track, 243201 cylinders, total 3907029168 sectors
     Units = sectors of 1 * 512 = 512 bytes
     Device Boot      Start         End      Blocks   Id  System
  /dev/sdc1              64  3907029167  1953514552   83  Linux

If the new disk is bigger than 2TB, you must use parted to format the new disk because it is the only partition editor that is able to support disks larger than 2TB. Additionally, if you have a disk that is larger than 2TB, it is guaranteed to be an advanced format disk, so you must make sure to choose a starting sector for the partition that observes the 4K block boundary, to avoid severe performance hits. Also, to ensure compatibility with boot loaders that require more than 62 sectors following the partition table, it is smart to always start the first partition at sector 2048. Since parted has a parameter that automatically figures out what is the optimal alignment for a partition, based on disk geometry, we can just pick 2048 by default and it will tell us if that number won't work. So, run it like this:

     su
     /sbin/parted -a optimal /dev/sdc
       mklabel gpt
       mkpart primary ext2 2048s 100%
       print
       quit

The print command should show something like this:

     Model: ATA WDC WD40EZRZ-00G (scsi)
     Disk /dev/sdc: 4001GB
     Sector size (logical/physical): 512B/4096B
     Partition Table: gpt
     Number  Start   End     Size    File system  Name     Flags
      1      1049kB  4001GB  4001GB               primary

We used the "s" after "2048" to tell parted that the first number was a starting sector number, not a size in megabytes. We used the "%" after "100" to tell parted that the ending number was 100% of the disk, in other words the last physical sector.

The next step is to make the file system that you wish to use for the partition, with mkfs. Usually for a video server, you should pick an ext3 file system and use mkfs.ext3. Note that for advanced format drives, it is extremely important, regardless of which file system you choose, that the block size chosen for the file system is a multiple of 4096. If not, there will be a severe performance hit. Since we are going to be using this drive to store a few large video files, there is no real penalty to always use 4096-byte blocks so why not just get into the habit of always using them. Thus, for mkfs.ext3, we'll always use:

     /sbin/mkfs.ext3 -b 4096 -j -L / -T news /dev/sdc1

In this example, we labeled the file system "/". You may wish to use some other label, chosen to match what will be on the drive. Be especially careful about this if your system boots with the "LABEL=" parameter in the GRUB configuration and/or mounts partitions using the "LABEL=" parameter in /etc/fstab.

Since the file system will only hold static data, there's no real reason to have fsck check it at boot time. This is especially relevant because for the large file systems that are found on 1 or 2TB disks, checking the file system could take a very, very long time (i.e. hours and hours). If you have several large disks on your video server and all of the file systems happen to get coincidentally checked, booting your system could easily take half a day. You will most certainly want to turn off this dubious feature with:

     /sbin/tune2fs -c 0 -i 0 /dev/sdc1

If you are into housekeeping, you may want to delete the superfluous lost+found directory:

     rm -rf /DVD/sdc/lost+found

To hook the new disk up to your video server, add another subdirectory to the high-level directory that contains the mount points for the multiple disks on the server:

     mkdir /DVD/sdc

In simpler times, it was merely a matter of editing /etc/fstab and adding a line to mount /dev/sdc to the /DVD/sdc mount point. For example:

     /dev/sdc1  /DVD/sdc  ext3  0  0

However, it has now become a case of the inmates truely being in charge of the asylum.

If you are using an HBA to attach disks (which is a common approach for video servers), as well as the ATA ports on the system's motherboard, it can lead to the names assigned to the disks being inconsistent from one boot to the next. This makes it particularly fun when it comes to mounting the disks. And, better yet, there's no way to fix this stupidity. You just have to take what they give you.

Instead of using actual device names, the fstab needs to mount the disks by UUID. The UUID in question is assigned when the partitions are built so you need to obtain the UUID after the disk is partitioned and formatted. Assuming that your video server has more than one or two disks (it is a video server, after all), you can figure out what the UUIDs of all of the disks are with:

     su
     /sbin/blkid /dev/sdxx1
     /sbin/blkid /dev/sdxx2
     /sbin/blkid /dev/sdxx3
          .
          .
          .

But, before you do this, make sure that the disk you are asking the UUID for is really the disk that you mean to mount. You should copy down the physical serial number from the disk's external label, when you install the disk, and then look at the disk information for the device that you suspect is the disk in question. If the serial number you copied down is the same, you can proceed. Get the disk info this way:

     su
     /usr/bin/udisks --show-info /dev/sdxx

And, speaking of the inmates running the asylum, if your video server is running under CentOS 7.x, the udisks command has been removed and you must now use the following command, provided by the udisks2 package:

     su
     /usr/bin/udisksctl info -b /dev/sdxx

However, in their infinite wisdom, the smartest people in the world have decided to leave out such identifying information as the device serial numbers from the output produced by udisksctl, so you may have to resort to:

     su
     /usr/sbin/smartcl -a /dev/sdxx

It may be of assistance to you to note that the disks plugged into HBA ports are assigned disk names first (e.g. /dev/sda, /dev/sdb, etc.), before the disks plugged into the motherboard ATA ports. Also, it appears that for most HBAs (which implement SAS/SATA ports with a 4-port controller chip), the disk names are assigned in ascending order in groups of four, to the disks plugged into Port 3, Port 2, Port 1, Port 0, then Port 7, Port 6, Port 5, and Port 4, etc. So, Port 3 gets the name /dev/sda, Port 2 gets /dev/sdb, ..., Port 7 gets /dev/sde, Port 6 gets /dev/sdf, etc. But, only if there is something actually plugged into the port.

Now, we create a shared directory, which is then exported by Samba so that it can be mounted by any system wishing to see the videos. In this example we will call the directory /dvdlib:

     su
     mkdir /dvdlib
     mkdir /dvdlib/posters
     mkdir /dvdlib/DVD
     mkdir /dvdlib/DVD/Movies
     mkdir /dvdlib/mnt
     chgrp joeblow /dvdlib/
     chmod ug=rwx,o=rx /dvdlib/
     chgrp joeblow /dvdlib/DVD/
     chmod ug=rwx,o=rx /dvdlib/DVD/

Continuing with this example, the /dvdlib/DVD/Movies subdirectory is actually on the boot disk (third partition) and is used to hold any videos (i.e. movies) that are stored on the boot disk itself. Similarly, the posters directory is used to hold poster artwork for the movies and TV shows served by the video server.

The partitions on the boot disk, (either plugged into a motherboard ATA port or connected to a RAID controller), are mounted in the file system in the usual spots (i.e. "/" and "/boot"). But, for all of the other disks plugged into the motherboard, as well as any disks on an HBA, mount points must be created somewhere in the file system for them. Since they must be accessible by any system that wishes to access the videos, they must be exported as part of the /dvdlib tree so we'll hang them off the /dvdlib/mnt subdirectory. We'll give them names that indicate their port numbers:

     su
     mkdir /dvdlib/mnt/hba0p0
     mkdir /dvdlib/mnt/hba0p1
     mkdir /dvdlib/mnt/hba0p2
     mkdir /dvdlib/mnt/hba0p3
     mkdir /dvdlib/mnt/hba0p4

Once you have the UUIDs for all of the disks/partitions that you want to mount, you can update /etc/fstab, which should look something like this:

     #
     # /etc/fstab
     #
     # Originally updated by J. Blow on Fri Jul 4 2014, 11:22:03
     # Updated for this install by J. Blow on Tue Nov 3 2015, 08:30:45
     #
     # Accessible filesystems, by reference, are maintained under '/dev/disk'
     # See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
     #
     # The first SATA disk, on the motherboard.  This is the boot disk.
     UUID=fdbc0fb2-ff6a-f1c1-bbcc-8a0287b2ccc3 /               ext3 defaults 1 1
     UUID=820dc26e-f1fe-fcfc-b9ae-2fd222b8a922 /boot           ext3 defaults 1 2
     UUID=f0ec0fcc-cc3a-f038-a03d-9ac7dbc8d803 swap            swap defaults 0 0
     # The SAS/SATA disks, on HBA0 (in port order).
     UUID=29c02f99-9967-f730-affe-c00bff997c71 /dvdlib/mnt/hba0p0 ext3 defaults 0 2
     UUID=39f6c03c-ec70-f7b8-88ff-ef92e1ac20a0 /dvdlib/mnt/hba0p1 ext3 defaults 0 2
     UUID=2d0f1f77-2db9-f32c-aecc-b2dcba6aa1cf /dvdlib/mnt/hba0p2 ext3 defaults 0 2
     UUID=cbacbffd-2d08-fd3e-8f02-7b7f08cbe2da /dvdlib/mnt/hba0p3 ext3 defaults 0 2
     UUID=c2eb2097-09c2-fa02-926d-a222cbdf0c1d /dvdlib/mnt/hba0p4 ext3 defaults 0 2
     # Temporary file systems, system file systems, etc.
     tmpfs                   /dev/shm                tmpfs   defaults        0 0
     devpts                  /dev/pts                devpts  gid=5,mode=620  0 0
     sysfs                   /sys                    sysfs   defaults        0 0
     proc                    /proc                   proc    defaults        0 0

If you add a new disk or replace an existing disk with a different one, you will need to go through all of the steps described above to find the UUID of the disk and update /etc/fstab with it.

Once fstab is updated, you can either reboot the system or, we prefer, try auto-mounting everything first (this way, if fstab is broken, your system will still be up and running and you'll have a chance to fix things):

     su
     mount -a -v

After all the file systems are mounted, you should give them any non-root permissions that you want them to have. Doing this before they are mounted will only modify the permissions of the directory entries in /mnt which are overridden when the file systems are mounted:

     su
     chgrp joeblow /dvdlib/mnt/hba
     chmod ug=rwx,o=rx /dvdlib/mnt/hba

The top level index of the videos taxonomy is now created on the video server using symlinks. All of the symlinks must be soft links that are relative to the /dvdlib subdirectory so that they will work on the systems that mount the exported subtree. Here is an example of a suggested taxonomy:

     su
     cd /dvdlib/DVD
     ln -s ../mnt/hba0p0 Action
     ln -s ../mnt/hba0p4/Cartoons Cartoons
     ln -s ../mnt/hba0p4/Comedy Comedy
     ln -s ../mnt/hba0p4/Cooking Cooking
     ln -s ../mnt/hba0p2/"Cops and Robbers" "Cops and Robbers"
     ln -s ../mnt/hba0p2/Detectives Detectives
     ln -s ../mnt/hba0p4/Documentaries Documentaries
     ln -s ../mnt/hba0p1/Drama Drama
     ln -s ../mnt/hba0p3/Lawyers Lawyers
     ln -s ../mnt/hba0p3/Medicine Medicine
     ln -s ../mnt/hba0p4/Music Music
     ln -s ../mnt/hba0p1/Politics Politics
     ln -s ../mnt/hba0p1/"Science Fiction" "Science Fiction"
     ln -s ../mnt/hba0p4/Transportation Transportation

You will note that some index entries (e.g. Action) point directly to a full disk. All of the subdirectories and files on this disk will appear under the single heading (i.e. Action). Other index entries (e.g. Comedy and Cooking) point to a specific subtree on a single disk. Some of the videos on that disk are in the Comedy top level index and some are in the Cooking top level index. You are pretty much free to arrange the videos directories as you like. Just make sure that all of the symlinks are located at the top of the tree.

Creating the top level index in this manner allows it to be maintained from a single location on the video server itself. You do not have to change any links on the client machines.

Note that the appropriate directory structure on each of the individual file systems should be set up according to the index found in the Myth videometadata table.

Now is the time to copy your video files to your video storage disk(s).

Also, you'll recall that, earlier in this section, we set up a posters directory to hold all of the DVD posters or covers that are downloaded from the Internet or made up by you. This is necessary because the only copy of the database will point to this directory, so it must be accessible to all of the Mythbuntu machines that will access the DVD library. If you've already begin collecting posters, now is the time to copy them to the posters directory.

Next, we'll adjust the Samba config file to allow the high-level video directory to be mounted by guests (i.e. Mythbuntu clients).

     /etc/samba/smb.conf:
     Basically, all you have to do is add a share point for the DVD library:
      [dvdlib]
         comment = DVD Library
         path = /dvdlib
         browseable = yes
         read only = yes
         guest ok = yes
     You do not need to monkey with any of the other security settings in the
     Samba config file.
     Restart Samba to get it to export the new share.

Then, proceed to the steps outlined in Mounting Shares Under Mythbuntu to set up shared video directories under Mythbuntu.

Finally, if you need to expand a disk on you video server, you should proceed, as described in the Increasing Storage Capacity section, to partition, format, and populate the new disk via direct file copy or via lftp. In all probability, you should follow the steps that detail how to set up an Ext3 partition. That section also has tips on how to copy the video onto the new system.

Mounting Shares Under Mythbuntu

To begin with, make sure that the appropriate Samba components are installed on the system. Normally, only the Samba server is installed but to mount CIFS or SMBFS share points additional packages are required. You may wish to include the utility commands installed with the Samba client package (smbclient) to aid you diagnosing problems, etc. However, all that is really necessary (on later systems, at least) is either the smbfs package or the cifs-utils package. Searching for "samba" and or "cifs" in the package manager should yield a list. Be sure to install the same version of the client and utilities as the version of Samba that is already installed on your system. If you are brave and you don't want to use the package manager to check what you're installing, you can try:

     sudo apt-get install smbclient cifs-utils

Note that the smbfs package is supposed to be superseded by the cifs-utils package but that some people experience problems with CIFS. If you are one of them, you may have to revert to SMBFS. To do this, install the smbfs package, which requires cifs-utils as one of its prerequisites:

     sudo apt-get install smbfs

Once the appropriate packages are installed, you should be able to do:

     man mount.cifs

and optionally:

     man mount.smbfs

Share points need to be mounted in the Mythbuntu file system somewhere. Usually, the top-level directory /mnt is used for this. We like to keep things organized so we create a second-level directory named after the machine we're mounting from and a third-level directory named after the share name. So, for example:

     sudo mkdir /mnt/videoserv
     sudo mkdir /mnt/videoserv/DVD

You can mount the shared video directory on a one-time-basis (good for testing) or permanently. To do it on a one time basis, use:

     sudo mount -t cifs //192.168.1.10/DVD /mnt/videoserv/DVD --verbose -o
       ro,guest,user=guest,sec=none,iocharset=utf8

If you have problems mounting shares from an older version of Samba, you may be able to change "cifs" to "smbfs" (after you install smbfs, per the instructions above) but you should really upgrade your older Samba to a later version. Under the latest kernels, "smbfs" may not be supported.

To mount the share permanently, edit /etc/fstab with your favorite editor and add a line to mount the share:

     sudo emacs /etc/fstab
     /etc/fstab
     #Samba shares
     //192.168.1.10/DVD  /mnt/videoserv/DVD  cifs  \
         ro,noauto,guest,user=guest,sec=none,iocharset=utf8  0  0

You should test that you can mount the share now with:

     sudo mount /mnt/videoserv/DVD

If the mount does not succeed, you can usually find out what happened by doing:

     sudo dmesg | tail

Some other options that you may wish to consider for your fstab entry are:

     password=itsasecret,noserverinfo,file_mode=0555,dir_mode=0555

These specify the password for the user on the video server (if any), that the video server's inode numbers should not be used on the local system (the default, but it never hurts to specify the defaults), and the mode for files and directories (if the video server doesn't support the CIFS Unix extensions).

Once you are sure that the mount will work, edit /etc/rc.local to automatically mount the share, after everything is up and running (the mount cannot be done directly in fstab, since Samba will not be up and running when the mounts are done -- besides, this allows for the video server to be down and not stop the system from booting):

     sudo emacs /etc/rc.local
     /etc/rc.local

.

.

# Bring up the Samba shares, once everything is up and running. #
# Note that the same fracking geniuses who screwed up the way system tasks # are started apparently had a crack at rc.local too. It no longer waits # until all tasks have started before it runs. So, we must force an # artificial delay to allow the network to come up before we try the Samba # mounts.
sleep 10
mount /mnt/videoserv/DVD

         .
         .
         .

The share will come up mounted when next you reboot.

Note that, for MythVideo to work, all of the video files must be readable as part of the local filesystem. This means if you have a separate frontends and backends, they must all mount the directories themselves. Consequently, you must perform this step for each of your frontends/backends.

Also, since the full path names to all the videos are stored in the shared database, you must mount the video directories under exactly the same path on each of the systems that will view them. This restriction applies, even though you get to supply the list of directories (below, via the "Directories that hold videos" field). Perhaps the path names stored in the database should have been relative to the path names given in the "Directories that hold videos" field but, so far, this is not the case.

MythVideo Setup

From the MythTV frontend, choose Utilities/Setup from the main menu, then Setup, Media Settings, Videos Settings, and General Settings from the menu tree. Navigate to the first field named "Directories that hold videos". Here, you can enter your video directories as a colon separated list. You would typically use the directories that you mounted (see above) or a local directory. For example:

     /mnt/videoserv/DVD/sda:/mnt/videoserv/DVD/sdb

You should change the field named "Directory that holds movie posters" to point to the shared posters directory that you created on the video server. For example:

     /mnt/videoserv/DVD/posters

Under the field named "Default view", I prefer to pick "Listings".

On the second page, choose all of the items in the list. You may set "Video tree remembers last selected position" item to whatever your preference is. There is nothing that needs setting on pages 3 thru 7 but you must navigate through them all to save your choices.

Exit the setup screens, all the way back to top-level "Utilities/Setup" screen and then pick "Video Manager". You should see a list of all of the videos that are available in the directories that you set, above.

Scroll down to the first video and hit the memu button on your remote or the "M" key on the keyboard. A menu should pop up. Pick the "Manually Enter Video #" choice. A box will pop up that says, "Enter IMDB #".

Note that under Mythbuntu 9.04 (MythTV 0.21), the manual entering of IMDB numbers is broken because somebody made a typo when naming the IMDB menu. If it is broken, you will see the "Enter IMDB #" menu as soon as you fire up the Video Manager and you will not be able to enter IMDB numbers at any point. The fix is to run the following command from the command line, as root:

     find /usr/share/mythtv/themes/ -name "video-ui.xml" -print |
       xargs sed -i 's/enterimdb/entertmdb/g'

Or, if you didn't change the root password and are still using the sudo method to do all of your maintenance, try this:

     find /usr/share/mythtv/themes/ -name "video-ui.xml" -print |
       xargs sudo sed -i 's/enterimdb/entertmdb/g'

Note that there won't be any fixes for this problem for MythTV version 0.21, since the geeks have all moved on to yet another way of doing things that's way more better (Yeah, like we haven't heard that before) and they aren't interested in fixing the old stuff.

You will need to surf over to www.imdb.com on the Internet, using another computer and the Web browser. Look up the name of the movie in the search box and pick the correct movie from the search list (you're usually looking for the item that says "Media from ..."). The link to the movie will include a number that looks something like "tt0073906". You want the significant digits of that number. Enter the number (e.g. 73906) into the pop up box that says, "Enter IMDB #".

MythVideo will look up the appropriate movie poster for the movie, cache it in the directory chosen above and fill in the database with all of the relevant information about the movie (e.g. director, year, run time) from IMDB. When you browse through the movies later on, you'll see all of this info.

That's all there is to it. Set up all of the movies that you've loaded into the DVD repository in the same manner.

Finally, just in case you want to know more about MythVideo, you can find a comprehensive HowTo at: http://www.mythtv.org/wiki/index.php/MythVideo.

Adding Your Own MythVideo Metadata

Unfortunately, the Myth UI for the video metadata leaves a lot to be desired. You can only edit some of the data, not all of it. If you can find your movie in IMDB, most of the information is filled in automatically. However, if you can't find your movie in IMDB or its information is wrong or missing, you can't change it.

Not to fear. We'll hack the MySQL database directly. What fun. Begin by firming up the MySQL command processor:

     mysql -uroot -p mythconverg

The first thing to do is list the movie you're trying to update. You can try something like this:

     select * from videometadata where title like 'A%';

The above would show all movies beginning with the letter 'A', for example.

Once you find the movie you want to update, you can try the following:

     update videometadata set director='Joe Blow' where intid=nn;
     update videometadata set year=2009 where intid=nn;
     update videometadata set length=105 where intid=nn;
     update videometadata set coverfile='/mnt/videoserv/DVD/posters/MyPoster.jpg'
       where intid=nn;

The first example would be used to set the director's name. You can use multiple names, separated by commas but don't go nuts. The second example would set the movie release year to 2009. The third example would set the movie run time to 105 minutes. In all of the examples, nn is the actual internal ID that you determined by selecting the movie you're interested in (above).

And, the fourth example sets the cover file (which is displayed when you surf through the list of movies) to something of your choosing.

If IMDB doesn't have a cover for your movie (or you hate their choice), you can scan the cover of your legally-purchased copy of the DVD (you do have one of those, don't you) and turn it into a cover that MythVideo can use. Crop the scanned image so that it is roughly 3" wide and 4.5" high. Make sure the dots per inch are set to 72. Save it in medium resolution as a JPEG. The place to save it is the posters directory on your video server. Once you've done that, aim the metadata at the poster (still at the MySQL command prompt):

     update videometadata set coverfile='/mnt/videoserv/DVD/posters/BVSSexy.jpg'
       where intid=nn;

Here, we're aiming the cover file at our own version of the Buffy The Vampire Slayer cover, with the sexy (not for general consumption) image of S.M.G. and A.H. You can't get that off of IMDB.

If you want to hack other columns in the videometadata table, this gets you a list of all of the columns:

     show columns for videometadata;

You might want to look at what's already there before you start blasting. Oh, yeah. Before we start, let's (as Norm would say) talk about shop safety. Always wear safety glasses and ear protection, when blasting. And, always make a backup of the database beforehand. Otherwise, you may be looking at a blank screen where all you back episodes of Lost used to be. In other words, they will be truly lost. Whaaa!

Automatically Updating MythVideo Metadata

You can automatically update your MythVideo Metadata using the Perl script mythvideo-scanner.pl, which can be scheduled to run automatically, at regular intervals, by cron. This script makes a good faith effort to figure out all of the relevant Web sites that may have information associated with each of the video files in the MythVideo storage tree, and download it. The information is blended into a consistent metadata record which is written to the database. Information about actors is also added.

This script may be run on any machine that has a network connection to the master backend. It does not have to be run on the master backend itself. We prefer to run it on the video server instead of the master backend, since this allows us to mount the posters, artwork and/or banners directory (along with the MythVideo storage tree) as read-only on all of the Mythbuntu boxes that access the video server, thereby minimizing the chance of accidents.

Meanwhile, the metadata updating is done directly on the video server, where the posters, artwork and/or banners directories can be accessed directly, thereby allowing new posters, artwork, etc. to be downloaded and stored. This also offloads the MythVideo work to the video server, thus freeing the master backend to do other, recording-related work unimpeded.

Begin by downloading the mythvideo-scanner install file from:

     http://code.google.com/p/mythvideo-scanner/

Uncompress the install file:

     cd /rpm/mythvideo-scanner
     tar xzf mythvideo-scanner.3.1.tar.gz

To install the mythvideo-scanner, you can try the installing it via the makefile, like this:

     cd mythvideo-scanner
     make upgrade
     su
     make PREFIX=/usr install

We prefer putting it in our own directory, by hand, like this:

     su
     mkdir /usr/local/mythvideo
     mkdir /usr/local/mythvideo/modules
     mkdir /usr/local/mythvideo/grabbers
     cp modules/ /usr/local/mythvideo/modules/
     chmod u=rw,go=r /usr/local/mythvideo/modules/
     cp grabbers/ /usr/local/mythvideo/grabbers/
     chmod u=rw,go=r /usr/local/mythvideo/grabbers/
     cp .pl /usr/local/mythvideo
     chmod u=rwx,go=rx /usr/local/mythvideo/.pl

This allows code in the Perl scripts to set the current directory into the include directory list and always find the modules and grabbers, regardless of which version of Mythbuntu (or not) that you are using.

Make sure that you have all of the prerequisite Perl modules installed from CPAN. We have found (on CentOS) that all of the necessary modules were already installed except HTML::TreeBuilder and Text::Levenshtein. On Mythbuntu, many people have reported that Text::Levenshtein is the only module that needs to be installed. The full list of required modules is:

     File::Spec;
     Getopt::Long;
     HTML::Parser;
     HTML::TreeBuilder;
     HTML::Entities;
     LWP::Simple;
     LWP::UserAgent;
     Text::Levenshtein qw(distance);

You can install them like this, for example:

     su
     perl -MCPAN -e shell
     install HTML::TreeBuilder
     install Text::Levenshtein
     quit

If you won't be running mythvideo-scanner on the master backend or one of your Mythbuntu frontends, get a copy of the MythTV MySQL configuration text file from one of your Mythbuntu boxes. It is preferrable to use mysql.txt from a frontend, since it is a little closer to what we want to use for a system that will access the MythTV database remotely. We like to put it in the /etc/mythtv directory but you can do a find to see if it is already installed elsewhere. Here is a sample of a typical mysql.txt file:

/etc/mythtv/mysql.txt:

     # Database server host name (master backend).
     DBHostName=192.168.1.99
     # By default, Myth tries to ping the DB host to see if it exists.
     # If your DB host or network doesn't accept pings, set this to "no".
     #DBHostPing=no
     # Database connection information.
     DBUserName=mythtv
     DBName=mythconverg
     DBType=QMYSQL3
     DBPassword=123abc987

You might want to set the ownership and permissions of this file to root, read/write, so that it is free from prying eyes (it does contain your database password, after all), like this:

     su
     chown root:root /etc/mythtv/mysql.txt
     chmod u=rw,go= /etc/mythtv/mysql.txt

>>>>>>
add the host's info to the mythconverg prefs table. <<<<<<

You can now try running the mythvideo-scanner like this:

     /usr/local/mythvideo/mythvideo-scanner.pl --dryrun --status --verbose

If run gets an error like this:

     -bash: /usr/local/mythvideo/mythvideo-scanner.pl: /usr/bin/perl^M: bad
       interpreter: No such file or directory

You need to remove all of the carriage returns off the ends of the lines. This is easily accomplished with these commands:

     su
     cd /usr/local/mythvideo
     find . -type f -exec dos2unix -o \{\} \;

>>>>>>
You need to be superuser to run, if you removed permissions from the mysql.txt file

     /usr/local/mythvideo/mythvideo-scanner.pl --dryrun --verbose

<<<<<<

Downloading Podcasts

Audio programs (such as podcasts or streams) can be automatically captured and added to the MythTV music directory, where they can be played at your convenience. For podcasts, we can use a program called gPodder to periodically fetch the latest podcast of your favorite programs.

We'll begin by installing gPodder so that podcasts can be periodically captured. Information about how to download and install gPodder is found on the download page at:

     http://gpodder.org/downloads.html

However, downloading is not strictly necessary. For the latest versions of Mythbuntu, you can simply install gPodder in the usual manner with the package manager:

     sudo apt-get install gpodder

Even for earlier versions of Mythbuntu, the easiest way to install gPodder was to use the gPodder PPA from Launchpad:

     https://launchpad.net/~thp/+archive/gpodder

To install the PPA, proceed to the PPA's overview page in Launchpad and find and click the link that reads "Technical details about this PPA". Select your version of Ubuntu from the "Display sources.list entries for" dropdown list. Copy the lines that appear in the text box that look something like this:

     deb http://ppa.launchpad.net/thp/gpodder/ubuntu jaunty main
     deb-src http://ppa.launchpad.net/thp/gpodder/ubuntu jaunty main

Fire up your favorite text editor and edit the apt sources.list file. Add the lines that you copied to the bottom of the file:

/etc/apt/sources.list:

.

       .

deb http://ppa.launchpad.net/thp/gpodder/ubuntu jaunty main deb-src http://ppa.launchpad.net/thp/gpodder/ubuntu jaunty main

From the PPA's page, you'll find a signing key that looks something like:

     1024R/89617F48 (What is this?) 

Copy the portion after the slash and add it as one of the keys that apt can use to verify downloads:

     sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 89617F48

Ask apt to update the list of packages in the system's archive:

     sudo apt-get update

Now, you can install gPodder from the PPA:

     sudo apt-get install gpodder

Before you begin using gPodder, you may want to change the gPodder download folder to something that you prefer. For some versions of gPodder, you cannot change the download folder using gPodder's GUI (see bug 566), but you can always do so manually with the steps shown here.

Begin by shutting down gPodder, if it is running. Then, open the file ~/.config/gpodder/gpodder.conf (under the logged-in userid) with a text editor. Search for the line starting with "download_dir" and change the value to the directory you want:

~/.config/gpodder/gpodder.conf:

.

       .

download_dir = /Podcasts

Fire up gPodder from the GUI and add all of the feeds that you want to download. You can do this using URLs or via the gPodder search facilities. You may want to set the episode retention time for each feed, as you add them, or you can set the overall episode retention time from the Preferences menu. The default retention time is 7 days.

>>>>>>
Once you've installed gPodder and subscribed to all of the podcasts that you are interested in, you can automate the downloading of podcasts with this simple script (its more documentation than commands). Schedule it at regular intervals in your crontab:

     #!/bin/sh
     #
     # Shell script to update and download all podcasts that are subscribed to by
     # gPodder.
     #
     # This script should be scheduled out of crontab to run at regular intervals
     # sometime after the podcasts are scheduled to be available.  It will invoke
     # gPodder to update the list of podcasts which are currently available and
     # then invoke it again to download them.
     #
     # The reason for scheduling it at regular intervals is to spread out the
     # downloads over time so as to not overload the system at one particular
     # time.  Also, the podcasts are retrieved, throughout the day, as they
     # become available.  Note that the userid used to run this script should be
     # the one that is to be used to capture podcasts to the podcast directory.
     # For example:
     #
     #      30 1,8,10,14,16,19 * * *  mythuser  /my/scripts/PodcastUpdate
     #
     #
     # Where things are stored.
     #
     PodcastDir=/Podcasts
     ##############################################################################
     #
     # Update the podcast availability list and download the ones that are no
     # available.
     #
     /usr/bin/gpo update
     /usr/bin/gpo download

Older versions of gPodder maintained playlists for each podcast feed, if the "create_m3u_playlists" option was set to "True". With the later versions of gPodder, this feature has been dropped. <<<<<<

Note that the command line interface to gPodder doesn't do any episode cleanup. Consequently, you'll need to visit the GUI periodically to mark all of the episodes that have been downloaded as played and expire them according to the retention time you have chosen for each feed.

Capturing Audio Streams

Even if a podcast isn't available, an MP3 stream (or shoutcast) of the audio program may be available from one or more Internet radio sources. In that case, we can use a program called streamripper to capture the stream and turn it into the equivalent of a podcast. Alternately, for the popular Adobe Flash streams, we can use mplayer, the latest ffmpeg, and lame to capture them and turn them into an MP3 as well. A third option may be to copy the MP3 file directly from a fixed URL, where it is placed every day, at the same time.

Installing streamripper is even easier than installing gPodder (above), since it is available via the standard Ubuntu distribution mechanism:

     sudo apt-get install streamripper

To use streamripper, you need to find the actual MP3 stream source for the program that you wish to rip. You can often find a link to the source from the Web page of the broadcaster. A good starting point is the Public Radio Fan Web site, which lists many public radio broadcasters from around the world who broadcast on the Internet:

     http://www.publicradiofan.com/

To use the Web site, begin by choosing the "Set preferences" link from the lefthand menu of the home page. Choose "Time display preferences" and set your time zone. Then, choose "Audio format preferences". Deselect all types of streams except MP3 (streamripper only works with MP3 streams).

You can look for programs by choosing the "Schedule grid" link from the lefthand menu of the home page. Once on the schedule grid page, you can select what is displayed by clicking the "Change time interval and other grid options" link.

Peruse the listings to find the programs you’re interested in recording. Right click on the lightning-bolt icon (the Winamp logo) next to the program's source (you should see a URL ending with ".m3u" or ".pls") and choose “Save Link As...” to save the link to a temporary local file.

Open up the saved file and take a look at it. If it is a ".m3u" file, it will look something like this (example from CBC Radio 3):

     http://shoutcast1.cbcradio3.com/

If it is a ".pls" file, it will look something like this (example from CJRT Radio, JAZZ FM 91):

     [playlist]
     NumberOfEntries=1
     Title1=JAZZ.FM91 - Canada's Premier Jazz Station
     File1=http://streamerepsilon.jazz.fm:8000

Upon inspection, its pretty obvious what the URL to use for the source's streamcast is. Using the URL, you can now make up a streamripper command to capture the stream. Try this:

     streamripper http://shoutcast1.cbcradio3.com/ -a test.mp3 -s -l 120

You should get an mp3 file that contains a couple of minutes captured from the stream that you've chosen.

Quite a number of radio stations stream their broadcasts in real time using the Flash player format (flv) from Adobe. If you have a later version of Mythbuntu (e.g. 10.04), you can capture these streams with mplayer and the ffmpeg codec library libavformat. Note, however, that this doesn't work on earlier versions of Mythbuntu (e.g. 9.04) because the libavformat library doesn't support the "10" or "a" level of flv streams. If you see messages that look like this when you run mplayer, you're out of luck:

     libavformat file format detected.
     Stream not seekable!
     [flv @ 0x883ec08]Unsupported audio codec (a)

On earlier versions of Mythbuntu (e.g. 9.04), mplayer uses a built-in version of ffmpeg which cannot be replaced. Consequently, even if you upgrade ffmpeg or rebuild it from source, you won't be able to capture such streams because mplayer will still be using the old ffmpeg. On the 9.10 version of Mythbuntu, mplayer may just work or you may be able to upgrade the system's ffmpeg codec libraries such that mplayer will be able to capture the stream. On Mythbuntu 10.04 and up, it should just work.

There are notes at:

     http://ubuntuforums.org/showthread.php?t=1117283

Which describe how to upgrade your ffmpeg with the unstripped or extra libraries. It also points out how to compile ffmpeg, if you'd like to take that route, instead. This may come in handy the next time Adobe upgrades the Flash stream to level 11 or 12 or whatever. The whole ffmpeg story is at:

     http://www.ffmpeg.org/

Once you have a working version of mplayer, the basic method for capturing a Flash stream is simple. You run mplayer like this:

     mplayer http://123.234.2.3:80/WCMFFMAAC -ao pcm:file=/tmp/mpstream.wav \
       -vc dummy -vo null

This will create a wav file that lasts for as long as you let mplayer run.

The next step is to use lame to convert the wav file that is captured by mplayer into an MP3 file. This can be loaded into Myth or copied onto your portable MP3 player.

Normally, lame isn't installed on Mythbuntu so the first thing is to install it. Do this:

     sudo apt-get install lame

Answer the prompts and you're in business. That was easy.

The basic method for converting the wav file to MP3 is also pretty simple. You run lame like this:

     lame -m s /tmp/mpstream.wav -o /tmp/mpstream.mp3

After lame completes, you should have an MP3 file that can be played with any MP3 player (like vlc). If you wish, you can delete the wav file:

     rm -f /tmp/mpstream.wav

There is one more step that you may wish to take, although it isn't at all necessary. It is more like icing on the cake.

You can use the program id3v2 to add ID3, version 2 tags to the newly-created MP3 file so that any MP3 player that tries to play it will know what its all about. If you wish to take this step, you first need to install id3v2, since it isn't normally installed on Mythbuntu:

     sudo apt-get install id3v2

Once the install completes, you can use id3v2 to tag the MP3 file like this:

     id3v2 -a WCMF -A "WCMF Stream from 10 Aug 27 at 09:00" -g 78 \
       -t "WCMF Stream from 10 Aug 27 at 09:00" -T 1/1 -y 2010

You can just set the genre number to 255 (Podcast), if you don't actually care about the genre, or you list all of the genre numbers that you can use like this:

     id3v2 -L

Many of the available Flash audio streams are now supplied by a company called StreamTheWorld. This company is responsible for all of the online feeds of the various CBS Radio stations throughout the United States, for example. The feed URL used by StreamTheWorld is dynamic so that you cannot simply grab it once and use it forever. Instead, you need to go through the lookup process provided by their Web servers every time you which to capture one of the streams fed by StreamTheWorld.

Dan McGee has written a script that makes it a lot easier to play StreamTheWorld radio streams from the command line. You can find it at this URL:

     http://www.toofishes.net/blog/streamtheworld-streams-command-line/

We'll alter this script so that, instead of playing the stream directly, it simply outputs the dynamic URL where the stream can be found. This can then be used in a shell script to run mplayer and capture an hour or two of the stream at a time determined by a crontab entry. Here's the modified script:

streamtheworld.py:

     #!/usr/bin/env python
     from random import choice
     import os
     import sys
     import urllib2
     import xml.dom.minidom as minidom
     def validate_callsign(cs):
       '''
       Normal callsign format is 'WWWWFFAAA', where 'WWWW' is the radio station
       callsign, 'FF' is either 'AM' or 'FM', and 'AAA' is always 'AAC'.
       For this function, we expect the 'WWWWFF' part as input.
       '''
       if not cs or not isinstance(cs, str):
         raise ValueError('callsign \'%s\' is not a string.' % cs)
       if len(cs) < 6:
         raise ValueError('callsign \'%s\' is too short.' % cs)
       if not cs.endswith('AAC'):
         cs = cs + 'AAC'
       band = cs[-5:-3]
       if band != 'AM' and band != 'FM':
         raise ValueError('callsign \'%s\' is missing \'FM\' or \'AM\'.' % cs)
       return cs
     def make_request(callsign):
       host = 'playerservices.streamtheworld.com'
       req = urllib2.Request(
         'http://%s/api/livestream?version=1.2&mount=%s&lang=en' %
         (host, callsign))
       req.add_header('User-Agent', 'Mozilla/5.0')
       return req
     ## Example XML document we are parsing follows, as the minidom code is so
     ## beautiful to follow
     #
     #<?xml version="1.0" encoding="UTF-8" standalone="yes"?>        
     #<live_stream_config version="1" \
     #    xmlns="http://provisioning.streamtheworld.com/player/livestream-1.2">
     #  <mountpoints>
     #    <mountpoint>
     #      <status>
     #        <status-code>200</status-code>
     #        <status-message>OK</status-message>
     #      </status>
     #      <servers>
     #        <server sid="5203">
     #          <ip>77.67.109.167</ip>
     #          <ports>
     #            <port>80</port>
     #            <port>443</port>
     #            <port>3690</port>
     #          </ports>
     #        </server>
     #        <!-- multiple server elements usually present -->
     #      </servers>
     #      <mount>WXYTFMAAC</mount>
     #      <format>FLV</format>
     #      <bitrate>64000</bitrate>
     #      <authentication>0</authentication>
     #      <timeout>0</timeout>
     #    </mountpoint>
     #  </mountpoints>
     #</live_stream_config>
     def t(element):
       '''get the text of a DOM element'''
       return element.firstChild.data
     def check_status(ele):
       # should only be one status element inside a mountpoint
       status = ele.getElementsByTagName('status')[0]
       if t(status.getElementsByTagName('status-code')[0]) != '200':
         msg = t(status.getElementsByTagName('status-message')[0])
         raise Exception('Error locating stream: ' + msg)
     def create_stream_urls(srcfile):
       doc = minidom.parse(srcfile)
       mp = doc.getElementsByTagName('mountpoint')[0]
       check_status(mp)
       mt = t(mp.getElementsByTagName('mount')[0])
       allurls = []
       for s in mp.getElementsByTagName('server'):
         # a thing of beauty, right?
         ip = t(s.getElementsByTagName('ip')[0])
         ports = [t(p) for p in s.getElementsByTagName('port')]
         # yes, it is always HTTP. We see ports 80, 443, and 3690 usually
         urls = ['http://%s:%s/%s' % (ip, p, mt) for p in ports]
         allurls.extend(urls)
       return allurls
     if __name__ == '__main__':
       if len(sys.argv) < 2:
         print 'usage: station callsign must be the first argument'
         sys.exit(1)
     callsign = validate_callsign(sys.argv[1])
     req = make_request(callsign)
     result = urllib2.urlopen(req)
     urls = create_stream_urls(result)
     if len(urls) > 0:
       u = choice(urls)
       print u
       sys.exit(0)
     sys.exit(1)

Once you create the script, don't forget to give it execute permissions:

     chmod ugo+x streamtheworld.py

To test this script out, you can run it from the comand line like this:

     python streamtheworld.py WCMFFM

It will simply output the dynamic URL like this:

     http://208.80.52.50:443/WCMFFMAAC

For the next step, we'd like to be able to schedule a stream capture out of crontab and have it run for a predefined length of time (e.g. 1 hour). We can now do this with a simple, little shell script:

swcapture:

     #!/bin/bash
     # Get the stream URL and fire up mplayer in the background.
     StreamAddr=`python streamtheworld.py WCMFFM`
     mplayer $StreamAddr -ao pcm:file=/tmp/mpstream.wav -vc dummy -vo null \
         </dev/null >/dev/null 2>&1 &
     # Sleep for however long we want to capture the stream.
     sleep 30s
     # Kill the most recently backgrounded job.
     kill $!

Give this script execute permissions:

     chmod ugo+x swcapture

Now, we can run this script and it should capture 30 seconds worth of the stream in the /tmp directory:

     ./swcapture

Check it with:

     ls -l /tmp/mpsteam.wav

In order to have one stop shopping, we can combine everything into a single script that will: 1) directly copy MP3 files that have no RSS feed but are always in a fixed location (e.g. AIR News); 2) capture MP3 streams with streamripper; 3) capture flv streams from StreamTheWorld using mplayer and the steamtheworld script (above).

Here's a script that we use to capture AIR News, Jazz Decades, Morning Edition and Little Steven's Underground Garage (representing all three stream types). This capture script that can be added to your crontab to capture the audio streams of these programs at the appropriate times:

StreamCapture:

     #!/bin/sh
     #
     # Shell script to capture streamed radio broadcasts and save them as mp3
     # files.  This script can be used to create podcasts out of streams when
     # the radio station of interest doesn't offer a podcast, only a live
     # broadcast (e.g. NPR's Morning Edition).
     #
     # This script should be scheduled out of crontab to run at the appropriate
     # time, when the program is supposed to start.  Note that the userid used to
     # run this script sould be the one that is normally used to capture podcasts
     # to the regular podcast directory.  For example:
     #
     #      00 5 * * 1-5  mythuser  /my/scripts/StreamCapture MorningEdition
     #
     # In addition to capturing realtime streams, this script will retrieve mp3
     # files from download sites.  This can be used to assist sites that don't
     # offer an RSS feed but do offer downloadable files.  To use this feature,
     # schedule the script to run at some point after the download file normally
     # becomes available:
     #
     #      00 5 * * 1-5  mythuser  /my/scripts/StreamCapture AIRMiddayNews
     #
     # The list of programs that can be captured are:
     #
     #      AIRMiddayNews   - Downloads the Midday News from AIR.  Should be
     #                        scheduled to run sometime after 13:00 IST
     #                        (GMT+5:30), Monday thru Friday.
     #
     #      BigBandShow     - Records five hours of Glen Woodcock's Big Band Show
     #                        off of CJRT.  Should be scheduled to run at 17:00
     #                        EST (GMT-4:00) or EDT (GMT-5:00) on Sunday.
     #
     #      JazzDecades     - Records one hour of the late Raybo Smith's Jazz
     #                        Decades off of WGBH.  Should be scheduled to run
     #                        at 19:00 EST (GMT-4:00) or EDT (GMT-5:00) on Sunday,
     #                        as long as WGBH keeps rebroadcasting the old
     #                        episodes.
     #
     #      LittleSteven    - Records two hours of Little Steven's Underground
     #                        Garage, the weekly radio show of Steven Van Zandt
     #                        that plays rock 'n' roll and garage rock.  This
     #                        captures the WCMF FM flv stream from StreamTheWorld
     #                        and should be scheduled to run at 22:00 EST
     #                        (GMT-4:00) or EDT (GMT-5:00) on Sunday.
     #
     #                        Note that the streamtheworld.py helper script must
     #                        be installed at the location pointed to by the
     #                        SWHelper variable.
     #
     #      MorningEdition  - Records two hours of NPR's Morning Edition from
     #                        WBUR.  Should be scheduled to run at 05:00 EST
     #                        (GMT-4:00) or EDT (GMT-5:00), Monday thru Friday.
     #
     #
     # Where things are stored.
     #
     PodcastDir=/Podcasts
     SWHelper=/etc/podcast/streamtheworld.py
     #############################################################################
     BuildPlaylist()
     {
     #
     # Begin the playlist.
     #
     echo Build playlist for ${PodcastDir}/${1}
     echo "#EXTM3U" >${PodcastDir}/${1}.m3u
     #
     # Add all of the pod files in the target directory to the playlist.
     #
     OrigDir=`pwd`
     cd ${PodcastDir}/${1}
     for PodFile in `ls -t *.mp3`; do
         #
         # Get this file's date.
         #
         PodDate=`echo ${PodFile} | \
             /bin/grep -e "_[0-9]\{4\}_[0-9]\{2\}_[0-9]\{2\}" -o`
      PodYear=${PodDate%_[0-9][0-9][0-9][0-9]}
      PodYear=${PodYear}
      PodDate=${PodDate_[0-9][0-9][0-9][0-9]}
      PodMonth=${PodDate%_[0-9][0-9]}
      PodMonth=${PodMonth#_}
      PodMDay=${PodDate[0-9][0-9]}
      PodMDay=${PodMDay}
      PodWDay=`date -d ${PodYear}/${PodMonth}/${PodMDay} +%A`
      #
      # Pick up the title, if there is one.
      #
      if [ x"${2}" = x ]; then
          PodTitle=${1}
      else
          PodTitle=${2}
      fi
      #
      # Add the program and date info to the playlist.
      
      echo Adding "${PodFile} - ${PodYear}/${PodMonth}/${PodMDay} (${PodWDay})"
      echo "EXTINF:0,${PodTitle} - ${PodMDay}/${PodMonth}/${PodYear} \
          (${PodWDay})" \
          >>${PodcastDir}/${1}.m3u
      echo "${1}/${PodFile}" >>${PodcastDir}/${1}.m3u

done
#
# Put things back the way they used to was. #
cd ${OrigDir}
}

     #############################################################################
     #
     # Stupidity check.
     #
     if [ x"$1" = x ]; then
         echo Stream to capture not specified
         exit 1
     fi
     #
     # We need an air date and year, for tagging the MP3 file and possibly for
     # making up the stored file name.
     #
     AirDate=`date +%Y_%m_%d`
     AirYear=`date +%Y`
     #
     # Copy the Midday News from All India Radio.  Clean up the old broadcasts and
     # then build an up-to-date playlist.
     #
     if [ "$1" = AIRMiddayNews ]; then
         if [ ! -d ${PodcastDir}/AIRMiddayNews ]; then
             mkdir -p ${PodcastDir}/AIRMiddayNews
             chmod ug=rwx,o=rx ${PodcastDir}/AIRMiddayNews
         fi
         #
         # Use lftp to get the latest MP3 file.
         #
         /usr/bin/lftp -e "get -c -O ${PodcastDir}/AIRMiddayNews \
             \"/writereaddata/broadcast/English-Midday News-Bulletins-619.mp3\" \
             -o AIRMiddayNews_${AirDate}.mp3; quit" \
             http://www.newsonair.com
         #
         # Despite the fact that the pulled file is already an MP3, AIR doesn't
         # apply any tags so we'll tag it with the author, etc.
         #
         id3v2 -a "All India Radio" -A "AIR Midday News, ${AirDate}" \
             -g 255 -t "AIR Midday News, ${AirDate}" -T 1/1 -y $AirYear \
             ${PodcastDir}/AIRMiddayNews/AIRMiddayNews_${AirDate}.mp3
         #
         # Clean up the old files and build the playlist.
         #
         /usr/bin/find ${PodcastDir}/AIRMiddayNews/ -type f -mtime +7 \
             -exec rm -rf \{\} \;
         BuildPlaylist AIRMiddayNews "All India Radio - Midday News"
     fi
     #
     # Capture The Big Band Show from CJRT.  Clean up the old broadcasts and then
     # build an up-to-date playlist.
     #
     if [ "$1" = BigBandShow ]; then
         if [ ! -d ${PodcastDir}/BigBandShow ]; then
             mkdir -p ${PodcastDir}/BigBandShow
             chmod ug=rwx,o=rx ${PodcastDir}/BigBandShow
         fi
         #
         # Capture the stream with streamripper.
         #
         /usr/bin/streamripper http://streamerepsilon.jazz.fm:8000/ \
             -a ${PodcastDir}/BigBandShow/BigBandShow_%d.mp3 -s -l 18000 \
             -o always
         #
         # Tag the MP3 with the author, etc.
         #
         id3v2 -a "Glen Woodcock" -A "The Big Band Show, ${AirDate}" \
             -g 255 -t "The Big Band Show, ${AirDate}" -T 1/1 -y $AirYear \
             ${PodcastDir}/BigBandShow/BigBandShow_${AirDate}.mp3
         #
         # Clean up the old files and build the playlist.
         #
         rm -f ${PodcastDir}/BigBandShow/.cue
         /usr/bin/find ${PodcastDir}/BigBandShow/ -type f -mtime +31 \
             -exec rm -rf \{\} \;
         BuildPlaylist BigBandShow "Glen Woodcock - The Big Band Show"
     fi
     #
     # Capture Jazz Decades from WGBH.  Clean up the old broadcasts and then build
     # an up-to-date playlist.
     #
     if [ "$1" = JazzDecades ]; then
         if [ ! -d ${PodcastDir}/JazzDecades ]; then
             mkdir -p ${PodcastDir}/JazzDecades
             chmod ug=rwx,o=rx ${PodcastDir}/JazzDecades
         fi
         #
         # Capture the stream with streamripper.
         #
         /usr/bin/streamripper http://streams.wgbh.org:8000 \
             -a ${PodcastDir}/JazzDecades/JazzDecades_%d.mp3 -s -l 3600 -o always
         #
         # Tag the MP3 with the author, etc.
         #
         id3v2 -a "Ray Smith" -A "Jazz Decades, ${AirDate}" \
             -g 8 -t "Jazz Decades, ${AirDate}" -T 1/1 -y $AirYear \
             ${PodcastDir}/JazzDecades/JazzDecades_${AirDate}.mp3
         #
         # Clean up the old files and build the playlist.
         #
         rm -f ${PodcastDir}/JazzDecades/.cue
         /usr/bin/find ${PodcastDir}/JazzDecades/ -type f -mtime +730 \
             -exec rm -rf \{\} \;
         BuildPlaylist JazzDecades "Jazz Decades"
     fi
     #
     # Capture Little Steven's Underground Garage from WCMF FM.  Clean up the old
     # broadcasts and then build an up-to-date playlist.
     #
     if [ "$1" = LittleSteven ]; then
         if [ ! -d ${PodcastDir}/LittleSteven ]; then
             mkdir -p ${PodcastDir}/LittleSteven
             chmod ug=rwx,o=rx ${PodcastDir}/LittleSteven
         fi
         #
         # Get the stream URL and fire up mplayer in the background.
         #
         StreamAddr=`python $SWHelper WCMFFM`
         mplayer $StreamAddr -ao \
             pcm:file=${PodcastDir}/LittleSteven/LittleSteven_${AirDate}.wav \
             -vc dummy -vo null </dev/null >/dev/null 2>&1 &
         #
         # Sleep for the two hours while we capture the stream then kill the most
         # recently backgrounded job.
         #
         sleep 7200s
         kill $!
         #
         # Convert the file to an MP3 with lame.  Tag it with the author, etc.
         # Note that we cannot tag the MP3 file with the actual title because it
         # contains an apostrophe.  This fails so we leave it out.
         #
         lame -m s ${PodcastDir}/LittleSteven/LittleSteven_${AirDate}.wav \
             -o ${PodcastDir}/LittleSteven/LittleSteven_${AirDate}.mp3 \
             >/dev/null 2>&1
         id3v2 -a "Steven Van Zandt" \
             -A "Little Stevens Underground Garage, ${AirDate}" \
             -g 78 -t "Little Stevens Underground Garage, ${AirDate}" \
             -T 1/1 -y $AirYear \
             ${PodcastDir}/LittleSteven/LittleSteven_${AirDate}.mp3
         #
         # Clean up the old files and build the playlist.
         #
         rm -f ${PodcastDir}/LittleSteven/LittleSteven_${AirDate}.wav
         /usr/bin/find ${PodcastDir}/LittleSteven/ -type f -mtime +730 \
             -exec rm -rf \{\} \;
         BuildPlaylist LittleSteven "Little Steven's Underground Garage"
     fi
     #
     # Capture Morining Edition from WBUR.  Clean up the old broadcasts and then
     # build an up-to-date playlist.
     #
     if [ "$1" = MorningEdition ]; then
         if [ ! -d ${PodcastDir}/MorningEdition ]; then
             mkdir -p ${PodcastDir}/MorningEdition
             chmod ug=rwx,o=rx ${PodcastDir}/MorningEdition
         fi
         #
         # Capture the stream with streamripper.
         #
         /usr/bin/streamripper http://wbur-sc.streamguys.com:80/ \
             -a ${PodcastDir}/MorningEdition/MorningEdition_%d.mp3 -s -l 7200 \
             -o always
         #
         # Tag the MP3 with the author, etc.
         #
         id3v2 -a "National Public Radio" -A "NPR Morning Edition, ${AirDate}" \
             -g 255 -t "NPR Morning Edition, ${AirDate}" -T 1/1 -y $AirYear \
             ${PodcastDir}/MorningEdition/MorningEdition_${AirDate}.mp3
         #
         # Clean up the old files and build the playlist.
         #
         rm -f ${PodcastDir}/MorningEdition/.cue
         /usr/bin/find ${PodcastDir}/MorningEdition/ -type f -mtime +7 \
             -exec rm -rf \{\} \;
         BuildPlaylist MorningEdition "National Public Radio - Morning Edition"
     fi

MythNetTV

>>>>>>
MythNetTV is an add-on program that uses RSS to download video podcasts (vodcasts), webtv
broadcasts and movie trailers to a local storage directory on your Myth box, whereupon it updates the database such that the downloaded videos end up as recordings on the Watch Recordings page. You can then watch them as if they had be recorded by MythBackend. You can subscribe to any video feed that you want, provided its format is supported.

Note that MythNetTV is a command-line-only program which works but is somewhat difficult to use with subscriptions such as the TED Talks, where a lot of video podcasts appear in the RSS feed. If you like a GUI or want to pick and choose what you get, you might want to consider Miro and MiroBridge (see below), instead. But, beware that MiroBridge does not work on Myth 0.21 (e.g. Mythbuntu 9.04) and it does suffer from dain bramage of its own. On the other hand, it is probably the wave of the future so take that into consideration, if you care.
<<<<<<

MythNetTV can be downloaded from the Mythbuntu repository and istalled as follows (here, we are using /var/lib/mythtv/mythnettv as the storage directory):

>>>>>>

     sudo apt-get install mythnettv
     sudo mkdir /var/lib/mythtv/mythnettv
     sudo chown mythtv:mythtv /var/lib/mythtv/mythnettv
     sudo chmod g+ws /var/lib/mythtv/mythnettv
     mythnettv --datadir=/var/lib/mythtv/mythnettv

<<<<<<

If you'll be downloading programs via bittorrent, you will also need to install bittornado, which you can do as follows:

     sudo apt-get install bittornado

On the other hand, if you are planning to just download regular vodcasts that consist of MP4 or x264 files, and the like, you don't need to install bittornado at all. MythNetTV will work perfectly fine without it.

Before subscribing to any feeds, you may want to set up a storage group on the Mythbuntu machine where you'll run MythNetTV. This allows you to direct where MythNetTV places the downloaded vodcasts and programs, instead of just letting it pick the first directory it finds under the "Default" storage group (the concept of "first" that MythNetTV has may not be the same concept that you have).

If you want to do this, set up a "MythNetTV" storage group on the machine where MythNetTV will be run. You can do this from the MythTV backend setup application (mythtv-setup) that can be run from the desktop System menu. The new storage group is added from the Storage Groups menu of this application.

You can subscribe to a feed in this manner (here, we subscribe to the TED Talks):

     mythnettv subscribe "http://feeds.feedburner.com/TedtalksHD?format=xml" \
       "TEDTalks"

Note that the name you use to subscribe to the feed should not include any spaces (despite its being quoted) or it will break things. For example, do not be tempted to call your subscription "TED Talks".

Once you've subscribed to one or more feeds, you can update the list and download the content like this:

     mythnettv update
     mythnettv download 1 "TEDTalks"

The default action upon download is to queue a commercial flagging job for all of the downloaded material (one job per vodcast). If you'd rather not have this done (i.e. most vodcasts don't have commercials), you can run the download like this:

     mythnettv --nocommflag download 1 "TEDTalks"

If you subscribe to a new feed, there may be lots of older items in the feed and you may not want to see all of them. If that's the case, you can review each of them and mark them as already downloaded (so that they won't be downloaded again) with this command:

     mythnettv markread 1000 "TEDTalks"

You'll be prompted for each item that is currently in the feed which has not yet been downloaded. If you answer "yes" to the question, it will be marked as downloaded. If you answer "no" to the question, it will be left in the queue for downloading. Alternately, you can try turning them all off with this SQL command:

     update mythnettv_programs set download_finished=1, imported=1 \
       where title='TEDTalks'

When you're happy with the results, you can automate things by putting the update and download into your cron table at some suitable time in the middle of the night (say 02:00).

After the feeds are downloaded, you can surf over to the Watch Recordings page and you should see them all there. For example, the TED talks should appear in the list under "TEDTalks".

If a feed gets hosed and MythNetTV gives up on the downloads, you can cause them to be retried if and when the feed is repaired with this SQL command:

     update mythnettv_programs
      set download_started=NULL, download_finished=NULL,
       imported=0, transfered=0, inactive=NULL,
       attempts=0, failed=0, last_attempt=0
      where title like 'TED%'
       and date='2016-09-16 23:12:34';

or possibly:

     ... where guid='eng.hd.talk.ted.com:2584';

Here is a list of some useful RSS feeds:

     ABC News          http://abcnews.go.com/Site/page?id=3520115 (select feed
                         from list)
     ABC US News       http://feeds.abcnews.com/abcnews/usvideos
     ABC World News    http://feeds.abcnews.com/abcnews/internationalvideos
     ABC Tech News     http://feeds.abcnews.com/abcnews/technologyvideos
     ABC 7:30 Report   http://www.abc.net.au/7.30/xml/730_vodcast_m4v.xml
     ABC Lateline      http://www.abc.net.au/lateline/xml/ll_vodcast.xml
     Ben Heck Show     http://revision3.com/tbhs/feed/MP4-hd30
     Chandra in HD     http://chandra.harvard.edu/resources/podcasts/hd/\
                         podcasts.xml
     CNET (RSS home)   http://www.cnet.com/podcasts/
     CNET News (HD)    http://feeds.feedburner.com/cnet/cnetnewshd?format=xml
     CNET Podcasts     http://feeds2.feedburner.com/cnet/allhdpodcast?format=xml
     CNN Daily         http://rss.cnn.com/services/podcasting/cnnnewsroom/rss.xml
     Discovery News    http://feeds.feedburner.com/DiscoveryNews-Top-Stories?\
                         format=xml
     ESOcast           http://feeds.feedburner.com/ESOcast?format=xml
     Frontline World   http://feeds.pbs.org/pbs/frontlineworld
     Hidden Universe   http://www.spitzer.caltech.edu/resource_list/\
                         6-Hidden-Universe-NASA-s-Spitzer-Space-Telescope?\
                         def=hi&format=xml
     Hubblecast        http://feeds.feedburner.com/hubblecast?format=xml
     i on NIH          http://www.nih.gov/news/vodcast/nihvodcast.xml
     NASAcast          http://www.nasa.gov/rss/NASAcast_vodcast.rss
     Nova              http://feeds.pbs.org/pbs/wgbh/nova-video
     PBS Podcasts      http://www.pbs.org/podcasts/ (select feed from list)
     Philharmoia       http://www.philharmonia.co.uk/thesoundexchange/projects/\
                         podcasts/podcast.xml
     Reuters           http://www.reuters.com/tools/rss (select feed from list)
     Reuters Business  http://feeds.reuters.com/reuters/USVideoBusiness?format=xml
     Reuters Tech      http://feeds.reuters.com/reuters/USVideoTechnology?\
                         format=xml
     Reuters Top News  http://feeds.reuters.com/reuters/USVideoTopNews?format=xml
     Revision 3 shows  http://revision3.com/shows
     Scam School       http://revision3.com/scamschool/feed/MP4-hd30
     Royal Society     http://downloads.royalsociety.org/rss/video.xml
     Tech News 2Night  http://feeds.twit.tv/tn2n_video_large.xml
     TED Talks         http://feeds.feedburner.com/TedtalksHD?format=xml
     Wood Whisperer    http://feeds.feedburner.com/TheWoodWhisperer?format=xml

If you ever want to see what feeds you are subscribed to, you can use this command:

     mythnettv list

To unsubscribe from from a feed, you can use the unsubscribe command, like this:

     mythnettv unsubscribe "http://feeds.feedburner.com/TedtalksHD?format=xml" \
       "TEDTalks"

However, this simply marks the feed as inactive, in the MySQL database, and marks all of the files in the feed's list as downloaded. If you really want to purge things from the database, after doing the unsubscribe command, these SQL commands should work:

     delete from mythnettv_programs where title='TEDTalks';
     delete from mythnettv_subscriptions where title='TEDTalks';

Also note that, if you add a feed with a URL that gets an error (the error will only show up once you do "mythnettv update"), the feed will be marked inactive and you will not be able to unsubscribe from it. This will be too baddy, if you then try to add the feed with the correct URL. To fix this up, you'll want to delete the feed with this SQL command:

     delete from mythnettv_programs where title='BadFeed';

To automate downloading of vodcasts in the feeds that you've subscribed to with MythNetTV, you can create a script that can be run at regular intervals and schedule it to do so in crontab:

     #!/bin/sh
     #
     # Shell script to download video podcasts (vodcasts) and load them into
     # MythTV.  This script works in conjunction with vodcasts that are
     # subscribed to by MythNetTV.
     #
     # This script should be scheduled out of crontab to run at the appropriate
     # time, when the vodcasts are supposed to be available.  For some vodcasts
     # (e.g. the large ones) you may want to schedule them at off-peak times.
     # The names of one or more vodcast subscriptions, that are to be downloaded,
     # may be passed on the command line to control what is downloaded.  If no
     # name is passed all available subscribed vodcasts will be downloaded.  This
     # mode can be used at the off-peak time to sweep up everything that didn't
     # get downloaded (for whatever reason) in prior downloads.
     #
     # Note that the userid used to run this script, by cron, should be the one
     # that is normally used to run MythTV.  This is because the vodcasts will be
     # loaded into the Myth storage directory with this userid and the use of the
     # wrong userid will prevent MythTV from being able to delete the video file,
     # when the user asks to delete it.  An example of some typical cron entries
     # might be:
     #
     #      00 10 * * 1-5  mythuser  /my/scripts/VodcastUpdate ABCReport
     #      00 15 * * *    mythuser  /my/scripts/VodcastUpdate CNET+News
     #      30 2  * * *    mythuser  /my/scripts/VodcastUpdate
     #
     # The list of programs that can be captured are any that you have previously
     # subscribed to with "mythnettv subscribe".  The program names are the
     # actual titles that you used to do the subscribe.
     #
     #
     # Where MythNetTV can be found.
     #
     MythNetTV=/usr/bin/mythnettv
     #
     # Where things are stored.
     #
     PodcastDir=/Podcasts
     #############################################################################
     #
     # See if we should just download everything.
     #
     # MythNetTV craps out if we don't tell it how many vodcasts to download.
     # Hopefully, 1000 should do it.  If that's not enough, the link will
     # probably croak from the load, anyway.  So, 1000 is probably a good
     # thing (tm).
     #
     if [ x"$1" = x ]; then
         echo Downloading the whole enchilada
         $MythNetTV update
         $MythNetTV --nocommflag download 1000
         exit 0
     fi
     #
     # Download all of the titles that we were asked to do.
     #
     while [ "$1" ]; do
         echo Downloading only $1
         $MythNetTV update "$1"
         $MythNetTV --nocommflag download 1000 "$1"
         shift
     done

Miro

Video programs (such as vodcasts) can be automatically captured and added to the MythTV recordings directory, where they can be played at your convenience, using a program called miro to periodically fetch the latest vodcast or torrent of your favorite programs. But, beware that Miro (or more specifically mirobridge) will only work with Mythbuntu 9.10 or greater, although it does appear to be the direction video downloading will take in the future (there's a plug-in for mirobridge built in to the 10.04 Mythbuntu setup menu, for example).

We'll begin by installing miro so that podcasts/torrents can be downloaded. Information about how to download and install it is found on the download page at:

     http://www.getmiro.com/download/

However, downloading is not strictly necessary. The easiest way to install miro under Mythbuntu is to use the miro PPA from Launchpad:

     https://launchpad.net/~pcf/+archive/miro-releases

To install the PPA, proceed to the PPA's overview page in Launchpad and find and click the link that reads "Technical details about this PPA". Select your version of Ubuntu from the "Display sources.list entries for" dropdown list. Copy the lines that appear in the text box that look something like this:

     deb http://ppa.launchpad.net/pcf/miro-releases/ubuntu lucid main
     deb-src http://ppa.launchpad.net/pcf/miro-releases/ubuntu lucid main

Fire up your favorite text editor and edit the apt sources.list file. Add the lines that you copied to the bottom of the file:

/etc/apt/sources.list:

.

       .

deb http://ppa.launchpad.net/pcf/miro-releases/ubuntu lucid main deb-src http://ppa.launchpad.net/pcf/miro-releases/ubuntu lucid main

From the PPA's page, you'll find a signing key that looks something like:

     1024R/2D75E850 (What is this?) 

Copy the portion after the slash and add it as one of the keys that apt can use to verify downloads:

     sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 2D75E850

Ask apt to update the list of packages in the system's archive:

     sudo apt-get update

Now, you can install miro from the PPA:

     sudo apt-get install miro

There are a some formats such as certain Windows formats, Real Player, and Apple Quicktime which do not have native codecs under Linux. To work around this issue, external binary codecs that can be used to play these formats are obtained by Medibuntu from the MPlayer website, codecs directory (located at http://www.mplayerhq.hu/MPlayer/releases/codecs/) and distributed in the non-free component of the Medibuntu repository.

If you wish to download and play these formats, you may want to install the optional codecs package from the Medibuntu repository. Note that there is no PPA for this repository since the rules of PPA prohibit the inclusion of non-free code in any repository. Hence, you'll have to do the install directly:

     For i386, the package is called w32codecs:
     wget -c http://packages.medibuntu.org/pool/non-free/w/w32codecs/\
       w32codecs_20071007-0medibuntu2.1_i386.deb
     sudo dpkg -i w32codecs_20071007-0medibuntu2.1_i386.deb
     For amd64, the package is called w64codecs:
     wget -c http://packages.medibuntu.org/pool/non-free/w/w64codecs/\
       w64codecs_20071007-0medibuntu1_amd64.deb
     sudo dpkg -i w64codecs_20071007-0medibuntu1_amd64.deb

>>>>>>
<<<<<<