<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Knowledge Base (Posts about ffmpeg)</title><link>https://bgstack15.ddns.net/blog/</link><description></description><atom:link href="https://bgstack15.ddns.net/blog/categories/ffmpeg.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2024 &lt;a href="mailto:bgstack15@gmail.com"&gt;bgstack15&lt;/a&gt; 
&lt;a rel="license" href="https://creativecommons.org/licenses/by-sa/4.0/"&gt;
&lt;img alt="Creative Commons License BY-SA"
style="border-width:0; margin-bottom:12px;"
src="https://bgstack15.ddns.net/.images/l_by-sa_4.0_88x31.png"&gt;&lt;/a&gt;</copyright><lastBuildDate>Wed, 06 Mar 2024 14:00:36 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Split mkv file on chapters</title><link>https://bgstack15.ddns.net/blog/posts/2024/03/06/split-mkv-file-on-chapters/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;To split a large mkv file into a file for each chapter, run the output of this command.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/files/2024/listings/split-on-chapters.sh.html"&gt;files/2024/listings/split-on-chapters.sh&lt;/a&gt;  &lt;a href="https://bgstack15.ddns.net/blog/files/2024/listings/split-on-chapters.sh"&gt;(Source)&lt;/a&gt;&lt;/p&gt;&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;
&lt;span class="normal"&gt;15&lt;/span&gt;
&lt;span class="normal"&gt;16&lt;/span&gt;
&lt;span class="normal"&gt;17&lt;/span&gt;
&lt;span class="normal"&gt;18&lt;/span&gt;
&lt;span class="normal"&gt;19&lt;/span&gt;
&lt;span class="normal"&gt;20&lt;/span&gt;
&lt;span class="normal"&gt;21&lt;/span&gt;
&lt;span class="normal"&gt;22&lt;/span&gt;
&lt;span class="normal"&gt;23&lt;/span&gt;
&lt;span class="normal"&gt;24&lt;/span&gt;
&lt;span class="normal"&gt;25&lt;/span&gt;
&lt;span class="normal"&gt;26&lt;/span&gt;
&lt;span class="normal"&gt;27&lt;/span&gt;
&lt;span class="normal"&gt;28&lt;/span&gt;
&lt;span class="normal"&gt;29&lt;/span&gt;
&lt;span class="normal"&gt;30&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="c1"&gt;# File: split-on-chapters.sh&lt;/span&gt;
&lt;span class="c1"&gt;# Location: /mnt/public/Support/Programs/DVDs&lt;/span&gt;
&lt;span class="c1"&gt;# Author: bgstack15&lt;/span&gt;
&lt;span class="c1"&gt;# Startdate: 2024-02-17-7 14:22&lt;/span&gt;
&lt;span class="c1"&gt;# Title: Split mkv on chapters&lt;/span&gt;
&lt;span class="c1"&gt;# Purpose: oneliner for splitting mkv file into separate files per chapter&lt;/span&gt;
&lt;span class="c1"&gt;# History:&lt;/span&gt;
&lt;span class="c1"&gt;#    2024-02-22 moved -ss and -to before -i&lt;/span&gt;
&lt;span class="c1"&gt;# Usage:&lt;/span&gt;
&lt;span class="c1"&gt;# Reference:&lt;/span&gt;
&lt;span class="c1"&gt;#    man ffmpeg&lt;/span&gt;
&lt;span class="c1"&gt;#    slightly improved over https://superuser.com/questions/795373/split-mkv-based-on-chapters&lt;/span&gt;
&lt;span class="c1"&gt;#    https://superuser.com/questions/795373/split-mkv-based-on-chapters/1830690#1830690&lt;/span&gt;
&lt;span class="c1"&gt;#    https://stackoverflow.com/questions/14005110/how-to-split-a-video-using-ffmpeg-so-that-each-chunk-starts-with-a-key-frame/33188399#33188399&lt;/span&gt;
&lt;span class="c1"&gt;# Improve:&lt;/span&gt;
&lt;span class="c1"&gt;# Dependencies:&lt;/span&gt;
&lt;span class="c1"&gt;# Documentation:&lt;/span&gt;
&lt;span class="c1"&gt;#    This is insufficient:&lt;/span&gt;
&lt;span class="c1"&gt;#       HandBrakeCLI -c 2 -i twoeps.mkv -o 2.mkv # this does not get subtitles, and reencodes which takes a while&lt;/span&gt;
&lt;span class="c1"&gt;#   WARNING! Jellyfin+chromecast might malfunction on a video split in this manner, within the first few seconds of playback, because of the keyframe/chapter mismatch.&lt;/span&gt;

split_by_chapter&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;for&lt;/span&gt; word &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;do&lt;/span&gt;
      ffmpeg -i &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;word&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sed -n -r -e &lt;span class="s2"&gt;"/start.*end.*[0-9]*/{s/.*#[0-9]*:([0-9]*).* ([0-9]*\.[0-9]*).*( [0-9]*\.[0-9]*)/ffmpeg -ss \2 -to\3 -i &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;word&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; -acodec copy -vcodec copy -scodec copy &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;word&lt;/span&gt;&lt;span class="p"&gt;%%.mkv&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;-chapter\1.mkv \;/g;p;}"&lt;/span&gt;
   &lt;span class="k"&gt;done&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

split_by_chapter &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;So:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;$( ./split-on-chapters.sh twoepisodes.mkv )
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Splitting a video file can get weird with &lt;code&gt;-codec copy&lt;/code&gt; and &lt;code&gt;-ss&lt;/code&gt;. If you stream at the beginning of a file split in this manner, it might never start displaying the video. There might be some way to split "correctly" by dealing with the key frames, but I spent maybe 30 minutes and couldn't figure it out. I'll just live with the consequences, of waiting a few seconds before chromecasting a split video file from Jellyfin on an android device.&lt;/p&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;h3&gt;Man pages&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/linux.die.net/man/1/ffmpeg"&gt;man ffmpeg&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Web links&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;slightly improved over &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/superuser.com/questions/795373/split-mkv-based-on-chapters"&gt;video - Split MKV based on Chapters - Super User&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/superuser.com/questions/795373/split-mkv-based-on-chapters/1830690#1830690"&gt;video - Split MKV based on Chapters - Super User#1830690&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/stackoverflow.com/questions/14005110/how-to-split-a-video-using-ffmpeg-so-that-each-chunk-starts-with-a-key-frame/33188399#33188399"&gt;How to split a video using FFMPEG so that each chunk starts with a key frame? - Stack Overflow&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;</description><category>ffmpeg</category><category>mkv</category><category>oneliner</category><guid>https://bgstack15.ddns.net/blog/posts/2024/03/06/split-mkv-file-on-chapters/</guid><pubDate>Wed, 06 Mar 2024 13:51:47 GMT</pubDate></item><item><title>Find average volume change needed for album</title><link>https://bgstack15.ddns.net/blog/posts/2023/08/19/find-average-volume-change-needed-for-album/</link><dc:creator>bgstack15</dc:creator><description>&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;x=0 ; for word in *.mp3 ; do x=$((x+1)) ; ffmpeg -i "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" -af "volumedetect" -vn -sn -dn -f null /dev/null 2&amp;gt;&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;1 | awk "BEGIN{OFS=\",\"} /mean_volume/{a=\$5} /max_volume/{b=\$5} END{print a,b}" | sed -r -e "s/^/&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;,/;" ; done
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And then I saw the whole list of max and mean volumes. So my minimum max_volume is &lt;code&gt;-8.3&lt;/code&gt;, so I need to add this amount to each file. I think ffmpeg does not use fractional decibels, so I chose 9.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;x=0 ; time for word in *.mp3 ; do x=$((x+1)) ; new="new&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" ; ffmpeg -i "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" -af "volume=9dB" "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" ; done
&lt;/pre&gt;&lt;/div&gt;</description><category>audio</category><category>ffmpeg</category><category>mp3</category><category>music</category><category>volume</category><guid>https://bgstack15.ddns.net/blog/posts/2023/08/19/find-average-volume-change-needed-for-album/</guid><pubDate>Sat, 19 Aug 2023 12:36:19 GMT</pubDate></item><item><title>Installing ffmpeg &gt;=4 on CentOS 7 for Jellyfin</title><link>https://bgstack15.ddns.net/blog/posts/2023/03/09/installing-ffmpeg-4-on-centos-7-for-jellyfin/</link><dc:creator>bgstack15</dc:creator><description>&lt;h2&gt;tl;dr&lt;/h2&gt;
&lt;p&gt;Fetched ffmpeg &lt;a href="https://github.com/PhantomX/chinforpms/tree/main/_pasture/ffmpeg"&gt;spec from Chinforpms pasture&lt;/a&gt;, fixed some rpm macros, compiled it, and installed it.&lt;/p&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;I use &lt;a href="https://jellyfin.org/"&gt;Jellyfin server&lt;/a&gt; on CentOS 7, which I install from a local yum repository after downloading the correct files from the &lt;a href="https://repo.jellyfin.org/releases/server/"&gt;upstream page&lt;/a&gt;. I recently upgraded from 10.7.6 to 10.8.9 and media playback broke for almost all video content.&lt;/p&gt;
&lt;h2&gt;The start&lt;/h2&gt;
&lt;p&gt;To start the process, I made a backup of the data after stopping jellyfin.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="c1"&gt;# systemctl stop jellyfin&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="c1"&gt;# tar -C /var/lib -zcf /tmp/jellyfin.$( date "+%F" ).$( rpm -qf ).tgz jellyfin&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then I yum updated and started jellyfin.&lt;/p&gt;
&lt;p&gt;The problem was indicated in the server logs (&lt;code&gt;journalctl -n500 -f -u jellyfin&lt;/code&gt;): Jellyfin needs the path set for ffmpeg. That's slightly believable. I ensured I had &lt;code&gt;/usr/bin/ffmpeg&lt;/code&gt;, and set that as the path in the web admin console, but the web ui indicated it could not find ffmpeg. The server logs indicated specifically that it could not find ffmpeg 4, so it was a version problem. I realize CentOS 7 is now 9 years old; vm4's hardware RAID controller does not have a driver for the Linux kernel used by RHEL8 and above, at least at the time I installed that system.&lt;/p&gt;
&lt;h2&gt;The search&lt;/h2&gt;
&lt;p&gt;Turns out &lt;a href="https://rpmfusion.org/"&gt;rpmfusion&lt;/a&gt; only has ffmpeg &lt;a href="https://mirror.fcix.net/rpmfusion/free/el/updates/7/x86_64/repoview/ffmpeg.html"&gt;version 3&lt;/a&gt;. I spent time looking for a way to get ffmpeg &amp;gt;= 4 on CentOS 7. I first investigated the famous &lt;a href="https://negativo17.org/repositories/"&gt;negativo17 repository&lt;/a&gt;. I have used it in the past, with minor problems as some of the packages want to own the same files from other packages in the OS. negativo17's "epel-multimedia" repository has ffmpeg 5 in it!&lt;/p&gt;
&lt;p&gt;I wanted to find another way to get ffmpeg without having to use that repository, if I could. I can use that repository if I have to. I checked another Fedora custom repackager that I follow, &lt;a href="https://github.com/PhantomX/chinforpms/"&gt;PhantomX&lt;/a&gt;, who did indeed package ffmpeg in the past! In fact, PhantomX had stopped about 3 years ago at version 4.2.2, which was perfect! &lt;a href="https://github.com/PhantomX/chinforpms/blob/main/_pasture/ffmpeg/ffmpeg.spec"&gt;This spec file&lt;/a&gt; needed only minor adjustments for rpm macros that do not exist in the version of rpm in CentOS 7 (PhantomX targets Fedora, and 3 years ago would have been Fedora 32 approximately), and thankfully all the dependencies were in rpmfusion or the base repositories.&lt;/p&gt;
&lt;p&gt;So I manually built this ffmpeg 4 rpm on a CentOS 7 build node (I needed  too), and then deployed the files to my local yum repository, and ran &lt;code&gt;yum upgrade ffmpeg&lt;/code&gt;. And then I could set the path to the program in the Jellyfin web ui, and then my users can view videos again!&lt;/p&gt;
&lt;h2&gt;Details of spec file changes&lt;/h2&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="s s-Atom"&gt;---&lt;/span&gt; &lt;span class="s s-Atom"&gt;ffmpeg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="s s-Atom"&gt;spec&lt;/span&gt; &lt;span class="mi"&gt;2023&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;22.250386837&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0500&lt;/span&gt;
&lt;span class="s s-Atom"&gt;+++&lt;/span&gt; &lt;span class="s s-Atom"&gt;ffmpeg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="s s-Atom"&gt;spec&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="s s-Atom"&gt;new&lt;/span&gt; &lt;span class="mi"&gt;2023&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mf"&gt;15.043571569&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0500&lt;/span&gt;
&lt;span class="s s-Atom"&gt;@@&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="s s-Atom"&gt;@@&lt;/span&gt;
 &lt;span class="s s-Atom"&gt;#global&lt;/span&gt; &lt;span class="s s-Atom"&gt;date&lt;/span&gt;    &lt;span class="mi"&gt;20180419&lt;/span&gt;
 &lt;span class="s s-Atom"&gt;#global&lt;/span&gt; &lt;span class="s s-Atom"&gt;rel&lt;/span&gt;     &lt;span class="s s-Atom"&gt;rc1&lt;/span&gt;

&lt;span class="s s-Atom"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;%define ldconfig_post(n:)  %{?ldconfig:%post -p %ldconfig %{?*} %{-n:-n %{-n*}}&lt;/span&gt;
&lt;span class="s s-Atom"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;%end}&lt;/span&gt;
&lt;span class="s s-Atom"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;%define ldconfig_postun(n:)   %{?ldconfig:%postun -p %ldconfig %{?*} %{-n:-n %{-n*}}&lt;/span&gt;
&lt;span class="s s-Atom"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;%end}&lt;/span&gt;
&lt;span class="s s-Atom"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;%define ldconfig_scriptlets(n:)  %{?ldconfig:&lt;/span&gt;
&lt;span class="s s-Atom"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;%ldconfig_post %{?*} %{-n:-n %{-n*}}&lt;/span&gt;
&lt;span class="s s-Atom"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;%ldconfig_postun %{?*} %{-n:-n %{-n*}}&lt;/span&gt;
&lt;span class="s s-Atom"&gt;+&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;
 &lt;span class="s s-Atom"&gt;#&lt;/span&gt; &lt;span class="nv"&gt;Cuda&lt;/span&gt; &lt;span class="s s-Atom"&gt;and&lt;/span&gt; &lt;span class="s s-Atom"&gt;others&lt;/span&gt; &lt;span class="s s-Atom"&gt;are&lt;/span&gt; &lt;span class="s s-Atom"&gt;only&lt;/span&gt; &lt;span class="s s-Atom"&gt;available&lt;/span&gt; &lt;span class="s s-Atom"&gt;on&lt;/span&gt; &lt;span class="s s-Atom"&gt;some&lt;/span&gt; &lt;span class="s s-Atom"&gt;arches&lt;/span&gt;
 &lt;span class="c1"&gt;%global cuda_arches x86_64&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Probably eventually, I will need ffmpeg 5. Perhaps I just won't update Jellyfin again. It does exactly what I want already, and upgrading it now didn't even make anything better.&lt;/p&gt;
&lt;h2&gt;Additional thoughts&lt;/h2&gt;
&lt;p&gt;I needed to update my webhook template for new field names. Oh, and the app server needed to be restarted a few times to iterate through fetching the newer version of the webhook plugin, and enabling it, and using it, but it was painless.&lt;/p&gt;
&lt;h2&gt;Related files&lt;/h2&gt;
&lt;p&gt;All srpms and rpms in &lt;code&gt;/mnt/public/www/internal/repo/rpm/jellyfin-ffmpeg/&lt;/code&gt;.&lt;/p&gt;</description><category>centos</category><category>ffmpeg</category><category>jellyfin</category><category>narrative</category><category>packaging</category><guid>https://bgstack15.ddns.net/blog/posts/2023/03/09/installing-ffmpeg-4-on-centos-7-for-jellyfin/</guid><pubDate>Thu, 09 Mar 2023 13:37:07 GMT</pubDate></item><item><title>Split single mp3 of whole CD</title><link>https://bgstack15.ddns.net/blog/posts/2022/12/31/split-single-mp3-of-whole-cd/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;I had a single mp3 recording of an entire CD that I wished to split into the individual tracks. Thankfully, people smarter than me have already solved this problem on the Internet.&lt;/p&gt;
&lt;p&gt;The first order of business was to find the track times. Thankfully, &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/musicbrainz.org/"&gt;musicbrainz.org&lt;/a&gt; delivered TOC info. It looks like &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/musicbrainz.org/cdtoc/qOlvPZaSYJmwaW7Ds39icSnBr88-"&gt;this&lt;/a&gt; but I wasn't able to figure how to download a cddb-style TOC file, but that's OK. I used Firefox's CTRL+click-and-drag functionality to select just a column of the start times of the tracks, and pasted them in a file.&lt;/p&gt;
&lt;p&gt;I ended up having to subtract lots of seconds, because my recording was somehow skewed. I also remember that ffmpeg can only be so precise with seconds (due to how compression works?) so that affected things to. So my track times ended up a little different than the TOC I used.&lt;/p&gt;
&lt;p&gt;File &lt;code&gt;./times&lt;/code&gt;&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;21&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;04&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;08&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;22&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;53&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;52&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;29&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;58&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;03&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;39&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;54&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;53&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;58&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;span class="mi"&gt;01&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;44&lt;/span&gt;&lt;span class="w"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Notice how I had to add the end time of the last track! Armed with these times, I used a small script from &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/unix.stackexchange.com/questions/659789/automating-the-splitting-of-a-large-mp3-file-with-ffmpeg-into-multiple-files-in"&gt;Unix.SE&lt;/a&gt;, of course.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://bgstack15.ddns.net/blog/files/2022/12/listings/split.sh.html"&gt;split.sh&lt;/a&gt;  &lt;a href="https://bgstack15.ddns.net/blog/files/2022/12/listings/split.sh"&gt;(Source)&lt;/a&gt;&lt;/p&gt;&lt;div class="highlight"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;div class="linenodiv"&gt;&lt;pre&gt;&lt;span class="normal"&gt; 1&lt;/span&gt;
&lt;span class="normal"&gt; 2&lt;/span&gt;
&lt;span class="normal"&gt; 3&lt;/span&gt;
&lt;span class="normal"&gt; 4&lt;/span&gt;
&lt;span class="normal"&gt; 5&lt;/span&gt;
&lt;span class="normal"&gt; 6&lt;/span&gt;
&lt;span class="normal"&gt; 7&lt;/span&gt;
&lt;span class="normal"&gt; 8&lt;/span&gt;
&lt;span class="normal"&gt; 9&lt;/span&gt;
&lt;span class="normal"&gt;10&lt;/span&gt;
&lt;span class="normal"&gt;11&lt;/span&gt;
&lt;span class="normal"&gt;12&lt;/span&gt;
&lt;span class="normal"&gt;13&lt;/span&gt;
&lt;span class="normal"&gt;14&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c1"&gt;# Adapted from https://unix.stackexchange.com/questions/659789/automating-the-splitting-of-a-large-mp3-file-with-ffmpeg-into-multiple-files-in&lt;/span&gt;
&lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"00:00:00"&lt;/span&gt;
&lt;span class="nv"&gt;z&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="nv"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;basename -- &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;ext&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;##*.&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;filename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;%.*&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;initcmd&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"ffmpeg  -nostdin -hide_banner -loglevel error -i &lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="nb"&gt;read&lt;/span&gt; y &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
   &lt;span class="nv"&gt;initcmd&lt;/span&gt;&lt;span class="o"&gt;+=&lt;/span&gt;&lt;span class="s2"&gt;" -ss &lt;/span&gt;&lt;span class="nv"&gt;$x&lt;/span&gt;&lt;span class="s2"&gt; -to &lt;/span&gt;&lt;span class="nv"&gt;$y&lt;/span&gt;&lt;span class="s2"&gt; -c copy &lt;/span&gt;&lt;span class="nv"&gt;$filename$z&lt;/span&gt;&lt;span class="s2"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$ext&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
   &lt;span class="nb"&gt;let&lt;/span&gt; &lt;span class="s2"&gt;"z=z+1"&lt;/span&gt;
   &lt;span class="nv"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$y&lt;/span&gt; 
&lt;span class="k"&gt;done&lt;/span&gt; &amp;lt; &lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;initcmd&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Then I ran the script:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;./split.sh ./times album.mp3
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;I had to subtract lots of seconds, smeared across the whole track. I suspect the whole recording was the tiniest bit fast, but I also remember that ffmpeg plays fast and loose with relative time specifications. &lt;/p&gt;
&lt;p&gt;But now, I had an mp3 file for each track! Then I used puddletag and its "Tag Sources" window to load the musicbrainz information for these songs.&lt;/p&gt;</description><category>ffmpeg</category><category>metadata</category><category>mp3</category><guid>https://bgstack15.ddns.net/blog/posts/2022/12/31/split-single-mp3-of-whole-cd/</guid><pubDate>Sat, 31 Dec 2022 13:35:19 GMT</pubDate></item><item><title>Manually fix volume in mp3 file</title><link>https://bgstack15.ddns.net/blog/posts/2018/08/25/manually-fix-volume-in-mp3-file/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;I am shamelessly ripping off a superuser answer: &lt;a href="https://superuser.com/questions/323119/how-can-i-normalize-audio-using-ffmpeg/323127#323127"&gt;How can I normalize audio
using ffmpeg?&lt;/a&gt;.&lt;/p&gt;
&lt;h6&gt;Option 3: Manually normalizing audio with &lt;code&gt;ffmpeg&lt;/code&gt;&lt;/h6&gt;
&lt;p&gt;In ffmpeg you can use the &lt;code&gt;volume&lt;/code&gt; filter to change the volume of a track.
Make sure you &lt;a href="http://ffmpeg.org/download.html"&gt;download a recent version&lt;/a&gt; of
the program. This guide is for &lt;em&gt;peak&lt;/em&gt; normalization, meaning that it will make
the loudest part in the file sit at 0 dB instead of something lower. There is
also RMS-based normalization which tries to make the &lt;em&gt;average&lt;/em&gt; loudness the
same across multiple files. To do that, do not try to push the maximum volume
to 0 dB, but the mean volume to the dB level of choice (e.g. -26 dB).&lt;/p&gt;
&lt;h6&gt;Find out the gain to apply&lt;/h6&gt;
&lt;p&gt;First you need to analyze the audio stream for the maximum volume to see if
normalizing would even pay off:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ffmpeg -i video.avi -af "volumedetect" -vn -sn -dn -f null /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Replace &lt;code&gt;/dev/null&lt;/code&gt; with &lt;code&gt;NUL&lt;/code&gt; on Windows. The
&lt;a href="https://ffmpeg.org/ffmpeg.html#Stream-selection"&gt;&lt;code&gt;-vn&lt;/code&gt;&lt;/a&gt;,
&lt;a href="https://ffmpeg.org/ffmpeg.html#Stream-selection"&gt;&lt;code&gt;-sn&lt;/code&gt;&lt;/a&gt;, and
&lt;a href="https://ffmpeg.org/ffmpeg.html#Stream-selection"&gt;&lt;code&gt;-dn&lt;/code&gt;&lt;/a&gt; arguments instruct
ffmpeg to ignore non-audio streams during this analysis. This drastically
speeds up the analysis. This will output something like the following:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;[Parsed_volumedetect_0 @ 0x7f8ba1c121a0] mean_volume: -16.0 dB
[Parsed_volumedetect_0 @ 0x7f8ba1c121a0] max_volume: -5.0 dB
[Parsed_volumedetect_0 @ 0x7f8ba1c121a0] histogram_0db: 87861
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see, our maximum volume is -5.0 dB, so we can apply 5 dB gain. If
you get a value of 0 dB, then you don't need to normalize the audio.&lt;/p&gt;
&lt;h6&gt;Apply the volume filter:&lt;/h6&gt;
&lt;p&gt;Now we apply the &lt;a href="http://ffmpeg.org/ffmpeg-filters.html#volume"&gt;&lt;code&gt;volume&lt;/code&gt; filter&lt;/a&gt; to an audio file. Note that applying the filter means we
will have to re-encode the audio stream. What codec you want for audio depends
on the original format, of course. Here are some examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Plain audio file:&lt;/strong&gt; Just encode the file with whatever encoder you need: &lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;ffmpeg -i input.wav -af "volume=5dB" output.mp3
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Your options are very broad, of course.&lt;/p&gt;</description><category>audio</category><category>ffmpeg</category><category>mp3</category><guid>https://bgstack15.ddns.net/blog/posts/2018/08/25/manually-fix-volume-in-mp3-file/</guid><pubDate>Sat, 25 Aug 2018 13:01:05 GMT</pubDate></item><item><title>Install ffmpeg on devuan</title><link>https://bgstack15.ddns.net/blog/posts/2017/10/20/install-ffmpeg-on-devuan/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;If you want to use ffmpeg on devuan (I want to convert mp4 files to mp3), you
should use utility avconv from package libav-tools.&lt;/p&gt;
&lt;h2&gt;References&lt;/h2&gt;
&lt;h3&gt;Weblinks&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://superuser.com/questions/286675/how-to-install-ffmpeg-on-debian/865744#865744"&gt;https://superuser.com/questions/286675/how-to-install-ffmpeg-on-debian/865744#865744&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Interesting discussion about the politics behind libav and ffmpeg and so on &lt;a href="https://hardforum.com/threads/the-dark-side-of-foss.1947261/"&gt;https://hardforum.com/threads/the-dark-side-of-foss.1947261/&lt;/a&gt; &lt;/li&gt;
&lt;/ol&gt;</description><category>devuan</category><category>ffmpeg</category><category>mp3</category><category>mp4</category><guid>https://bgstack15.ddns.net/blog/posts/2017/10/20/install-ffmpeg-on-devuan/</guid><pubDate>Fri, 20 Oct 2017 17:35:12 GMT</pubDate></item></channel></rss>