Fixing the audio on live TV from a certain network (which shall remain nameless) in TVHeadend

266px-Pavo_cristatus_(male)_-feathers-8aThis is a followup to a previous article, Fixing the audio on recorded programs from a certain network (which shall remain nameless). In that article, which you may want to read first for some additional background information, I showed you how to fix the audio on previously-recorded programs. In this article, I’ll show you how to do it in real time, assuming you are using TVHeadend (version 3.9.2100 or later) as your PVR backend software. This is useful for both watching live TV, and for when you are recording a program but want to begin watching the recording before the program has ended.

My note about ffmpeg from the previous article also applies here:

Note: For this to work, you must have a version of ffmpeg from (link is to download page) or, if you are a Linux user but do not feel comfortable attempting to build software from source, then you may be better off using a static build such as is offered at this site (technically this is an unofficial build, so use at your own risk, but as I write this the packages offered in the deb repositories are older versions that don’t work as well for this purpose, and produce files that don’t play well on underpowered systems). Please note that some Linux distributions, notably some versions of Debian and Ubuntu and their derivatives, provide a package called ffmpeg in their repositories that is not true ffmpeg, but instead is a transitional package for libav. The syntax shown above will not work with the transitional package version; you need true ffmpeg for this to work! For the reason this sad situation exists, see The FFmpeg/Libav situation or for a slightly more technical view, FFmpeg versus Libav.

Another possible way to get the real ffmpeg installed on Ubuntu and some derivative systems is explained in the article, How To Install FFmpeg 2.6.1 On Ubuntu 15.04, Ubuntu 14.10, Ubuntu 14.04 And Derivative Systems from the site.

This assumes that you have already scanned in the relevant channels from either the Ku-band side of AMC-1 or the C-band side of AMC-18 and that you have assigned them channel numbers in TVHeadend’s web interface. If you are in the habit of occasionally renumbering your channels as you add new ones or remove ones that are no longer functional, then I suggest you give those channels high numbers that will not be changed (starting with 1000 or even 10000, for example). The reason is that if you change the numbering of those original channels, this will stop working until you make the necessary adjustments. In any case, you need to note the channel numbers assigned to those channels, as they will be needed in one of the steps here.

The first thing you have to do, if you have not done it already, is to create an IPTV network. In TVHeadend’s web interface, go to Configuration > DVB Inputs > Networks and create a new IPTV Network:

Select IPTV network from the dropdownConfigure the new network as shown here:

Give the network a name, and uncheck The Network Name can be anything you like; I just called it IPTV to make it easy to recognize.  I also unchecked “Network Discovery” because it seems that you can’t automatically scan the channels anyway, so I didn’t want TVHeadend trying to do something in the background that would fail.

The above only has to be done once, no matter how many channels you add.  The next thing you need to do is add a Mux.  In TVHeadend’s web interface, go to Configuration > DVB Inputs > Muxes and create a new Mux, selecting the IPTV network from the dropdown:

Choose the IPTV network from the dropdown.Configure the new Mux as shown here:

Add Mux 2The full URL should be in this form (this is all one line):

In FFMPEG Version 2.x:
pipe:///usr/local/bin/ffmpeg -loglevel fatal -i -c copy -filter_complex [0:1][0:2][0:3]amerge=inputs=3,pan=5.1|FL=c0|FR=c1|FC=c2|LFE=c3|BL=c4|BR=c5 -c:a eac3 -f mpegts pipe:1

In FFMPEG Version 3.0 and later (only when using eac3 as the output codec):
pipe:///usr/local/bin/ffmpeg -loglevel fatal -i -c copy -filter_complex [0:1][0:2][0:3]amerge=inputs=3,pan=5.1|FL=c0|FR=c1|FC=c2|LFE=c3|BL=c4|BR=c5 -c:a eac3 -mpegts_flags system_b -f mpegts pipe:1

      • The above line assumes that ffmpeg is located in the /usr/local/bin directory on your system – if that’s not the case, and there’s a good chance it isn’t depending on which instructions you followed when you installed ffmpeg, you must change the path to point to the actual location of ffmpeg (you can enter “which ffmpeg” from the Linux command line to find the correct path).
      • Replace CHANNEL_NUMBER with the channel number of the original channel – this is why I suggested that you assign those channels high channel numbers, so you would not want or need to renumber them later.
      • Note that this converts the audio to eac3, which Kodi will generally play as true 5.1 audio, depending on its audio settings and the ability of your AV receiver to handle encoded audio (in some Kodi skins it’s erroneously reported as 7.1, but it’s really 5.1). If that doesn’t work for some reason, you can try changing the -c:a option from eac3 to ac3 or if it still doesn’t work, you can try mp2 as a last resort (but you may only get 2-channel stereo if you use mp2). When using ffmpeg 3.0 or later and specifying the eac3 codec, the -mpegts_flags system_b option must be included, or you may get no audio at all!
      • The above line converts the audio stream only.  All other streams are copied verbatim, which means that video, closed captions (if available) and anything else in the original stream should also be available in the converted stream (although closed captions seem to be iffy; in my experience that stream often has missing characters or is not present at all).

Be sure to give the Mux a name of your choosing – it makes it a lot easier to work with in the subsequent steps.  Short and simple is better here, for example just the network name and time zone.  It only needs to be unique and recognizable.

After adding your Mux, you can look in the Services tab to make sure it got added, but don’t try to map the service from there because it won’t work (at least I could never get it to work).  Instead, go to Configuration > Channels / EPG > Channels and click the Add button or link (in the bar just above the channel list).  You can then add the channel from this dialog box:

Add ChannelMake sure the “Enabled” box is checked.  For the Name, enter the channel name as you want it to appear in your channel list and guide in Kodi.  For the Number, give it the channel number you want it to use.  In the Services dropdown, select the correct service from the list; it will be in the format Network Name/Mux Name/Service01.  Note you may also see a listing of the form Network Name/Mux Name/{PMT:####} or something similar in the dropdown, but don’t use that one because it won’t work.  Use the one that ends in Service01.

If you have figured out how to add channels to the Electronic Program Guide, then you should also select the correct EPG Source from the dropdown.  Do not check the “Auto EPG Channel” box.  Then click the “Create” button.

If you want to add more channels (for different time zones, etc.) then just repeat the above process, starting with adding a new Mux.

You should be able to play your added channel(s) just like any other satellite channels in Kodi (or whatever you use to play video from the backend).  Note that because this is piping a stream through ffmpeg in real time, there may be a short delay (a few seconds at most) before the stream starts playing if you are trying to watch Live TV.  Unfortunately, this short delay apparently sometimes causes Kodi to ignore the video stream, but only when trying to play Live TV.   My guess is that because the video doesn’t arrive quickly enough, Kodi thinks you’re playing a radio or other audio-only channel and ignores  the video stream.  If this happens, you can stop the playback and try again, or you can start recording the channel, wait several seconds, and then start playing the recording.  I have never seen this problem occur when playing a recording, probably because recordings tend to start playing almost immediately. You only see it when you attempt to play the live stream directly, and even then it will only happen a certain (hopefully small) percentage of the time.

Speaking of recording,  if you want to record from the channel, you do that in the normal manner, just as you would for any other channel.  There’s no need to do any type of post-processing, unless you do that for reasons other than to fix the audio.

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.

EDIT: If it doesn’t work or suddenly stops working, check that you haven’t inadvertently blocked TVHeadEnd from accessing itself in the Access Entries tab in TVHeadend’s web interface.  At one point we tried changing the Network prefix values away from the default to something more specific to the local network.  Everything else on the network could still access the backend, but it caused these channels to fail with an error message “No input source available for subscription” because TVHeadEnd could no longer access itself.  Strange…

On my TVHeadend backend, I’ve found that ffmpeg does not add significantly to the CPU usage as long as you are only converting audio.  I think converting video would be an entirely different story, and I doubt you could do that in real time unless you have a very high-powered backend system (and maybe not even then), but feel free to try if you have that need.

Custom MPEG-TS Input (TVHeadend Wiki)