ytffmpeg-1.1.0 released!

The wait is finally over! ytffmpeg-1.1.0 is now available! This comes with a few new features and some tested workflows that streamline activities around video creation, subtitle generation and now with the ability to post the results to an SFTP endpoint!

Project Page



Download from Github

What is ytffmpeg?

ytffmpeg is a python project that was put together to automate workflows when it comes to video editing, subtitle generation and video composition. I refuse to pay for software on a license like Adobe Illustrator. Most of the awesome video editors out there were made specifically for a Mac or Windows and have little to no support for Linux. OpenShot-QT crashes too consistently to be used reliably. Also, personally, I find the GUI-version of video editing to be quite distasteful. It just doesn't seem like I can get the level of precision on a frame-by-frame basis like I can get with ffmpeg. Being able to drill down to the very frame of the video and make perfect cuts every time rather than a slider (try editing a 10-min video in-app on TikTok -- big fingers, tiny buttons). Kdenlive became slow and would crash when editing videos >~8mins...

Also, with my background in CloudOps/DevOps, I became accustomed to the idea of using configuration files to describe the final result.

ytffmpeg was designed to be simple enough to get started and making videos quickly, but also allow for the depth and complexity one may desire or need from more advanced operations. By having the full power of ffmpeg at your fingertips, but not necessarily requiring to learn all of the filters available in ffmpeg, let alone the chain of filters you sometimes have to put together because you changed one property of a video snippet. For example, having to reset the presentation timestamp of a snippet before concatenating a few streams together, or resetting the sample aspect ratio after scaling or cropping content. If that sounds complicated, don't worry -- ytffmpeg will take the rough edges off for you in due time with its simple configuration, I plan to make data structures take the place of the complex filter graphs to help you better visualize the results of your project.


Install your own DNS Server

I want to do a series on "rolling your own" and how you can use open-source software for just about all your needs. In this way, you can learn about how some software architectures work under the hood, how to configure, how to research and understand what is needed in order to get something like this setup and running. If you're like me, you're probably on a time-budget, so I won't delay, let's get right into it.

Install bind9

Let's start with the software required. If you are starting from a bare headless linux install like a Docker container or a fresh image, there may be a few things to install like your favorite text editor since we will be editing files. If you don't know of a text editor in Linux, you can use nano (yes, I probably just infuriated a third of you -- I can already see you in the comments section). I like it because it's simple and key-combination based, rather than arcane spell based as far as the navigation is concerned, but remember: it's all about preference and what works for you.

You can install bind9 with the following command (as of Debian Bookworm / Devuan Daedalus):

sudo apt-get install bind9 bind9-host bind9-utils bind9-dnsutils


Once you have the service installed, it will be ready for you to configure. Let's checkout /etc/bind/:

$ tree -Ca /etc/bind 
|-- bind.keys
|-- db.0
|-- db.127
|-- db.255
|-- db.empty
|-- db.local
|-- named.conf
|-- named.conf.default-zones
|-- named.conf.local
|-- named.conf.options
|-- rndc.key
`-- zones.rfc1918

0 directories, 12 files

In this directory, we see the configuration for named (I pronounce it "name-dee") which is the underlying name of the service. There's the root configuration, which is just an include statement to the other configuration files as named.conf.options, named.conf.local and named.conf.default-zones. Let's checkout named.conf.options:

$ cat /etc/bind/named.conf.options 
options {
	directory "/var/cache/bind";

	// If there is a firewall between you and nameservers you want
	// to talk to, you may need to fix the firewall to allow multiple
	// ports to talk.  See http://www.kb.cert.org/vuls/id/800113

	// If your ISP provided one or more IP addresses for stable 
	// nameservers, you probably want to use them as forwarders.  
	// Uncomment the following block, and insert the addresses replacing 
	// the all-0's placeholder.

	// forwarders {
	// };

	// If BIND logs error messages about the root key being expired,
	// you will need to update your keys.  See https://www.isc.org/bind-keys
	dnssec-validation auto;

	listen-on-v6 { any; };

In this file, I would just uncomment the forwarders{} section and replace with a DNS server I can trust to send my queries against. You can include multiple addresses here, one to each their own line and separated by a semicolon. Here's the above updated the way I would configure as such:

$ cat /etc/bind/named.conf.options 
options {
	directory "/var/cache/bind";

	forwarders {;;

	dnssec-validation auto;

	listen-on-v6 { any; };

In this way, this named instance will use those IP addresses for DNS queries it cannot answer. Next, let's checkout named.conf.local:

// Do any local configuration here

// Consider adding the 1918 zones here, if they are not used in your
// organization
//include "/etc/bind/zones.rfc1918";

So, in this file, I would just scrap the comments and create my custom zone as I wanted to control it like so:

zone "markizano.net" {
  type master;
  file "/etc/bind/markizano.net.zone";
  allow-query { any; };

You can put whatever zone you want here. It won't be recognized by the broader Internet, but in your local network, it works great! All devices you point to this DNS server will get the addresses you control and set here! This configuration will create a zone we control in our DNS server and the target file in /etc/bind/markizano.net we will create that will contain the zone records for this domain. If you find yourself managing multiple domains, I find it easier to place these configurations in a subdirectory.

Domain Configuration

Now that we have our base server configuration in place, it's time to configure our domain! Let's setup a few essential records in /etc/bind/markizano.net.zone:

; ##### Markizano.NET
$TTL    600
@       IN      SOA     markizano.net. root.markizano.net. (
                     2024021517 ; Serial
                         604800 ; Refresh
                          86400 ; Retry
                        2419200 ; Expire
                           600) ; Negative Cache TTL

; ### Main Root DB and A records
@                           IN  A
@                           IN  AAAA    fe80::01

@                           IN  NS      ns1
@                           IN  NS      ns2

ns1							IN	A
ns2							IN	A

The initial $TTL 600 tells the default timeout for the root SOA or "Source Of Address". A Zone must have a root A record, so that is provided as It also helps to have NS or "Name Space" records, so those are defined as "ns1" and "ns1" for "ns1.markizano.net" and "ns2.markizano.net".

Fun tip: Domain records that end with a trailing dot "." are the actual TLD or "Top-Level Domain", so you might sometimes see ns1.markizano.net..

Check Configuration

Before we restart the service, we can check the syntax of our configuration to ensure it's all correct. This avoids failures on restart. Let's use the named-checkconf command to check the configuration. This command should output nothing if there is no issues and return 0 in its exit code. If there are errors with your configuration, it should print where there is an error and you can correct that.

You can check the zones configuration file with named-checkzone like so:

# named-checkzone markizano.net /etc/bind/markizano.net.zone
zone markizano.net/IN: loaded serial 2024021517

Once you get the OK from these commands, you should be good to proceed!

Restart Service

The next step after all the configuration is in place is to restart the service so the configuration is loaded into the daemon to be served up! Once the service is restarted, you can query against it to find out if your records are working!

$ sudo service named restart

Querying against the DNS server is as easy as nslookup, host, or dig. Let's use host:

$ host -d markizano.net
Trying "markizano.net"
Using domain server:

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 27155
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;markizano.net.			IN	A

markizano.net.		600	IN	A

Received 47 bytes from in 0 ms
Trying "markizano.net"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57057
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;markizano.net.			IN	AAAA

markizano.net.		600	IN	AAAA	fe80::1

Received 59 bytes from in 0 ms
Trying "markizano.net"
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41693
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0

;markizano.net.			IN	MX

markizano.net.		600	IN	SOA	markizano.net. root.markizano.net. 2024021517 604800 86400 2419200 600

Received 72 bytes from in 0 ms

and Boom! You now have a fully functional DNS server that you control! Congratulations! If you want your system to use this by default, simply update /etc/resolv.conf, make sure this entry is first in this file:


Or whatever the IP address is of the host running your DNS service in your environment. That's how you roll your own 😎

If you like tutorials on CloudOps/DevOps stuff, feel free to subscribe to this or any of my socials! I have a lot of work to catch up on!!!
Drop a comment if you would like another post on how to secure and harden your configuration to have a DNS server face the public.


I Deleted my TikToks 😱

Yes, it's true. I suppose I should address this somewhere and my blog being the target of where my TikTok's pointed should be a good place to address it, right?

My Experience with TikTok

Let's first address the fact that TikTok is wildly different about the videos it shows you from the time you login to every action it can track about you. Based on my experience, watch time is the most important, then comments, then likes, then shares, then favorites and any other interactions with the app. I understand I deleted about 2 years of historic analytics data, but let's face it: TikTok's analytics retention period is terribad. I would like to see more support (even if you have to charge the user for storage) around analytics retention periods.

Why I Deleted My Accounts?

The straw that broke the camels back was an experience I had where I was arguing with someone over some situation they had going on. In trying to provide motivating energy as I often find myself doing, this person seemed pretty deep in their situation and probably could use a little cheerleading to help them find their way out of it. Seeing their depression, it was then, I realized what they meant by mental health issues and the usage of the social media platforms. It was then, I understood just how depressing a place this can be, alone in front of the camera. Ultimately, the end-user is the one that should be knowledgeable enough to know when it's time to put the app down, but that hit of dopamine of seeing something amazing if you just swipe one more time is the real saturation point for the app. I had to put it down. Somewhere in all that swyping was a subliminal message being planted in my brain: You are going to die of late stage capitalism and there's absolutely nothing you can do about it.

I refuse to accept this. I refuse to live in a world where I am ruled by my fear that's keeping me from achieving the goals in life that I need to accomplish. Since putting the app down, I've noticed a change in my behaviour and how much of my time I have available to me again. I am happy to see the use of that time being invested in things that will serve my future instead of waste my present. I'm studying again. I'm reading again. I am being conscious of what I feed my mind and consume and it's starting to have immediate effects. I may make another post about my situation in some months to checkin and see how things are going but for now, I'm happy to be in a happier place and contributing to something greater than myself that benefits the greater society.

Live with Purpose and Intention

With this decision, this is yet another step in a greater execution I have in my life function and that is to live with purpose and intention. I refuse to be just another corporate slave statistic to add to the pile. I plan on taking advantage of my gifts to their fullest capacity. This means taking executive priority over my time and investment of my time since it is our most precious resource. Going forward, I will no longer mindlessly consume content from the app until I can develop a healthy framework around its interaction and have a better sense of what it means for me. Until then, I will post-only to the account and respond to engagements in the comments or messages to me. I will allow TikTok to continue to be a communication point for those that wish to maintain that line.

Since putting the app down, I find myself reading and writing more. I provide higher quality work to my job. I have more time to deep dive into code and explore new software. I spend less time wallowing in a silent argument that happened earlier today or anger over a moment that isn't Now. I'm grateful for this.

So, @markizano.draconus and @KizanosMusings have been deleted in favor of @Kizanos.FinTech. This will be my professional account where I can share vertical education content on IT and DevOps. I want to also learn more and explore about ActivityPub, PeerTube, the Fediverse and Mastadon as well.