Building a VCR based on Linux and IVTV |
IVTV Video RecorderLately I've seen the rising popularity of so-called HTPC-solutions as well as standalone DVD-recorders that have been put together to make our lives and accessibility for entertainment easier than it has been until recent times. However I never had the need for most of the functionality or complexity added by most of these solutions - what I wanted was simply a solution that would record the shows I wanted to see without any fuss... Especially those that ran in the timeslots after my bedtime. Most directly existing solutions simply weren't usable or even worked with my hardware so I had to put it together myself based on standard computer components.Table of Contents
0. The hardwareAs a basis for the solution I'm reusing one of my older computers that I had lying around the house, and with a few modifications it was ready to go.The computer comes with the following specifications:
Several cards were inspected and I at one point ended up buying a cheap Happauge! WinTV-PCI-FM, but this however was a mistake since the capture-quality of this card is so low you'll soon regret it (also uses a rather slow BT88xx-chip without hardware support). With this experience in mind I decided to stop being a cheapskate and shelled out for one of the top of the range cards in the form of a Happauge! WinTV-PVR-500MCE card (from this point I'll refer to this card as PVR-500). The PVR-500 is a media center card intended to be used with Microsoft Windows XP Media Center 2005, but this can also easily be used on Linux via the IVTV-driver. Specifications includes FM-stereo radio, two tuners capable of full frame 720x576 PAL as well as a hardware-based MPEG2 encoder/decoder. 1. The operating systemFor the operating system to go on the computer I chose my favoured distrobution, and opted to install the latest release of Patrick Volkerding's Slackware Linux, version 10.2. This is one of the oldes distrobutions and every aspect of it is easily configurable by editing plaintext-files.The installation is rather straight forward as long as you remember to partition your hard-drive before starting the setup-program. Since I had 200GB at my disposal I simply set away 512MB for swap memory (it's better to give up a little hard-drive space and not need it than it is to suddenly run out), 20GB for the main root (/) as well as dedicating the rest of the drive for video. Since we have a lot of space available I recommend simply installing everything of the cds, both of them actually, and not having to wonder if a missing dependency is somewhere to be found on the cd or if I'll need to go searching for them. One thing you should however note is that the IVTV-driver will for the most parts not work with 2.4.x kernels so you should be installing the 2.6.x kernel that comes with that release. Also take note that for some reason the modules for kernel 2.6.x will not be installed by the setup program and will have to be installed manually from cd #2 - while you're there install the kernel-source as well as the package containing the ALSA-modules for this kernel. As well as that you should refrain from deactivating hotplug-support since the driver depends on it. 2. Configuring soundcardConfiguring the soundcard is trivial thanks to the easy to use utilities that comes with Linux, but you need to have already installed the ALSA-modules as well as booted into the stock 2.6.x kernel. Log in as root and run the following command to auto-detect and configure the soundcard:alsaconfThis should take care of loading the correct modules, and modifying the configuration-files so that the card is configured and ready for use even after the computer has been rebooted. If the card however isn't detected then this could be because of conflicting resources, but this can normally easily be corrected by moving it to another free PCI-slot. 3. Installing and configuring TV-tuners (IVTV)The PVR-500 is as previously mentioned supported on linux via the IVTV-driver, but as most technical aspects of Linux rarely are the most straight forward things in this world I'll go through the installation step-by-step.3.0 Install IVTVStart by downloading the latest stable version of the driver from the homepage and you'll be ready to start. Compiling and installing the driver should be done as following:tar -zxf ivtv-0.4.0.tar.gz 3.1 Install the correct modulesWhile running "make install" you'll probably notice a few warnings due to some unusable (for us that is) modules that came with the kernel, but this isn't really a problem since we'll be replacing those manually. To make those incompatible modules stop being an issue we'll rename them by executing the following set of commands:cd /lib/modules/`uname -r`/kernel/drivers/media/video/Now that we have those out of the way we can now move the correct freshly compiled modules into place (first go to the directory where you extracted ivtv) by running the following command: cp *.ko /lib/modules/`uname -r`/kernel/drivers/media/video/That final command will take care of reindexing the modules available on your system meaning that when we later try to load a module then the underlying system hopefully knows what to do. 3.2 Module optionsWe are now ready to start configuring the modules we just installed, and that implies that we are going to edit the file "/etc/modprobe.conf" (manual says "/etc/modules.conf", but this configuration-file seemed to work just as well) - as editors go I recommend that you use either pico or emacs since they are a lot easier than vim if you aren't all that experience with Linux and Unix systems.Add the following lines to the end of the file: alias char-major-81 videodevIf you've read other guides for installing you'll notice that the third and fourth line isn't usually listed and this is because this card as opposed to the more reasonably priced one has two tuners so we need the third line to use the second tuner - the fourth however makes sure that the cards are set to PAL upon start. 3.3 Obtain and install firmwareThe PVR-500 doesn't feature on-chip firmware and while this means that updating firmware is incredibly easy it does however mean that we'll need to have the driver load the firmware from a file. The firmware recommended at the time this project started has been attached to this project, but I recommend checking wether there's a new version available before using these. If you decide to download the newer firmware you need to know how to extract them from the windows drivers on the Happauge! homepage, but first use the following set of commands to download and unzip the driver:wget ftp://ftp.shspvr.com/download/wintv-pvr_150-500/inf/pvr_2.0.24.23035.zipNext we'll need to copy the firmware into the correct directories on your Slackware installation: cp HcwMakoA.ROM /lib/firmware/v4l-cx25840.fwThe next step entails installing the MPEG decoder firmware, and you should take note that the ivtvfwextract.pl-script is located in the utils subdirectory of the directory where you extracted the ivtv-source. Extracting and moving the firmware into the correct locations can be done as following: wget ftp://ftp.shspvr.com/download/wintv-pvr_250-350/inf/pvr_1.18.21.22254_inf.zipThe last and final step in installing the firmware is moving a special mpeg-file, used to initialize the tuners, that comes with the ivtv-distrobution - do that as following: cd ivtv_source/ 3.4 Load modulesThis should take care of the firmware, and we are now ready to actually test that the driver actually loads. The driver will be loaded automatically on reboot as long as you've activated hotplug-support (this is very important since the driver won't load without it), but since I don't believe in rebooting after every tiny alteration you can go ahead and load the modules with the following command:/sbin/modprobe ivtvIf you get errors probing for the card you probably have resource conflicts and should try moving it to another free PCI-slot, but for now we'll assume you didn't get any errors. Before continueing you should take a look at the output in /var/log/messages to see if the driver initialized successfully - if hotplug wasn't loaded you'll see errors about firmware not being found and this should correct itself once you've enabled hotplug-support and rebooted (or started it manually, "/etc/rc.d/rc.hotplug start"). 3.5 Tune to a channelLiving in Norway and being a subscriber to Canal-Digital cable-tv I should use the standard channels for western europe - with this setup the norwegian channel TV2 is on channel E8. Tuning to that channel can be done with the "ivtv-tune"-utility that came with ivtv with the following command:/usr/local/bin/ivtv-tune -t europe-west -c E8You should't get any errors from this command, and if the tuner found a signal on that frequency the tool will output the frequency as well as a message that a signal was found. 4. Watch TVHere is the moment we have all been waiting for, and it's time to actually watch tv on one of the newly installed tv-tuners. PVR-500 outputs MPEG2 encoded video directly instead of the raw data most Linux TV-applications expect so we won't be able to use programs such as XawTV - the good news however is that programs such as Xine and MPlayer can read this data directly.If you installed all the software on the Slackware cd-roms the most suitable program installed will be Xine, and watching TV can be done using the following command (see "Tune to a channel" for details on how to change channels): cat /dev/video | xine stdin:/If you don't allready have a graphical desktop installed or don't have it properly configured you can still watch tv from a textbased terminal by substituting the "xine"-command with "aaxine" - the display quality is laughable, but it'll give you an idea wether you're watching a blank screen, static or sweet TV. 5. Recording TVThanks to the hardware-based MPEG2-encoder all we need to do in order to record TV is to copy the frames from /dev/video to a filename of your choosing. The simplest solution would imply simply running "cat /dev/video > recording.mpg" and pressing Ctrl-C to stop recording, but this isn't all that easy to do while sleeping so we'll need some sort of program to do this for us - unfortunately I never could find a program to do this so I made a few bash-scripts to do this for me (attached to the project).The syntax for using the "record.sh"-script is as following: record.tv HH:MM:SS "channel decription"What this means is that if you want to record a program called American Idol on channel SE10 with a duration of 45 minuts you would give the following command when the program started (notice the hyphens around the description): record.tv 00:45:00 SE10 "American Idol"The script will put a temporary file in /var/run when a tuner is being used for recording so that if the first tuner is busy the script will instead use tuner number two. The result is an easy to use recorder that'll easily record two shows at the same time. The script is also able to use a channel name instead of the rather cryptic channel numbers such as E8 by adding the corrensponding channels and their names to the file name ".channels" - at the moment this only works one way with the result being more descriptively named video-files. The supplied script, scan_tv.sh, is able to scan the channels relevant to your area and create a file with the channels that had a detectable signal. 5.0 Set to record at a specific timeSetting the script to record at a specific time isn't directly possible, but thanks to years of work put into the standard commandline-tools on Linux we have everything we need to get started - the tool we're going to used is "at" via the "atd"-daemon so make sure that the relevant packages are installed if they aren't already (if you followed the Slackware-installation instructions on this page this daemon is installed and running).We can set the program to record a 30-minute long show on channel E8 on March 31 2006 at 23:00 by running the following command (notice the extra slashes around the program description for record.sh): echo "/path_to_scripts/record.sh 00:30:00 E8 \"Program description\"" | at 23:00 31.03.06The "atd"-daemon running on your system will now take care of keeping track of the time and making sure that your show gets recorded on schedule - just make sure that you don't schedule more shows than you have tuners in that timeslot (PVR-500 has two tuners and to be quite honest more than two good shows at the same time seems statisticly impossible given the whole reality farce the world is going through at the moment). See the man-pages for at for more information on this tool. 5.1 Regular recordingsWhile the previous chapters dealt with setting up a job that takes care of recording a single show and as such is a one-time assignment, but what if you for instance would like to make sure that you get to see a tv-serie you're following - this chapter'll show you how a regular recording job can be set up using crontab.Crontab is a daemon that takes care of running programs and scripts at regular intervals with basis in the configured jobs you enter into it's configuration file. An ordinary crontab entry found on a regular standard Slackware (in the file /var/spool/cron/crontabs/root) looks like the following: This file can be said to consist of six separate sections, and the descriptions for what these sections actually means is instantly a lot clearer when the following chart is taken into account:20 4 1 * * /usr/bin/run-parts /etc/cron.monthly 1> /dev/null Suddenly the file doesn't look so scary any more, and if you're wondering how you can make things happen at a regular interval such as every monday, tuesday and wednesday all you'd need to do is comma-separate the values in the date field so that it read "1,2,3".* * * * * command to be executed - - - - - | | | | | | | | | +----- day of week (0 - 6) (Sunday=0) | | | +------- month (1 - 12) | | +--------- day of month (1 - 31) | +----------- hour (0 - 23) +------------- min (0 - 59) Personally I enjoy watching show xxx (lasts 30 minuts, and in case you're wondering I just used xxx as an example name) on channel SE16 every weekday at 21:00, and in order to make sure that show is recorded every time I would have to add the following entry to my crontab-file (/var/spool/cron/crontabs/root): This should take of that, but please take notice that the crontab-daemon might not instantly realize that it's configuration-file has been changed (try doing a "kill -HUP pid" on its process). One thing you'd also be wise to remember is that some channels might not actually start the program at its given time due to commercial breaks or timing differences between you and them so I'd recommend starting the recording a bit earlier and increasing the duration so that you're ensured to get the whole thing - commercial breaks before and during can be easily fast-forwarded past when viewing it at a later moment.00 21 * * 1,2,3,4,5 /root/scripts/record.sh 00:30:00 SE16 "xxx" 6. Converting MPEG2 to another formatNot everyone likes the way MPEG2 seems to take up a lot of space on the hard-drive - with the standard settings on this card one hour of MPEG2 equals between 3.5 and 4.0 GB. This is perfectly agreeable for files you don't intend to keep lying around, but files you'd like to keep should perhaps be converted to another format. Converting media-files isn't the easiest thing to do on Linux due to heavy dependencies, but I'll try to give the instructions needed to make a suitable program, transcode, work for you. The list below lists the various packages that need to be installed - those that do not have especially described installation routines are installed using the classic "configure", "make" and "make install".6.0 Installing transcodeInstallation steps:
6.0.0 libdvdreadHomepage: http://www.dtek.chalmers.se/groups/dvd/downloads.shtml6.0.1 libdvdcssHomepage: http://developers.videolan.org/libdvdcss/6.0.2 lameHomepage: http://lame.sourceforge.net/download/download.html6.0.3 libmpeg2 (mpeg2dec)Homepage: http://libmpeg2.sourceforge.net/Additional commands: ./bootstrap 6.0.4 mjpegtoolsHomepage: http://mjpeg.sourceforge.net/Additional commands: configure, make ... 6.0.5 xvidcoreHomepage: http://www.xvid.org/Additional commands: cd build/generic/ 6.0.6 ffmpegHomepage: http://ffmpeg.sourceforge.net/index.phpAdditional commands: ./configure --enable-shared --enable-pthreads --enable-mp3lame --enable-xvid --enable-gpl 6.0.7 transcodeHomepage: http://www.transcoding.org/cgi-bin/transcodeAdditional commands: ./configure --enable-mjpegtools 6.1 Converting mediaAfter having installed transcode with a lot of dependencies we are now ready to start converting files, and for that purpose I've examined a few settings that may or may not prove usefull...MS MPEG4 suitable for Windows Media Player: # MS MPEG4 for Windows Media Player Xvid4: #- y xvid, export type - see /usr/local/lib/transcode/export_* for more choices 7. About the scriptsThe bash-scripts that have been attached to this project have been put together in order to enable me to easily set up, record and organize recordings. The script named "record.sh" was used in chapter 5, Recording tv, and is the most central functionality, but the rest of them may prove usefull to you as well - they do however assume that you have already installed the utilities that came with the ivtv-driver as well as transcode if you intend to convert any of the files to Xvid.7.0 Directory structureThe first thing you should make sure is that you have made a directory structure that is suitable for use by the scripts that are described a lot more in detail in chapter 7.2, About the scripts. The directory structure is the same as the structured directory called "video" that you can see in the filebrowser - a tree view of the directory should look like the following:. `-- video |-- convert_me |-- converted |-- keep `-- recordings
7.0.0 videoThis is the folder where newly recorded shows will be placed when running the "record.sh"-script.WARNING: If configured to do so via crontab the script named "delete_old.sh" will regularly take care of deleting all files in this folder (doesn't touch any of the subfolders so they're safe to put stuff in) that were created more than five days ago. 7.0.1 video/convert_me/If configured to do so via crontab the "convert_all.sh"-script will at a regular interval take care of converting all MPEG2-files in this folder to Xvid files. The original MPEG2-file will be deleted while the Xvid-file will be placed in the subfolder called converted.WARNING: Files in this folder will as previously mentioned be converted to a new Xvid and the original file will then be DELETED. 7.0.2 video/converted/Files in the "convert_me" will, if configured to do so by using "convert_all.sh" via crontab, be converted to Xvid and subsequently be placed in this folder.7.0.3 video/keep/To be quite honest there's really nothing special about this folder at all other than that you can be sure the files here won't be touched by any of the supplied scripts - either by you calling them directly or scheduled via crontab.7.0.4 video/recordings/If you've activated the CHANNEL_DIRS-variable from within "record.sh" (the current setting if you haven't changed it yourself) recorded files are put within subdirectories named with the same name as the channel names the recordings were taken from. Using this setting should prove to ease keeping cluttering at bay since it'll be easier to get an overview when you have configured many regular recordings.7.1 Configuring the scriptsThe first thing you should make sure is that you have made the directory structure described in section 7.0, Directory structure. After doing that you need to edit the various scripts to check that all the variables in the settings-section of the scripts point to what they're supposed to be pointing to - if you installed everything according to the instructions on this page you'll mostly only have to make sure that the path to the various folders described in chapter 7.0, directory structure, are accurate.A couple of the scripts will also need special attention by setting them up as a cron-job - instructions on how to do this is described in the next couple of sub-chapters. 7.1.0 Setting up "delete_old.sh"Takes care of deleting recordings older than five days, but for a more detailed description of what this script does see chapter 7.2.2, "delete_old.sh". The following line takes care of executing this script 01:00 every night:00 1 * * * /path_to_scripts/delete_old.sh 1> /dev/null 7.1.1 Setting up "convert_all.sh"Takes care of converting files in "convert_me" to Xvid, but for a more detailed description of what this script does see chapter 7.2.0, "convert_all.sh". The following line takes care of executing this script 02:00 every night:00 2 * * * /path_to_scripts/convert_all.sh 1> /dev/null 7.2 Script descriptionsThe following is a description of the various scripts that composes this package as well as in some cases examples on usage.7.2.0 "convert_all.sh"The purpose of this script is to process all files in the directory named video/convert_me/ and convert them using the previously installed transcode-application via the "convert_xvid.sh"-script. Converted files will be placed in the directory named video/converted/ - the original file is removed after the file has been converted. While this script can be run directly from the command-line its purpose is really to be run at an appropriate time - perhaps in the middle of the night when the computer isn't used for anything else.7.2.1 "convert_xvid.sh"A simple script that uses the transcode application to convert an MPEG2-file such as the ones made by the "record.sh"-script into an Xvid-file. The script itself takes two input parameters, one being the file to convert and the other the filename of the converted file. Conversion can be done as following:./convert_xvid.sh my_input_file.mpg my_output_file.xvid 7.2.2 "delete_old.sh"Script, intended to be run via crontab at night, that has as a main purpose to make sure that we don't run out of disk-space due to neglect or failing to clean up once in a while. This script simply scans the video-directory (all subdirectories are left untouched) for files older than 7 (easily changed by editing the script) days and deletes them.7.2.3 "record.sh"The center of the whole package, and in short is the script that actually takes care of making an actual recording. In essence you supply the channel (run "scan_tv.sh" to view a list of channels) you want to record from, the duration to record as well as an optional description you want added to the filename.Simply put in order to record a half-hour show on channel E8 described as "My favourite show" you'd issue the following command: ./record.sh 00:30:00 E8 "My favourite show"Doing regular recordings or a one-time recording at a specific time and date can be used by using either crontab or the at-daemon - for more information see 5. Recording TV.
7.2.4 "scan_tv.sh"This script uses the ivtv-tune program that comes with the ivtv-driver and runs through all channels registered for the frequency table used where I'm currently living (europe-west, see documentation for the ivtv-driver for other choices) outputting a list of all channels where a signal has been detected - ie. there was a tv-channel on that specific frequency.In addition when the "record.sh"-script generates a filename that is used when recording - the name of the channel recorded from is included as the first part of the filename. Since the scripts doesn't automatically know what a channels name is - that name is read from a file called "channels.conf", and a simple template for this file can be created by supplying this script with a filename which to write to. Generating a blank "channels.conf"-file consisting of only the tv-channels with a sufficient signal can be done as following (remember to edit the file in order to add better channel descriptions later on): ./scan_tv.sh channels.conf 7.2.5 "setup_card.sh"Takes care of setting up some of the initial configurations of the tv-tuners suitable for running at boot. Among other sets the capture resolution to 720x576 PAL with the default bitrate at 8000000 bits per second (DVD-quality is supposedly around 5000000 although signal degradation on the tv-signal will make a DVD look a little bit better). Another item that needs tending is the fact that volume of the captured sound was a bit low on my default configuration so I set it to max-volume here - you may experience other results.In most cases the default settings should be both adequate and sufficient to make the card function so running this script may not be necessary, but I find that it's needed. 7.2.6 "tuner_status.sh"All of the scripts here makes sure to create files named tuner0.running and / or tuner1.running in "/var/run" when a specific tuner is currently being used - this scripts simply checks for the existance of these files and outputs a nice status page regarding the tuners current availability.
7.2.7 "view_tv.sh"The script takes care of checking too see wether there are any available tuners, and if there are the script runs and allows you to view the currently selected tv-channel via the Xine multimedia player. Other programs could possibly be used, but the script relies on Xine - in addition you'll offcourse need to have X-running in order for Xine to run properly.7.2.8 "current_channel.sh"This script reads a few of the hardware registers and translates them into an understandable format in order to present the user with a description of which channels the different channels are currently set to.
7.2.9 "tune.sh"This scripts purpose is to give easily usable interface from which the user can tune a tuner to a specific channel. Channels are read from "channels.conf" and displayed on the screen in a menu - in addition to entering numbers (and pressing ENTER) to select a channel you can enter 's' to swap active tuner as well as a single lower-case 'x' to exit the script.
|