This commit is contained in:
Joshua Seigler 2025-06-28 02:14:29 -04:00
parent 378ffd22df
commit 49092fb0df
380 changed files with 100 additions and 13608 deletions

View file

@ -1,162 +1,4 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, viewport-fit=cover"
/>
<link rel="stylesheet" href="/site.css?v=88202782cebe" />
<style>
/* inter-latin-wght-normal */
@font-face {
font-family: "Inter Variable";
font-style: normal;
font-display: swap;
font-weight: 100 900;
src: url(/fonts/inter-latin-wght-normal.woff2)
format("woff2-variations");
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
U+2212, U+2215, U+FEFF, U+FFFD;
} /* inter-latin-wght-italic */
@font-face {
font-family: "Inter Variable";
font-style: italic;
font-display: swap;
font-weight: 100 900;
src: url(/fonts/inter-latin-wght-italic.woff2)
format("woff2-variations");
unicode-range:
U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
U+2212, U+2215, U+FEFF, U+FFFD;
}
</style>
<script
defer
src="https://stats.apps.seigler.net/script.js"
data-website-id="ccb4bd94-2a71-47fe-8eea-d85bf75b7f6d"
></script>
<script defer src="/scripts/effects.js?v=d86d3b7642f1"></script>
<link rel="me" href="https://github.com/seigler" />
<link
rel="webmention"
href="https://webmention.io/joshua.seigler.net/webmention"
/>
<title>FFmpeg audio cleanup - joshua.seigler.net</title>
<meta
name="description"
content="A script to apply dynamic compression and noise reduction to audio files"
/>
<meta name="keywords" content="posts, technical, ffmpeg" />
<meta property="og:title" content="FFmpeg audio cleanup" />
<meta property="og:type" content="" />
<meta
property="og:url"
content="https://joshua.seigler.net/posts/ffmpeg-audio-cleanup/"
/>
<meta name="twitter:title" content="FFmpeg audio cleanup" />
<meta
name="twitter:description"
content="A script to apply dynamic compression and noise reduction to audio files"
/>
<meta name="twitter:card" content="summary" />
<meta name="generator" content="Eleventy v3.1.0" />
</head>
<body data-font="english" data-path="/posts/ffmpeg-audio-cleanup/">
<header>
<nav>
<div class="nav-row">
<div class="nav-home"><a href="/">joshua.seigler.net</a></div>
</div>
<div class="nav-categories">
<a class="nav-active" href="/posts/">/posts</a>
<a class="" href="/about/">/about</a>
<a class="" href="/now/">/now</a>
<a class="" href="/uses/">/uses</a>
<a class="" href="/recipes/">/recipes</a>
<a class="" href="/music/">/music</a>
<a class="" href="/books/">/books</a>
<a class="" href="/links/">/links</a>
<a class="" href="/search/">/search</a>
</div>
</nav>
<h1>FFmpeg audio cleanup</h1>
<div class="header-meta">
<author>Joshua Seigler</author><date>June 26, 2025</date>
<span class="tags" style="--totalTags: 11"
><a class="tag" style="--tagIndex: 5" href="/tags/technical"
>technical</a
>
<a class="tag" style="--tagIndex: 10" href="/tags/ffmpeg">ffmpeg</a>
</span>
</div>
</header>
<header class="toc"></header>
<main data-pagefind-body="data-pagefind-body">
<p>
I recently needed to process 20+ phone audio recordings. The files are
mp3 recordings in stereo, made in an environment with echoes and noise
from fans/heaters.
</p>
<p>
Although I could do it easily with
<a href="https://tenacityaudio.org/" target="_blank" rel="noopener"
>Tenacity</a
>
I didnt want to use a manual process, since it would take days. So I
tried using FFmpeg filters and Bash scripting.
</p>
<p>
I found an FFmpeg filter called
<a
href="https://ffmpeg.org/ffmpeg-filters.html#compand"
target="_blank"
rel="noopener"
>compand</a
>
which lets you map an input decibel range to an output decibel range. I
also used the
<a
href="https://ffmpeg.org/ffmpeg-filters.html#anlmdn"
target="_blank"
rel="noopener"
>anlmdn</a
>
filter to reduce noise, and the
<a
href="https://ffmpeg.org/ffmpeg-filters.html#highpass"
target="_blank"
rel="noopener"
>highpass</a
>
filter to help with clarity.
</p>
<p>I ran into a couple gotchas.</p>
<ol>
<li>
<code>mpv</code> does something special for audio playback that
prevents audio from clipping. <code>vlc</code> plays the file as it
is.
</li>
<li>
Because the compressor has an attack and decay (which is necessary for
things to sound good) it can cause clipping if the volume rises
sharply. Applying a <code>delay</code> parameter with half the
duration of the attack length fixed this.
</li>
</ol>
<p>Here is the script:</p>
<p><code>process-audio.sh</code></p>
<pre
class="language-bash"
><code class="language-bash"><span class="token shebang important">#!/bin/bash</span>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><style>@font-face{font-family:'Inter Variable';font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/inter-latin-wght-normal-Dx4kXJAl.woff2) format('woff2-variations');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:'Inter Variable';font-style:italic;font-display:swap;font-weight:100 900;src:url(/assets/inter-latin-wght-italic-DpCbqKDY.woff2) format('woff2-variations');unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}</style><script defer src="https://stats.apps.seigler.net/script.js" data-website-id="ccb4bd94-2a71-47fe-8eea-d85bf75b7f6d"></script><link rel="me" href="https://github.com/seigler"><link rel="webmention" href="https://webmention.io/joshua.seigler.net/webmention"><title>FFmpeg audio cleanup - joshua.seigler.net</title><meta name="description" content="A script to apply dynamic compression and noise reduction to audio files"><meta name="keywords" content="posts, technical, ffmpeg"><meta property="og:title" content="FFmpeg audio cleanup"><meta property="og:type" content=""><meta property="og:url" content="/posts/ffmpeg-audio-cleanup/"><meta name="twitter:title" content="FFmpeg audio cleanup"><meta name="twitter:description" content="A script to apply dynamic compression and noise reduction to audio files"><meta name="twitter:card" content="summary"><meta name="generator" content="Eleventy v3.1.0"><script type="module" crossorigin src="/assets/main-CdOn50KG.js"></script><link rel="stylesheet" crossorigin href="/assets/main-DuEJPS2d.css"></head><body data-font="english" data-path="/posts/ffmpeg-audio-cleanup/"><header><nav><div class="nav-row"><div class="nav-home"><a href="/">joshua.seigler.net</a></div></div><div class="nav-categories"><a class="nav-active" href="/posts/">/posts</a> <a href="/about/">/about</a> <a href="/now/">/now</a> <a href="/uses/">/uses</a> <a href="/recipes/">/recipes</a> <a href="/music/">/music</a> <a href="/books/">/books</a> <a href="/links/">/links</a> <a href="/search/">/search</a></div></nav><h1>FFmpeg audio cleanup</h1><div class="header-meta"><author>Joshua Seigler</author><date>June 26, 2025</date><span class="tags" style="--totalTags:11"><a class="tag" style="--tagIndex:5" href="/tags/technical">technical</a> <a class="tag" style="--tagIndex:10" href="/tags/ffmpeg">ffmpeg</a></span></div></header><header class="toc"></header><main data-pagefind-body="data-pagefind-body"><p>I recently needed to process 20+ phone audio recordings. The files are mp3 recordings in stereo, made in an environment with echoes and noise from fans/heaters.</p><p>Although I could do it easily with <a href="https://tenacityaudio.org/" target="_blank" rel="noopener">Tenacity</a> I didnt want to use a manual process, since it would take days. So I tried using FFmpeg filters and Bash scripting.</p><p>I found an FFmpeg filter called <a href="https://ffmpeg.org/ffmpeg-filters.html#compand" target="_blank" rel="noopener">compand</a> which lets you map an input decibel range to an output decibel range. I also used the <a href="https://ffmpeg.org/ffmpeg-filters.html#anlmdn" target="_blank" rel="noopener">anlmdn</a> filter to reduce noise, and the <a href="https://ffmpeg.org/ffmpeg-filters.html#highpass" target="_blank" rel="noopener">highpass</a> filter to help with clarity.</p><p>I ran into a couple gotchas.</p><ol><li><code>mpv</code> does something special for audio playback that prevents audio from clipping. <code>vlc</code> plays the file as it is.</li><li>Because the compressor has an attack and decay (which is necessary for things to sound good) it can cause clipping if the volume rises sharply. Applying a <code>delay</code> parameter with half the duration of the attack length fixed this.</li></ol><p>Here is the script:</p><p><code>process-audio.sh</code></p><pre class="language-bash"><code class="language-bash"><span class="token shebang important">#!/bin/bash</span>
<span class="token keyword">if</span> <span class="token punctuation">[</span> <span class="token string">"<span class="token variable">$#</span>"</span> <span class="token operator">==</span> <span class="token string">"0"</span> <span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token keyword">then</span>
<span class="token builtin class-name">echo</span> <span class="token string">"Error: no arguments provided."</span>
<span class="token builtin class-name">echo</span> <span class="token string">"Usage: <span class="token variable">$0</span> file1 file2 file3 ..."</span>
@ -178,30 +20,4 @@
<span class="token keyword">fi</span>
<span class="token builtin class-name">shift</span>
<span class="token keyword">done</span>
</code></pre>
<p>
If this is useful to you please leave a comment or send an email, I
would love to hear about it.
</p>
</main>
<script
data-isso="//comments.apps.seigler.net/"
src="//comments.apps.seigler.net/js/embed.min.js"
></script>
<section id="isso-thread" data-title="">
<noscript>Javascript needs to be activated to view comments.</noscript>
</section>
<footer>
&copy; Joshua Seigler 2025. -
<a rel="me" href="mailto:joshua@seigler.net?subject=Hello">Contact</a>
-
<a href="/feed.xml">RSS</a>
-
<a href="/unoffice-hours/">Unoffice Hours</a>
-
<a href="/webrings/">Webrings</a>
</footer>
<div id="effects"></div>
</body>
</html>
</code></pre><p>If this is useful to you please leave a comment or send an email, I would love to hear about it.</p></main><script data-isso="//comments.apps.seigler.net/" src="//comments.apps.seigler.net/js/embed.min.js"></script><section id="isso-thread" data-title=""><noscript>Javascript needs to be activated to view comments.</noscript></section><footer>&copy; Joshua Seigler 2025. - <a rel="me" href="mailto:joshua@seigler.net?subject=Hello">Contact</a> - <a href="/feed.xml">RSS</a> - <a href="/unoffice-hours/">Unoffice Hours</a> - <a href="/webrings/">Webrings</a></footer><div id="effects"></div></body></html>