How to add NOAA weather radio (or another streaming radio station) as a radio channel in TVHeadEnd

I confess, this has nothing to do with Satellite TV, but there are times when you may be watching recorded TV or even a saved video on your HTPC and the weather outside starts to have ominous rumblings.  Wouldn’t you like to be able to quickly tune to your local NOAA weather radio station to hear the current forecast and any weather alerts?  I realize most of you will tune to a local TV station or grab your phone to check the weather, but there are satellite TV viewers in parts of the country that lose all local TV reception in severe weather.  So as long as your Internet connection stays up, and assuming there is a stream covering your area, you can do a quick check just by tuning to the NOAA weather radio station.

Of course you should not rely on this as your sole way of getting weather information, since it could unexpectedly go down for a number of reasons.  But another reason for publishing this was to show the basic method of setting up a radio station in TVHeadEnd that originates from a streaming source.  Once set up in this manner, you can listen to it live or even record it using TVHeadEnd’s Digital Video Recorder (Time Schedules).

First, if you have not already created an IPTV Network, see my previous article, Fixing the audio on live TV from a certain network (which shall remain nameless) in TVHeadend and generally follow the process shown there, up to the point where it shows the pipe URL usage. In this case, the pipe command you will want to use should look something like this:

pipe://ffmpeg -loglevel fatal -i http://ADDRESS_OF_STREAM -vn -c copy -strict -2 -metadata service_provider=RADIOPROVIDER -metadata service_name=RADIONAME -f mpegts -mpegts_service_type digital_radio pipe:1

Replace http://ADDRESS_OF_STREAM with the URL to your NOAA weather radio stream. You can go to this Weather Underground page and if a city in your area is on the list of available stations, right click on the mp3 URL link for that city and copy the link. So for example, if you are in Los Angeles, the address would be http://audioplayer.wunderground.com/wb6ypf/Altadena.mp3 (as of the date when this article was written – note these links could change over time!).

Optionally, replace RADIOPROVIDER with something meaningful, like NOAA or Weather_Underground. Do not use spaces or punctuation (underscores in place of spaces are okay).

Replace RADIONAME with a meaningful name, like NOAA_Weather_Radio. Again, do not use spaces or punctuation.

Also in the Add Mux screen, make sure the Scan Status is set to PEND and that EPG Scan is disabled. Also it is important that you fill in the Mux Name field with something meaningful, since this will be the default channel name.  Click the Create button and it should find the stream and add it to the Services tab, and from there you can map it to a channel. It seems that with these streams mapping the channel in the normal manner does work.

Here is how the MUX configuration screen should appear after it’s been created and scanned (the Scan Status here shows IDLE, but when first created you’d use PEND):

NOAA Weather Stream Configuration

I won’t guarantee this will work with all audio streams you encounter on the Internet, but it’s always worth a try. In particular, I don’t know how it would work with stream URLs that do not start with http://. But at least this will get you started. If you have a “recipe” for another specific type of stream, please feel free to leave it in the comments.

EDIT: If you are using Tvheadend 4.3 or newer and you get an error such as “iptv: libav: Could not open input ‘pipe:///usr/bin/ffmpeg … (blah, blah) … ‘: Protocol not found”, you probably need to uncheck the box “Use A/V Library” in the IPTV network settings, and/or select “Do not use” in the dropdown for the “Use A/V Library” setting in your Mux settings – see this thread in the Tvheadend forum for details.

You may also be wondering if it’s possible to build a TV channel from an online streaming video source. Well of course it is possible, I just don’t know the “formula” for the pipe command at this time. Credit goes to this thread on the Kodi forum and user kaiseruk for providing the basic format of the pipe URL shown above.

Former Team Kodi member apologizes “if I was (or ever will be) ever a dick to you”

For those of you that run a satellite backend and use Kodi as the frontend on your media center, you may find this Reddit post (and the subsequent discussion) quite interesting:

To all the Kodi users and members of the community out there: I’m sorry if I was (or ever will be) ever a dick to you (Reddit)

It’s a rare moment of candor from someone associated with a software development project, and particularly one that so many of us use.

A bash script to rebuild the TBS tuner drivers after Linux kernel updates

UPDATE: This article covers rebuilding the TBS proprietary drivers for Linux that were formerly recommended by TBS, the last released version of which (at the time of this writing) is v170330 (link is to zip file containing the drivers on TBS’s site). However, recently TBS has switched to recommending the open source drivers which are NOT the subject of this article.  Some users may still prefer to use the proprietary Linux drivers, or may find that certain older cards will not work with the open source drivers.  In that case these instructions may still work, but be aware that if you have been using Linux kernel version 4.4.0-142-generic (or older) and then get upgraded to 4.4.0-143-generic (or newer) the proprietary drivers will stop working unless the following driver files are patched or replaced: ivtv-udma.c, ivtv-yuv.c, videobuf-dma-sg.c, and videobuf2-dma-sg.c — see the edits at the bottom of this article for more details.

Something that seems to annoy many TBS tuner card owners is that the TBS drivers need to be rebuilt and reinstalled EVERY SINGLE TIME there is a Linux kernel update, and although it’s not a particularly difficult process, it is time-consuming (it can take several minutes).  And, there a bit of typing or cutting and pasting involved, plus it’s possible to miss a step or introduce a typo and create a bad build. So, here is a bash script that you can install and run that will attempt to rebuild and install your TBS drivers. It came from a thread on Reddit so I cannot vouch for it in any way, but it looks pretty solid.

This script probably should not be relied upon for a first time installation of the drivers, since it does not appear to do any checks for any necessary dependencies, and also it does not check to make sure that your TBS cards aren’t using a shared IRQ (which is generally a bad thing – see this article for the fix). But, once you know your TBS cards work you could perhaps use this script after those kernel updates to keep them working.  As far as I know this script is not endorsed or supported by TBS, in fact they probably don’t even know about it.

If it is your first time installing the TBS drivers and you are running some version of Ubuntu or Debian, then at least do this prior to running this script for the first time:

sudo apt-get update
sudo apt-get install linux-headers-`uname -r`
sudo apt-get install make gcc

You should only need to do that once, and don’t be surprised if some or all of those are already installed. If you are not running some version of Ubuntu or Debian then you may still need to install Linux headers, make, and gcc using your OS’s package management tool, if any of those are not already installed.

Caveats (things not mentioned in the original Reddit thread but observed by reading the script):

  1. You must create a directory called “Drivers” in your home directory (enter mkdir ~/Drivers at the command prompt), this is where it will store the current driver version. The script as written does not appear to create the Drivers directory if it doesn’t already exist.  If you want to change the name or location of this directory then change the line “cd ~/Drivers” in the script accordingly. EDIT: This line has been modified so that if the directory does not exist, the script will no longer just blindly forge ahead in whatever directory you happen to be running it from; instead it will advise you to create the directory and exit.
  2. You must make the script executable.
  3. As written it appears it must be run as root or using sudo (sudo ./scriptname)
  4. It appears that as written it is dependent on the current TBS practice of showing the latest Linux version on the page at http://www.tbsdtv.com/download/ and actually providing the driver file at http://www.tbsdtv.com/download/document/common/tbs-linux-drivers_vyymmdd.zip where yymmdd are replaced by the file date.
  5. It seems that as written, the script is intended for use with modern 64-bit versions of Linux, as indicated by the “./v4l/tbs-x86_64.sh” – if you are running a 32-bit Linux (is anyone still doing this?) then you’ll need to use either “./v4l/tbs-x86_r3.sh” (for x86 32 bit installations of kernel 3.x) or if you are really living in the past, “./v4l/tbs-x86.sh” (for x86 32 bit installations of kernel 2.6.x) instead.
  6. After it runs to completion it will ask if you want to reboot the system, which will be necessary before the rebuilt drivers can be used.

I don’t guarantee this script will work for you.  Use is entirely at your own risk! I’m just passing it along. Feel free to comment on whether it works for you or not.

#! /bin/bash
(( UID != 0 )) && { echo "Error: needs root"; exit 1; } #Use this to check for root
cd ~/Drivers || { echo "Error: ~/Drivers directory does not exist - run 'mkdir ~/Drivers' (without the quotes) from the command prompt"; exit 1; }
rm -rf linux-tbs-drivers #Remove previous linux-tbs-drivers directory if it exists
wget -nc "http://www.tbsdtv.com/$(wget -q -O - 'http://www.tbsdtv.com/download/' | sed -n 's@.*href="\([^"]*common/tbs-linux-drivers_v[0-9]*.zip\)".*@\1@; T; p; q')" #The $() part returns only the first occurrence of "common/tbs-linux-drivers_v[0-9]*.zip". Downloading it with -nc (no clobber) will not overwrite a currently existing archive.
for latest in tbs-linux-drivers_v*zip; do :; done #This loops over all versions and $latest will become the alphanumerically last one.
if unzip -o "$latest"; then
    tar xjvf linux-tbs-drivers.tar.bz2
else
    echo "Error: Unzip failed"
    exit 1
fi
cd linux-tbs-drivers
./v4l/tbs-x86_64.sh || { echo "Error running ./v4l/tbs-x86_64.sh"; exit 1; }
make || { echo "Error running make"; exit 1; }
make install || { echo "Error running make install"; exit 1; }
read -p "Reboot (y/N)? "
[[ "$REPLY" == y ]] && reboot

EDIT: If your Linux kernel has been updated to 4.4.0-143-generic (or newer in the 4.4.0 kernel series) then you may need to apply CrazyCat’s patches when building the drivers, or make will fail. So do this at the Linux command prompt:

cd ~
mkdir Driver-patches
cd Driver-patches
sudo wget https://bitbucket.org/CrazyCat/linux-tbs-drivers/raw/c64955dd0fe79c9c76628de424bd2ec57ede115b/linux/drivers/media/video/ivtv/ivtv-yuv.c
sudo wget https://bitbucket.org/CrazyCat/linux-tbs-drivers/raw/c64955dd0fe79c9c76628de424bd2ec57ede115b/linux/drivers/media/video/ivtv/ivtv-udma.c
sudo wget https://bitbucket.org/CrazyCat/linux-tbs-drivers/raw/c64955dd0fe79c9c76628de424bd2ec57ede115b/linux/drivers/media/video/videobuf-dma-sg.c
sudo wget https://bitbucket.org/CrazyCat/linux-tbs-drivers/raw/c64955dd0fe79c9c76628de424bd2ec57ede115b/linux/drivers/media/video/videobuf2-dma-sg.c

Then modify the bash script shown above – add these lines just before the line cd linux-tbs-drivers:

cp ~/Driver-patches/ivtv-udma.c ~/Drivers/linux-tbs-drivers/linux/drivers/media/video/ivtv || { echo "Error copying patched ivtv-udma.c file"; exit 1; }
cp ~/Driver-patches/ivtv-yuv.c ~/Drivers/linux-tbs-drivers/linux/drivers/media/video/ivtv || { echo "Error copying patched ivtv-yuv.c file"; exit 1; }
cp ~/Driver-patches/videobuf-dma-sg.c ~/Drivers/linux-tbs-drivers/linux/drivers/media/video || { echo "Error copying patched videobuf-dma-sg.c file"; exit 1; }
cp ~/Driver-patches/videobuf2-dma-sg.c ~/Drivers/linux-tbs-drivers/linux/drivers/media/video || { echo "Error copying patched videobuf2-dma-sg.c file"; exit 1; }

After that your update script should work again, at least until the next time some incompatibility is introduced into the Linux kernel.

EDIT 2: And that did happen. Rather that continuing to tell you to make several edits, here is the complete script that appears to work in mid-September, 2019 – note that you still must have the patched drivers in the Driver-patches directory as explained above, or the script will fail:

#! /bin/bash
(( UID != 0 )) && { echo "Error: needs root"; exit 1; } #Use this to check for root
cd ~/Drivers || { echo "Error: ~/Drivers directory does not exist - run 'mkdir ~/Drivers' (without the quotes) from the command prompt"; exit 1; }
rm -rf linux-tbs-drivers #Remove previous linux-tbs-drivers directory if it exists
wget -nc "http://www.tbsdtv.com/$(wget -q -O - 'http://www.tbsdtv.com/download/' | sed -n 's@.*href="\([^"]*common/tbs-linux-drivers_v[0-9]*.zip\)".*@\1@; T; p; q')" #The $() part returns only the first occurrence of "common/tbs-lin$
for latest in tbs-linux-drivers_v*zip; do :; done #This loops over all versions and $latest will become the alphanumerically last one.
if unzip -o "$latest"; then
    tar xjvf linux-tbs-drivers.tar.bz2
else
    echo "Error: Unzip failed"
    exit 1
fi
cp ~/Driver-patches/ivtv-udma.c ~/Drivers/linux-tbs-drivers/linux/drivers/media/video/ivtv || { echo "Error copying patched ivtv-udma.c file"; exit 1; }
cp ~/Driver-patches/ivtv-yuv.c ~/Drivers/linux-tbs-drivers/linux/drivers/media/video/ivtv || { echo "Error copying patched ivtv-yuv.c file"; exit 1; }
cp ~/Driver-patches/videobuf2-dma-sg.c ~/Drivers/linux-tbs-drivers/linux/drivers/media/video || { echo "Error copying patched videobuf2-dma-sg.c file"; exit 1; }
cp ~/Driver-patches/videobuf-dma-sg.c ~/Drivers/linux-tbs-drivers/linux/drivers/media/video || { echo "Error copying patched videobuf-dma-sg.c file"; exit 1; }
cd linux-tbs-drivers || { echo "Error changing directory to linux-tbs-drivers"; exit 1; }
./v4l/tbs-x86_64.sh || { echo "Error running ./v4l/tbs-x86_64.sh"; exit 1; }
make || { /bin/sed -i '/CONFIG_VIDEO_TLG2300=m/c\# CONFIG_VIDEO_TLG2300 is not set' ~/Drivers/linux-tbs-drivers/v4l/.config; echo "Attempted ~/Drivers/linux-tbs-drivers/v4l/.config file patch - will restart$
make || { echo "Error running make"; exit 1; }
make install || { echo "Error running make install"; exit 1; }
read -p "Reboot (y/N)? "
[[ "$REPLY" == y ]] && reboot

If you found this article useful you may also like:
Do you run one or more TBS PCIe cards under Linux? Check your IRQs…

How to move Tvheadend’s settings from one system to another, or preserve them during a full reinstallation

If you have Tvheadend currently running on an existing system, and you decide to build a new system OR do a full reformat and reinstall on your current system (maybe because you want to upgrade the operating system and/or Tvheadend itself), you may have wondered if there is a way to move Tvheadend’s settings from one system to another, or to reinstall them on a system after a full update, even one that involves reformatting the hard drive. While there is no officially supported method, there have been several posts in the Tvheadend forum recently stating that people have had success in doing this by simply copying over the /home/hts/.hts/tvheadend directory from one system to another. However it’s not quite that simple, because you want to preserve permissions and ownership of the files, and there are a few other steps. As best I can determine, here is the full procedure (yes, I realize there is some redundancy in the use of sudo here). You should probably read the entire post before actually doing anything, and make sure you understand the entire process.

On the existing system, enter the following commands:

sudo service tvheadend stop
sudo -s
cd /home/hts/.hts
sudo tar cvfp ../tvheadend.tar tvheadend
cd /home/hts/

At this point you need to move tvheadend.tar file to a different system if you plan on reformatting the drive, or to the new system if you’re creating an entirely new setup after you have installed Tvheadend as described below. I would also urge you to copy any recordings you wish to keep, and any programs/scripts you may run outside of Tvheadend (for example, scripts and data to provide guide information to Tvheadend). You can use a Linux tool such as scp for this process (for example, sudo scp tvheadend.tar root@ip:~/) or if you have a way to transfer files via nfs, samba, ftp, sftp, etc. it doesn’t matter, just so long as you can move the tvheadend.tar file and any other files you want to save to a safe place.

On the new system, install your operating system and the driver(s) for your tuner card(s)/device(s), if any. Then install Tvheadend using one of the methods shown on the Download page. After you have done that, check to make sure that Tvheadend can find your tuners (in the TV adapters tab) – if it can’t then you need to figure out why before proceeding. Next, copy back/over all the files you saved in the previous step, putting them in the exact same directories they were in on the previous system (this is especially important if you want Tvheadend to find any recordings you saved). Then enter the following commands on the new system:

sudo service tvheadend stop
sudo -s
cd /home/hts/.hts
sudo mv tvheadend tvheadend-backup
tar xvfp ~/tvheadend.tar

Now if you reboot (or restart Tvheadend) you should find that your previous configuration is restored, except that it is possible that your tuner(s) will not be linked to any network(s). So go back to the TV adapters tab and make sure that each tuner is enabled and that it is linked to the correct network. Also, if you did not copy over the recordings from your previous system (or failed to put them back in the exact same spot in the directory tree), they will show up under the “Failed Recordings” tab in the Tvheadend web interface, so you can go ahead and delete those. Also, check the “Recording System Path” and the Timeshift “Storage Path” (under the Recording tab) to make sure that they are correct and that you have actually created directories with those names, and that they have the correct permissions and ownership.

If for some reason it does not work and you want to reconfigure Tvheadend from scratch, stop the Tvheadend service, delete the /home/hts/.hts/tvheadend directory, and rename the /home/hts/.hts/tvheadend-backup directory back to just tvheadend. Then reboot, or restart Tvheadend.

EDIT (August 2017): Note that if you are moving to Tvheadend version 4.2 or later from a pre-4.2 version, you may find that everything will work fine until you try to add a new channel to an existing mux, by rescanning the mux. It seems Tvheadend may find the new service, and allow you to map it as a new channel, but when you go to watch it you will get “No input source available for subscription” errors. The problem is that in 4.2 there are some new mux settings that you can only see if you set the View level to Expert. They are the checkboxes for “Accept zero value for TSID:” and “EIT – skip TSID check:”, and by default both are unchecked. But here in North America, providers often use invalid transport stream IDs. So, you probably need to check the boxes for both of those, and again, you will not even see those settings unless you set the view level to Expert. If you don’t do this, Tvheadend may not scan in any or all of the available services on the mux, but even if it does find and add a new service, you might get errors when you attempt to view a channel that you have mapped from the service.

New checkboxes in Tvheadend 4.2

If that doesn’t resolve the problem, you may need to delete the existing mux and any associated services and channels, and then re-add that mux, and then rescan the mux and re-add your channels. But maybe you fear that if you delete your existing channels, Tvheadend won’t rescan them. So if you want to assure yourself that Tvheadend can rescan the mux before you delete the existing one, create a temporary “test” network, temporarily link it to the tuner associated with the correct satellite dish and LNB, and then create a new temporary mux under that. That will allow you to see if Tvheadend can find the services in the mux before you delete your existing mux, services, and channels. If it works, you can delete the test network and temporary mux, as well as the existing mux and associated services and channels, and then recreate the mux using the correct network. (End of edit).

Once you are sure that everything is working the way you want, you can delete the tvheadend.tar file and the tvheadend-backup directory. However, it might not be a bad idea to take a “snapshot” of the /home/hts/.hts/tvheadend directory from time to time, and save it to a different system or at least a different hard drive, so you have a way to go back to working settings if everything falls apart or you make some major blunder.

When creating a new system, keep in mind that if you were using ffmpeg for any purpose on your previous system, you should make sure it is properly installed on the new one, and that if it’s not in the same place in the directory tree that you adjust any links accordingly. Also make sure any programs that provide guide data to Tvheadend are working correctly (you may need to check the permissions and ownership), and if you had any scheduled cron jobs, make sure you recreate those.

Some of the information in this post was derived from posts by Mark Clarkstone in an obscure thread in the Tvheadend forum.