如何在 MP3 文件的任意位置插入特定持续时间的静音?

Ele*_*ios 5 .net c# vb.net audio naudio

设想

我有一堆 MP3 文件,其中一些具有恒定比特率,另一些具有可变比特率,有些以 128 kbps 编码,有些以其他比特率编码,有些是立体声,有些是联合立体声。全部为 44,100 khz

为了使用这些数千个 MP3 文件自动执行任务,我正在尝试开发一种算法,该算法应该在不同的任意位置/持续时间将任意持续时间的静音插入这些 MP3 文件中(例如,将 500 毫秒的静音插入一个位置 00:02:30 的 MP3 文件,然后在位置 00:40:02 的其他 MP3 文件中插入 750 毫秒的静音)。

研究

我发现的唯一信息是在 MP3 文件的开头或结尾插入静音。这不是我想要的,因为我需要在任意位置插入静音。大多数情况下,对于大多数文件,我需要在 MP3 文件的中间附近添加静音,而且可能很少需要在 MP3 文件的开头添加静音。我永远不需要在文件末尾添加静音。

有人建议使用SOXFFMPEG命令行应用程序在 MP3 文件的开头或结尾插入静音。我不知道这些应用程序是否可以满足我的目的,但无论如何我的目标是使用 C# 或 VB.NET 语言来做到这一点,不依赖于任何第三方应用程序,这样我就可以完全控制哪些修改我将在文件中执行,并以编程方式处理生成的修改后的文件以使用它执行其他任务(因为插入静音只是我真正需要对这些 MP3 文件做的事情之一)。

但我同意任何外部库的使用,我记得NAudio for .NET,一个很棒的音频操作库,我发现了这个有趣的片段,它不是关于插入静音而是连接文件:

https://markheath.net/post/concatenating-sample-providers-in-naudio

我认为使用NAudio我将有机会开发一种算法来在特定持续时间插入静音。

方法

很明显我没有足够的知识来理解我如何完成这项任务。

我想出的方法之一就是尝试在流的特定位置插入/填充零,我知道该怎么做,但是......我应该如何将零(一个字节)转换为毫秒计算插入 MP3 文件的静音持续时间?所以我不知道仅仅插入一个零序列是否会起到沉默的作用,如果它有效,我不知道如何将该零序列转换为时间,我也不知道这种方法是否对于所有类型的 MP3 文件变体(CBR、VBR、ABR、单声道或立体声通道等)都是安全的。

我想到的第二种方法是使用任何音频编辑器软件生成一个包含 1 毫秒静音的 MP3 文件,然后在 MP3 文件流的特定位置根据需要多次插入和连接该静音。我想我需要为每个可能的 CBR 比特率生成这个 1 ms MP3 文件,但是 VBR 和 ABR 会发生什么?,我坚持这个想法。

可能最终事情会比我想象的要容易得多,并且肯定NAudio可以帮助我完成这项任务,或者至少以更少的努力完成其中的很大一部分。

如何使用 C# 或 VB 在未确定的 MP3 文件格式(可以是 CBR、VBR、ABR、单声道或立体声通道、联合立体声、128 或 320 kbps 等)的特定位置/持续时间插入特定持续时间的静音.NET 是否有NAudio或其他 .NET 库的帮助?。

要求

  • 不使用第三方命令行应用程序也不自动化 GUI 应用程序。

  • 文件修改应在没有音频丢失的情况下完成,即无需重新编码文件。就像MP3DirectCut那样,您可以在其中插入静音或剪切和粘贴而无需重新编码。

  • 最好能实现一个像下面这样的可重用通用函数,我想用这个参数原型来简化事情:

     public static MemoryStream InsertSilence(
                     Stream inputFile, // pass the raw file stream data
                     TimeSpan startPosition, // eg: new TimeSpan(0, 2, 10)
                     TimeSpan silenceDuration // eg. TimeSpan.FromSeconds(10)
     ) {
    
         // Do the work, save the data into a new stream and return it.
    
     return null;
     }
    
    Run Code Online (Sandbox Code Playgroud)

Sco*_*and 1

当音频采用 PCM 格式(也称为原始音频)时,就会发生对数字音频的任何操作...每个音频编解码器(mp3 等)都可以解码为 PCM -> 进行操作 -> 然后将 PCM 编码为任何音频编解码器

一旦采用 PCM 格式,识别音频曲线摆动的范围以确定其过零...在 PCM 中,每个音频样本(音频曲线上的点)通常是一个整数(可以是 16 位 int、24 位或 32 位,等)...所以如果它是一个无符号16位整数,它的值从0到2^16 - 1(0到65535)变化,在这种情况下,它的过零是该范围的中间值...还要注意无论您有符号整数还是无符号整数...无符号整数是最流行的,并且只能具有从零开始的值,而有符号整数可以存储负值...如果您有符号整数,则很可能您的过零值为零...无论哪种情况,过零始终是整数最大可能范围的中间值

为了增加静音,您可以向 PCM 数组添加一系列值,无论您的过零值是通过了解样本位深度来驱动的

注意字节序的概念...WAV 文件有一个 44 字节的标头部分,后跟 PCM 格式的有效负载...当您遍历有效负载以解析下一个音频样本时,如果您的位深度(如标头中所示)部分)是 16 位,那么音频样本需要两个字节,字节序将确定最高有效字节在这组字节中是排在第一位还是最后一位

最容易使用单声道,我强烈建议您仅使用单声道而不是像立体声那样的多通道来运行代码...仅添加多通道即可通过单声道获得成功

最重要的提示首先将您的 mp3 转换为 WAV 然后执行 manip 然后编码回 mp3