从 sox 输出中获取 .wav 的长度

Posted

技术标签:

【中文标题】从 sox 输出中获取 .wav 的长度【英文标题】:Get length of .wav from sox output 【发布时间】:2011-05-30 21:08:25 【问题描述】:

我需要获取 .wav 文件的长度。

使用:

sox output.wav -n stat

给予:

Samples read:            449718
Length (seconds):     28.107375
Scaled by:         2147483647.0
Maximum amplitude:     0.999969
Minimum amplitude:    -0.999969
Midline amplitude:     0.000000
Mean    norm:          0.145530
Mean    amplitude:     0.000291
RMS     amplitude:     0.249847
Maximum delta:         1.316925
Minimum delta:         0.000000
Mean    delta:         0.033336
RMS     delta:         0.064767
Rough   frequency:          660
Volume adjustment:        1.000

如何使用 grep 或其他方法只输出第二列的长度值,即 28.107375?

谢谢

【问题讨论】:

【参考方案1】:

stat 效果将其输出发送到stderr,使用2>&1 重定向到stdout。使用sed提取相关位:

sox out.wav -n stat 2>&1 | sed -n 's#^Length (seconds):[^0-9]*\([0-9.]*\)$#\1#p'

【讨论】:

我不知道你是如何构建这个的,但它就像一个魅力。谢谢! 对于它的价值,在 Windows 上使用 sox v14.0.0,$ (EOL) 标记导致这个答案无法给出预期的结果(而不是解析到行尾,它只是解析直到找到不是数字或句号的东西。 这比soxi 更可靠:这涉及遍历音频文件以计算 长度,而soxi 只报告标题中的内容 - 无论准确性如何【参考方案2】:

有更好的办法:

soxi -D out.wav

【讨论】:

不幸的是它返回错误的持续时间,在我的情况下与sox output.wav -n stat方法区分开来。 我从未见过它是错误的——你能区分在什么情况下这是错误的吗? 我用 mp3cut.net 裁剪了音频,并收到了来自 sox 的警告:WARN mp3-util: MAD lost sync 持续时间错误。另一方面,sox output.wav -n stat 执行在错误输出线程中返回正确的持续时间(请参阅我的答案以获得解释)。 Windows 资源管理器也显示正确的持续时间。 我认为两者的不同之处在于 soxi 使用标题信息,而 sox 也查看正文。所以如果标题错误,两者给出不同的输出。 为什么是理论? Man 直接声明它for soxi (sox --info):“显示来自给定音频文件或文件的标题的信息。”,for sox stat:“显示有关音频的时域和频域统计信息。音频未经修改地通过 SoX 处理链传递。 "您还可以进一步阅读它是如何收集和计算统计数据的。【参考方案3】:

这对我有用(在 Windows 中):

sox --i -D out.wav

【讨论】:

不幸的是它返回错误的持续时间,在我的情况下与sox output.wav -n stat方法区分开来。 stat 返回 139.389388,这返回 139.407007。就我的目的而言,没关系。谢谢。【参考方案4】:

这可以通过使用来完成:

soxi -D input.mp3 输出将直接以秒为单位的持续时间 soxi -d input.mp3 输出将是持续时间,格式如下:hh:mm:ss.ss

【讨论】:

【参考方案5】:

有我的 C# 解决方案(不幸的是 sox --i -D out.wav 在某些情况下返回错误的结果):

public static double GetAudioDuration(string soxPath, string audioPath)

    double duration = 0;
    var startInfo = new ProcessStartInfo(soxPath,
        string.Format("\"0\" -n stat", audioPath));
    startInfo.UseShellExecute = false;
    startInfo.CreateNoWindow = true;
    startInfo.RedirectStandardError = true;
    startInfo.RedirectStandardOutput = true;
    var process = Process.Start(startInfo);
    process.WaitForExit();

    string str;
    using (var outputThread = process.StandardError)
        str = outputThread.ReadToEnd();

    if (string.IsNullOrEmpty(str))
        using (var outputThread = process.StandardOutput)
            str = outputThread.ReadToEnd();

    try
    
        string[] lines = str.Split(new string[]  Environment.NewLine , StringSplitOptions.RemoveEmptyEntries);
        string lengthLine = lines.First(line => line.Contains("Length (seconds)"));
        duration = double.Parse(lengthLine.Split(':')[1]);
    
    catch (Exception ex)
    
    

    return duration;

【讨论】:

【参考方案6】:

在 CentOS 中

sox out.wav -e stat 2>&1 | sed -n 's#^Length (秒):[^0-9]([0-9.])$#\1#p'

【讨论】:

【参考方案7】:

我刚刚为“stat”和“stats”效果添加了一个 JSON 输出选项。这应该使获取有关音频文件的信息更容易一些。

https://github.com/kylophone/SoxJSONStatStats

$ sox somefile.wav -n stat -json

【讨论】:

【参考方案8】:

sox stat 输出到数组和 json 编码

        $stats_raw = array();
        exec('sox file.wav -n stat 2>&1', $stats_raw);
        $stats = array();

        foreach($stats_raw as $stat) 
            $word = explode(':', $stat);
            $stats[] = array('name' => trim($word[0]), 'value' => trim($word[1]));
         
        echo json_encode($stats);

【讨论】:

【参考方案9】:

对于红宝石:

string = `sox --i -D file_wav 2>&1` 
string.strip.to_f

【讨论】:

以上是关于从 sox 输出中获取 .wav 的长度的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 sox 将 wav 文件转换为 mp3 格式? [关闭]

有啥方法可以让 SoX 只打印 wav 文件中的幅度值?

如何使用 sox 获取所有音频的音频长度?

使用 libsox 从 wav 文件中减少通道

合并音频文件

sox 文件.wav -r 10 文件.dat