Dogs Nattai

Summer Fun

Dogs Nattai

Nattais’ 5th Birthday

May 25th Nattai turned 5 years old. I got him some cookie treats and a haul of toys from Pet Smart. A Chuck It flying Squirrel, 3 pack of Chuck It balls and a couple basic toys.

I had to read the fine print to make sure I actually bought a cookie for dogs and not people!
Nattai with his new toys. Squeaky Yellow spiked ball and the Chuck-It flying squirrel.

Dogs Nattai

Stick Is Life

Close up photo of Nattai a Blue Heeler cattle dog panting.
Close up of Nattai after fetching stick.

It’s been almost two months with Nattai now. He’s adjusting to his new life very well. I tried to set him up for success and I feel like it is working well. Might have thrown him into the fire in certain instances too soon on some things. It’s hard to not know that he hasn’t experienced things that are normal day to day for me. Or some things that you’d have expected a dog to have already experienced.

Nattai fetching a stick.
Dogs Nattai

Nattai the Cattle Dog

Meet my re-homed Australian Cattle Dog Blue Heeler, Nattai.

It was time for another chapter in my life.

Cobar Dogs Hemophilia

Cobar | 2007-2020

My beautiful, charismatic, loyal and best friend of 13 years Cobar passed away peacefully at my side on October 19th, 2020.

Cobar was an Australian Cattle Dog Red Heeler. He suffered from a a blood disease called Hemophilia. It was of the worst kind. He had 2% clotting factor (his blood didn’t clot). We were together from beginning to end. He lived a good happy life and full filled his job by making people happy and playing as much as he could.

He will be missed greatly.

photo of dog laying in grass with plush toy

Fedora Sendmail

Sendmail – Spamassassin – Configuration Errors

This is an entry to remind me of how I corrected some small issues with Spamassassin. I use Fedora, Sendmail, Spamassassin and upon upgrading to latest version I started getting some errors from Spamassassin. This is how I fixed the errors.

Can’t locate MLDBM/ error

I got this error even though the MLDBM perl module was installed via the package system. This may be a deprecated configuration, as it appears the solution is something to do with mySQL databases. I went with the cpan, cpanm, then install the MLDBM::Sync module route. Quick and painless. As root:

; Install cpanminus.
#cpan App::cpanminus
; Using cpanm to install the MLDBM:Sync that is missing from package.
#cpanm MLDBM::Sync

FuzzyOcr: Cannot find executable for gifinter

This error is due to the giflibs v5.x no longer has many of the utilities that were in the v4.x releases and FuzzyOcr hasn’t been updated. I suspect this isn’t really used much anymore, but there’s a couple solutions. I used the method of downloading, compiling and copying over the giflib v4.x gifinter program. Just download the latest v4.x version from the sourceforge project. Do the usual ./configure; make. But not make install. Copy the gifinter program to /usr/local/bin. Edit the /etc/mail/spamassassin/ file. Look for the #focr_bin_gifinter line and change it to /usr/local/bin/gifinter. I use /usr/local/bin to keep manually compiled programs separate from package installed programs that are usually in /usr/bin/.

Configuration file requires version 3.004002 of SpamAssassin, but this is code version 3.004003

Was surprised this even occurred. This was simple as running as root;


FFMPEG – Converting DSF to FLAC

When converting SACD DSF audio files to FLAC (or any other PCM type format) the conversion process will most likely introduce distortion in the upper frequencies. In order to eliminate this you need to use the lowpass filter during the conversion process. This post is mainly so I won’t forget.

These are the ffmpeg commands I used to convert to regular FLAC. To convert to 24bit FLAC use s32 for the sample format.

convert one file to flac
ffmpeg -i inputfile.dsf -af "lowpass=24000,volume=6db" -sample_fmt s16 -ar 48000 outputfile.flac
Convert all dsf files in directory
for i in *.dsf; do ffmpeg -i "$i" -af "lowpass=24000, volume=6dB" -sample_fmt s16 -ar 48000 "${i%.*}.flac"; done

24 bit and 32 bit FLAC

At the time I wrote this the FLAC encoder only supported 16 and 24 bit encoding. As of ffmpeg v6 the FLAC encoder now appears to support 32 bit encoding using the -strict experimental switch. Be sure to test playback devices for the new 32 bit encoded FLAC files.

convert to 24 bit flac
ffmpeg -i inputfile.dsf -af "lowpass=24000, volume=6dB" -sample_fmt s32 -ar 48000 outputfile.flac
convert to 32 bit flac
ffmpeg -i inputfile.dsf -strict experimental -af "lowpass=24000, volume=6dB" -sample_fmt s32 -ar 48000 outputfile.flac

Audio Filters

Remember that the audio filters are specific to convert DSF files only. If you are converting other file types to FLAC they are not necessary. The values are not absolute and can be modified. The lowpass filter passes all frequencies below its setting and blocks any above it. This is required due to the high frequency distortion from converting DSD format to PCM format. The volume filter adjusts the volume. This isn’t required, but highly recommended as the volumes between the two formats are represented differently. The resulting PCM file will be lower in volume. These settings are not specific to FLAC but the conversion process from DSD to PCM.

Written by a real human. No AI involved.

Fedora Sendmail

Sendmail – LetsEncrypt and verify=OK

How To Configure LetsEncrypt and Sendmail Properly

This documentation pulls from a form post on FreeBSD from user Kuli.

LetsEncrypt certificates aren’t listed in the main distributed ca-bundle.crt. The confCACERTand confCACERT_PATH configurations are two independent configurations that don’t really have anything to do with each other. When verifying certificates, it looks in the confCACERT_PATH for individual hashed files of root certificates. The confCACERTwill be configured with the intermediary LetsEncrypt chain.pem. Sendmail will then be happy to verify=OK the certificates. Do note that, it appears the majority of mail servers are using certificates that can’t be verified. So you will see a lot of NO. It’s better than FAIL. The script works with Fedora and probably any variant of Linux. Your experience may vary.

2021 Update!

I have discovered a much better way to generate the hashed ca files! I really struggled with the shell script. I have only tested this with Fedora 33, though I suspect it should work on other distributions.

Sendmail Configuration

define(CERT_DIR',/etc/letsencrypt/live/<your site>')

Create the CACERT_PATH files

2021 New Easy Way:

#p11-kit extract --format=openssl-directory --filter=ca-anchors --overwrite /usr/local/etc/ssl/ROOT/

Old Kinda Broken Shell Script Way:

#Separate the root cert into files each with only one cert and name hashed

mkdir -p $DESTDIR
rm -f *
cat $RCert | sed -E '/^(Certificate:|SHA1 Fingerprint|#| |$)/d' | awk 'BEGIN {c=0;} /BEGIN TRUS/{c++} { print > "cert." c ".pem"}'

for a in ls $DESTDIR
    mv $a openssl x509 -hash -noout < $a.0


Liquidsoap – Multi-Bitrate DASH streaming configuration

This is an example of multi-bitrate DASH streaming configuration. In this example Liquidsoap will be configured to output three different MPEGTS video streams with various frame size, bitrates and one stereo audio MPEGTS stream all via  UDP.  This configuration can be used with the same setup as my previous blog post about setting up Liquidsoap MPEGTS DASH streaming. This example is using Liquidsoap v1.3.3.

Please note that this is more of a proof of concept than practical use. A hardware encoder plugin for Gstreamer would help.

Liquidsoap Configuration: MPEGTS via UDP for Multi-Bitrate DASH Streaming

set("gstreamer.add_borders", true)

input = single("/home/user/Videos/Test/test-1280x720-25fps.ogv")

#MPEGTS Output For DASH Streaming.
#You must start Shaka Packager first before starting Liquidsoap.

#Audio Channel. Port 5000
"audioconvert ! fdkaacenc bitrate=128000 ! queue ! mpegtsmux alignment=7 name=muxer ! queue ! udpsink host= port=5000

#Video Channels.
#360p Video at 600kbps. Port 5001
"videoscale ! video/x-raw,width=480,height=360 ! videoconvert ! x264enc bitrate=600 key-int-max=72 pass=qual quantizer=20 tune
=zerolatency ! video/x-h264,profile=baseline ! queue ! mpegtsmux alignment=7 name=muxer ! queue ! udpsink host= port=5001 s

#480p Video at 1000kbps. Port 5002
"videoscale ! video/x-raw,width=640,height=480 ! videoconvert ! x264enc bitrate=1000 key-int-max=72 pass=qual quantizer=20 tun
e=zerolatency ! video/x-h264,profile=main ! queue ! mpegtsmux alignment=7 name=muxer ! queue ! udpsink host= port=5002 sync

#720p Video at 3000kbps. Port 5003
"videoscale ! video/x-raw,width=1280,height=720 ! videoconvert ! x264enc bitrate=3000 key-int-max=72 pass=qual quantizer=20 tu
ne=zerolatency ! video/x-h264,profile=main ! queue ! mpegtsmux alignment=7 name=muxer ! queue ! udpsink host= port=5003 syn
Shaka Packager Command

The packager will take the UDP output from Liquidsoap and encapsulate it into the DASH format for playback via the Shaka Player or any other DASH player.

$packager \
'in=udp://,stream=audio,init_segment=audio_init.mp4,segment_template=audio_$Number$.m4s' \
'in=udp://,stream=video,init_segment=h264_360p_init.mp4,segment_template=h264_360p_$Number$.m4s' \
'in=udp://,stream=video,init_segment=h264_480p_init.mp4,segment_template=h264_480p_$Number$.m4s' \
'in=udp://,stream=video,init_segment=h264_720p_init.mp4,segment_template=h264_720p_$Number$.m4s' \
--temp_dir /home/user/tmp -mpd_output test_h264.mpd

That is pretty much all there is to it. You could add higher or lower frame size and bitrates if you wanted to. However, this configuration is pushing the limits of Liquidsoap.


Liquidsoap – Streaming DASH via UDP

So now that you have that magical UDP stream going, what to do with it? Why  not a DASH stream using the HTML5 Shaka Player? DASH is D)umb A)ss S)treaming H)ibbtyjibbty also known as the Hard Drive Killer. Cause you ain’t gunna be doing this on a mechanical drive for very long. Who thought the idea of creating millions of tiny files constantly was a good idea? We totally needed a new wheel worse than the one before it, right? I mean, who wants to install various different media players when you now can install various different browsers. Anyways, on to the show!

This is relatively straight forward with a lot of ambiguity.  The path of the stream is as follows; Liquidsoap output MPEGTS via UDP into Shaka Packager. Shaka Packager encapsulates the MPEGTS stream into a DASH stream for playback via a web server and HTML5 clients and other media players that support DASH (such as VLC).  You will want to download the Shaka Packager and Shaka Player.  This is a bit beyond the scope of this article oh how to get the Shaka Player compiled, but just trudge through it.

Liquidsoap Configuration

First part we need to configure Liquidsoap. This will be a basic configuration with the key parts being the output settings. Most notably and very important is that the Shaka Packager does not support the RTP container so it’s MPEGTS flat out.


set("gstreamer.add_borders", true)

# The input file,
# any format supported by liquidsoap
input = single("/home/user/Videos/Test/video-720x576-25fps.ogv")

#MPEGTS via UDP Streaming (Shaka Packager doesn't support RTP container).
 "videoconvert ! x264enc pass=qual quantizer=20 tune=zerolatency ! video/x-h264,profile=baseline ! queue ! muxer.",
 "audioconvert ! fdkaacenc bitrate=128000 ! queue ! muxer.",
 "mpegtsmux alignment=7 name=muxer ! queue ! udpsink host= port=5000 sync=true",

The Shaka Packager doesn’t support MPEGTS in RTP via UDP. If you encapsulate your MPEGTS stream via RTP you will get this error from packager.

[0522/] Demuxer::Run() on file 'udp://'.
[0522/] Initialize Demuxer for file 'udp://'.
[0522/] Not implemented reached in shaka::Status shaka::media::Demuxer::InitializeParser()
[0522/] Packaging Error: 4 (UNIMPLEMENTED): Container not supported.
Shaka Packager

The Shaka Packager is just a fairly simple program. I just downloaded the binaries and put them in my /home/user/bin/.

In this scenario and since we are using UDP as the transport, the Shaka Packager will need to be started first and listening for the MPEGTS stream packets BEFORE Liquidsoap starts. This is an important and key step in this.

For this example we will start the Shaka Packager program in the root web directory of our website the DASH manifest and media files will be created in this directory.

[/var/www/html/]$packager \
 'in=udp://,stream=audio,init_segment=audio_init.mp4,segment_template=audio_$Number$.m4s'  \ 'in=udp://,stream=video,init_segment=h264_384p_init.mp4,segment_template=h264_384p_$Number$.m4s' \
--mpd_output h264.mpd

The Shaka Packager is fairly straight forward. Since the Audio and Video is in a single stream we call both streams for our audio and video.  It will create all the necessary media files and the MPD manifest file in the current directory.  Once Shaka Packager is running it will just print out that it’s initialized the demuxer for input from the UDP stream.  It is now time to start Liquidsoap.

Once you start Liquidsoap, the Shaka Packager doesn’t announce anything so it is difficult to know that it is working.  With this current setup after about a minute or two the Shaka Packager will spit an error similar to this.

[0522/] Found a gap of size 343 > kRoundingErrorGrace (5). The new segment starts at 324900702 but the previous segment ends at 324900359.

If you get this error then you know it’s working. As long as the gap size doesn’t grow the stream should be good.

Shaka Player

So now that you got the stream files all going, you could point VLC to the http://localhost/h264.mpd file and VLC should be happy to play the DASH stream.  But now onto the Shaka Player. It is beyond the scope of me to tell you how to install it. But I feel you.

Following the basic guide for the Shaka Player, just copy the shaka-player.compiled.js script into the same directory as the media files. Then create a simple index.html file.

<!DOCTYPE html>
<!-- Shaka Player compiled library: -->
<script src="shaka-player.compiled.js"></script>
<!-- Your application source: -->
<script src="myapp.js"></script>
<video id="video" width="640" poster="//" controls autoplay></video>

Then you will want to create the myapp.js file which is essentially a kind of configuration and initialization file for the Shaka Player. This is the file that points to the DASH manifest (MPD) file that the Packager has created.

// myapp.js

var manifestUri = '//localhost/h264.mpd';

function initApp() {
// Install built-in polyfills to patch browser incompatibilities.

// Check to see if the browser supports the basic APIs Shaka needs.
if (shaka.Player.isBrowserSupported()) {
// Everything looks good!
} else {
// This browser does not have the minimum set of APIs we need.
console.error('Browser not supported!');

function initPlayer() {
// Create a Player instance.
var video = document.getElementById('video');
var player = new shaka.Player(video);

// Attach player to the window to make it easy to access in the JS console.
window.player = player;

// Listen for error events.
player.addEventListener('error', onErrorEvent);

// Try to load a manifest.
// This is an asynchronous process.
player.load(manifestUri).then(function() {
// This runs if the asynchronous load is successful.
console.log('The video has now been loaded!');
}).catch(onError); // onError is executed if the asynchronous load fails.

function onErrorEvent(event) {
// Extract the shaka.util.Error object from the event.

function onError(error) {
// Log the error.
console.error('Error code', error.code, 'object', error);

document.addEventListener('DOMContentLoaded', initApp);

You should now have a functioning DASH stream with Liquidsoap.  This is a basic example and can be expanded on with enough CPU resources and x264 hardware encoding via GStreamer.  The idea of DASH is to have multiple bit rates at various frame sizes so that you can cover a wide variety of client types and connectivity.  I haven’t tested this out, but you could start with a larger frame size setting in Liquidsoap then create multiple video outputs with the various frame sizes. You will only need one audio output.

Have fun!