从 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 的长度的主要内容,如果未能解决你的问题,请参考以下文章