I was perusing the TBS forum recently and discovered that there’s a problem that can occur, notably with certain TBS cards but possibly with others as well, that can result in semi-corrupted recordings. The .ts file that contains the recording actually contains the entire program, and can usually be repaired by chopping off a few megabytes at the start of the file, but as it sits on the TVHeadEnd server it’s not easily playable for one or both of two reasons:
- It reports the wrong length (time) for the recoding – for example a one hour program may appear to be of a much greater length (several hours long), and/or
- The video and audio are out of sync by a second or two, where this is not usually the case.
In Kodi, you can generally play such a recording from the start, but skipping around within the program may be problematic or impossible.
The possible fix for this is to set a “Skip Initial Bytes” setting for each tuner, as described in this post on the TBS forum. The conversation there appears to be about a specific TBS card (the TBS6905) but I have heard of this problem happening with other cards as well. As best I can understand the problem, the card starts sending a virtual firehose stream of data before the buffers are ready to receive it, and some data gets lost at the start, corrupting the file. By skipping some initial bytes, you get only the “good” data once everything has had time to initialize. That’s probably a gross oversimplification, but that’s what I got out of that thread.
The place to change the setting is here:
You might think the number of bytes skipped is quite high, but since even a 30 minute recording can contain several gigabytes of data, that number is actually insignificant. The original poster in the thread states that “The 18800000 setting is a bit arbitrary; I chose it because it is more than 1 Meg and is the ‘Input Buffer (Bytes)’ value x 1000. If the issue persists I may try an even higher value.” Feel free to experiment with lower or higher values; I personally think I’d start with something lower such as 188000 (10 times the Input Buffer) and then if that doesn’t resolve the issue, go up to 1880000. And if that still doesn’t always fix the problem, then go to the 18800000 value. But, it’s entirely up to you. And remember that if you have more than one tuner, you have to add this setting for each affected tuner.
The thread also notes, “If the new value doesn’t appear after you change it and click save, refresh the page in your browser, then navigate back to the TV adapters tab.”
If TVHeadEnd is creating these types of bad recordings on your backend server, I’d suggest this fix is at least worth a try, since you can easily reverse it if it turns out to not have any effect.
What if you already have a bad recording and want to fix it?
While the above advice may help you prevent future bad recordings, it will not help you fix an already recorded program that has bad timing information. Usually ffmpeg can fix the timing issues, so I have used this script to fix existing recordings:
# If calling from Tvheadend, invoke using path/to/scriptname "%b"
# Then $1=%b in this script
# Extension of converted file must be same as original file (.ts)!
/usr/bin/ionice -c 3 /usr/bin/nice -n 20 /usr/local/bin/ffmpeg -loglevel quiet -i "$1" -c copy -f mpegts "converted-$1" &> /dev/null
mv -f "converted-$1" "$1"
The line that starts with /usr is a long line, so you may need to copy the above script and paste it into a text editor to see it correctly. Note that you must run this as the hts user (or whatever user the Tvheadend service runs as) to avoid permissions issues (you can do sudo su hts to temporarily become the hts user). And you must check all the paths shown in this script to make sure they are valid for your system, and change them accordingly if they are not.
The first (non-comment) line changed the working directory to the directory where Tvheadend stores its recordings. The second line uses ffmpeg to convert the file – it simply copies all the audio, video, and data information but it does fix the timing information in most cases. The “/usr/bin/ionice -c 3 /usr/bin/nice -n 20” at the beginning of the line is to set this process to the lowest priority, so that if you are actively recording any channels at the time, it won’t steal CPU power or disk I/O from that activity. The final line moves the converted file over the original. You must move it over the original, not copy it, because Tvheadend will lose track of the recording if you try to copy it over. This script does not save a backup of the original file, so if you want one, copy the original file to a safe location prior to running this script.
To use the script, find the filename of the bad recording (you could do ls /home/hts/recordings) and then, as the hts user, just run the script with the filename as an argument. Note that it is also possible to call the script as a Post-processor command in a Digital Video Recorder Profile in Tvheadend, so that the script will run automatically when a program finishes recording (in case you have a channel that frequently gives you bad recordings, and you can’t use the method shown at the top of the page). See the comments at the top of the script for information.
If you are running on a system that doesn’t have the bash shell, this script will probably run just was well under whatever shell you have, although minor tweaking may be required. At the very least, you will need to change the #!/bin/bash line at the top. And, this assumes you have ffmpeg installed on your system – run which ffmpeg from the command line, and if ffmpeg is present then it will show the correct path to ffmpeg. If you don’t have ffmpeg installed and it isn’t available in your Linux distribution’s repository, then I suggest using a static build of ffmpeg, since it is much easier to install than trying to compile it from scratch. Just copy the ffmpeg program (and any of the others you may want) from the downloaded archive to the /usr/local/bin directory, and make sure the ownership and permissions are set correctly (should be owned by root, and executable by everyone). I use Midnight Commander (mc) to do these types of operations, but to each their own.
Obviously, the fix shown at the top of this article is a lot easier to implement than using ffmpeg to fix a bad recording once it’s already recorded (plus, using that method, you can start watching the show while it is still being recorded without issues) but some tuners may not have the “Skip Initial Bytes” setting, or changing it may not work for some tuners. In my experience it almost always works for TBS tuners (unless you are having a problem with low signal strength or quality), so try the “Skip Initial Bytes” setting first if it is available to you!