使用FFMPEG从音频文件中获取波形数据

时间:2017-01-14 06:40:24

标签: c# .net azure ffmpeg asp.net-core

我正在编写一个应用程序,需要获取音频文件的原始波形数据,以便我可以在应用程序(C#/ .NET)中呈现它。我正在使用ffmpeg卸载此任务,但看起来ffmpeg只能output the waveform data as a png or as a stream to gnuplot

我已经看过其他库来做这件事(NAudio / CSCore),但是他们需要windows / microsoft media foundation,因为这个应用程序将作为web应用程序部署到azure我不能使用它们。

我的策略是从png本身读取波形数据,但这看起来很糟糕而且在顶部。理想的输出是阵列中固定采样的一系列峰值,其中数组中的每个值都是峰值(范围从1-100或其他东西,例如this)。

2 个答案:

答案 0 :(得分:2)

Sabona budi,

写了关于手动获取波形的方法,然后给你看一个例子,我发现this code可以做你想要的(或者至少,你可以从中学到一些东西)。

1)使用FFmpeg获取样本数组

尝试此处显示的示例代码:http://blog.wudilabs.org/entry/c3d357ed/?lang=en-US

尝试使用它,尝试使用手动等建议进行调整...在显示的代码中,只需将string path更改为指向您自己的文件路径。修改proc.StartInfo.Arguments部分,将最后一部分替换为:

proc.StartInfo.Arguments = "-i \"" + path + "\" -vn -ac 1 -filter:a aresample=myNum -map 0:a -c:a pcm_s16le -f data -";

myNum部分中aresample=myNum的计算方式为:

44100 * total Seconds = X.
myNum = X / WaveForm Width.

最后使用ProcessBuffer函数和这个逻辑:

static void ProcessBuffer(byte[] buffer, int length)
{
    float val; //amplitude value of a sample
    int index = 0; //position within sample bytes
    int slicePos = 0; //horizontal (X-axis) position for pixels of next slice


    while (index < length)
    {
        val = BitConverter.ToInt16(buffer, index);
        index += sizeof(short);

        // use number in va to do something...
        // eg: Draw a line on canvas for part of waveform's pixels
        // eg: myBitmap.SetPixel(slicePos, val, Color.Green);

        slicePos++;
    }
}

如果您想手动without FFmpeg。你可以试试......

2)将音频解码为PCM
您可以将音频文件(mp3)加载到您的应用程序中,然后首先将其解码为PCM(即:原始数字音频)。然后只读取PCM编号以生成波形。不要直接从压缩数学字节中读取数字,如MP3。

这些PCM数据值(关于音频幅度)进入字节数组。如果您的声音是16位,那么您通过将每个样本读取为short一次获得两个连续字节的值)来提取PCM值16 bits == 2 bytes length)。

基本上,当一个字节数组中有16位音频PCM时,每两个字节代表一个音频样本的幅度值。此会在每个切片处变为高度(响度)。切片是波形中 time 的1像素垂直线。

现在采样率表示每秒采样数。通常44100个样本(44.1 khz )。您可以看到使用44,000个像素来表示一秒钟的声音是不可行的,因此divide所需的波形width总计为multiply。取结果&amp; while乘以2(覆盖两个字节),这就是你在形成波形时跳跃 - 和 - 采样幅度的方式。在left循环中执行此操作。

答案 1 :(得分:0)

您可以使用this tutorial中描述的功能将从音频文件解码的原始数据作为double值数组。