检查命令行上的音频文件的持续时间

时间:2012-01-19 20:47:54

标签: unix audio sox

我需要检查一组音频文件的持续时间。 在unix命令行上有一种简单的方法吗?

> duration *

我有一个惊人的SoX应用程序,它有一个名为stats的选项,可以生成一组音频信息,包括持续时间。我正在寻找一种方法来获得持续时间。 我对输出格式很灵活,可以是任何样本长度,hh:mm:ss或秒。 后者是我的偏好。

15 个答案:

答案 0 :(得分:31)

soxi -D filename
soxi -D *

Soxi查询音频文件的元数据; D是持续时间选项。它支持globbing。 Soxi的大哥sox进行命令行音频处理。

答案 1 :(得分:23)

mp3info -p "%m:%02s\n" filename

mm:ss格式显示指定文件的长度(mm可以大于59)。对于文件中的总秒数,您可以使用:

mp3info -p "%S\n" filename

要获得所有mp3文件的总长度,AWK可以提供帮助:

mp3info -p "%S\n" *.mp3 | awk 'BEGIN { s = 0 }; { s = s + $1 }; END { print s }'

答案 2 :(得分:12)

mediainfo将返回音频文件的毫秒数。假设当前目录只有音频文件,则以下

mediainfo --Inform="Audio;%Duration%" "Miley Cyrus - Wrecking Ball.mp3"

要计算本地目录中所有音频的持续时间,this gist会有所帮助:

shopt -s nullglob
let playlist_duration_ms=0
for song_file in *.{mp3,ogg,m4a,flac,wav}; do
  playlist_duration_ms=$(expr $playlist_duration_ms + $(mediainfo --Inform="Audio;%Duration%" "$song_file"))
done
shopt -u nullglob

let playlist_duration_secs=$(expr $playlist_duration_ms / 1000)
let playlist_duration_mins=$(expr $playlist_duration_ms / 60000)
let playlist_duration_remaining_secs=$(expr $playlist_duration_secs - $(expr $playlist_duration_mins \* 60))

echo $playlist_duration_mins minutes, $playlist_duration_remaining_secs seconds

答案 3 :(得分:9)

ffmpeg -i <audiofile> 2>&1 | grep Duration

答案 4 :(得分:8)

在OSX上

在当前目录中打印每个音频文件的长度:

afinfo * | awk '/estimated duration/ { print $3 }'

包含文件路径:

afinfo * | awk '/File:/ { song=$2 } /estimated duration/ { print song, $3 }'

答案 5 :(得分:4)

除了cdosborn的answer之外,还要在当前目录的子文件夹中递归计算所有def indicator_to_part_list(indicator): sidx = indicator.argsort() # indicator.argsort(kind='mergesort') keeps order sorted_arr = indicator[sidx] split_idx = np.nonzero(sorted_arr[1:] != sorted_arr[:-1])[0] sidx_list = sidx.tolist() start = np.append(0,split_idx+1) stop = np.append(split_idx+1,indicator.size+1) return [sidx_list[start[i]:stop[i]] for i in range(start.size)] 个文件的长度,并以.mp3格式显示总和结果:< / p>

在zsh中:

days:hours:minutes:seconds

在bash或sh:

afinfo **/*.mp3 | awk '/estimated duration/ { print $3 }' | paste -sd+ - | bc | awk '{printf("%d:%02d:%02d:%02d\n",($1/60/60/24),($1/60/60%24),($1/60%60),($1%60))}'

结果是这样的(7天,5小时,6分钟,58秒):

find . -name "*.mp3" -exec afinfo {} \; | awk '/estimated duration/ { print $3 }' | paste -sd+ - | bc | awk '{printf("%d:%02d:%02d:%02d\n",($1/60/60/24),($1/60/60%24),($1/60%60),($1%60))}'

答案 6 :(得分:3)

sox --info -D file             --> duration in seconds
sox --info -d file             --> duration in HH:mm:ss.ss
sox --info file                --> metadata 

答案 7 :(得分:3)

基于commandlinefu syssyphus的mplayer的解决方案适用于音频和视频文件:

sudo apt-get install mplayer
find -type f -name "*.mp3" -print0 | xargs -0 mplayer -vo dummy -ao dummy -identify 2>/dev/null | perl -nle '/ID_LENGTH=([0-9\.]+)/ && ($t +=$1) && printf "%02d:%02d:%02d\n",$t/3600,$t/60%60,$t%60' | tail -n 1
  

获取当前目录(及以下)中所有视频/音频的总长度:H:m:s

     

*.mp3更改为您想要匹配的内容(例如*.avi*.wav),如果要检查所有文件,则可以完全删除它。

输出示例:00:00:37

答案 8 :(得分:3)

我在这里扩展了 Navid Naderi 的回答,并创建了一个 bash 函数,该函数将为您提供每个文件运行时间的摘要,以及各种格式(秒、分钟或总运行时间)的总时间。

function sox_duration_total
{
  if [[ "$#" -lt 1 ]]; then
    echo "find files!"
    echo "  sox_duration_total *.wav"
    echo ""
    return
  fi
  for i in "$@"; do
    val=`soxi -d "$i"`
    echo "$val | $i"
  done
  soxi -D "$@" | python -c "import sys;print(\"\ntotal sec:    \" +str( sum(float(l) for l in sys.stdin)))"
  soxi -D "$@" | python -c "import sys;print(\"total min:    \" +str( sum(float(l) for l in sys.stdin)/60 ))"
  soxi -D "$@" | python -c "import sys;import datetime;print(\"running time: \" +str( datetime.timedelta(seconds=sum(float(l) for l in sys.stdin)) ))"
}

输出看起来像:

00:01:40.97 | subatomicglue - inertialdecay - 01 - hard.wav
00:00:32.00 | subatomicglue - inertialdecay - 02 - acidbass.wav
00:04:50.80 | subatomicglue - inertialdecay - 03 - cause.of.a.new.dark.age.wav
00:02:08.00 | subatomicglue - inertialdecay - 04 - daybreak.falls.wav
00:05:20.75 | subatomicglue - inertialdecay - 05 - forestfloor.wav
00:03:56.32 | subatomicglue - inertialdecay - 06 - rabbithole.wav
00:03:50.40 | subatomicglue - inertialdecay - 07 - feedme.wav
00:06:03.97 | subatomicglue - inertialdecay - 08 - grand.wav
00:02:09.45 | subatomicglue - inertialdecay - 09 - strawberryflavoreddeath.wav
00:04:43.29 | subatomicglue - inertialdecay - 10 - subfloor.wav
00:03:36.96 | subatomicglue - inertialdecay - 11 - silicone.wav
00:04:28.47 | subatomicglue - inertialdecay - 12 - inertial decay.wav
00:01:23.81 | subatomicglue - inertialdecay - 13 - the.void.wav
00:01:18.86 | subatomicglue - inertialdecay - 14 - weet.wav

total sec:    2764.0637880000004
total min:    46.06772980000001
running time: 0:46:04.063788

答案 9 :(得分:2)

另一个基于soxi的答案,包括文件名和持续时间,以小时,分钟和秒格式显示。

$for f in *amr; do printf "$f "; soxi -d $f; done

DGT20161216.amr 00:22:04.62
DGT20170108.amr 00:28:22.80
DGT20170117.amr 00:20:05.18

答案 10 :(得分:1)

mediainfo可以做到这一点,但是mediainfo是那些非常有用的工具之一,你几乎需要知道如何使用它来学习如何使用它(在linux世界中发生了很多事情) )。

经过数小时的试验和高低读数后,我终于得到了一个以逗号分隔的递归文件名列表及其持续时间(以毫秒为单位)。

cd到起始目录并发出以下命令:

find "$(pwd)" -type f -print0 | xargs -0 -I {} mediainfo --Inform="General;%CompleteName%,%Duration%" {} > list.txt

结果将输出到list.txt。

答案 11 :(得分:0)

(当您没有public static string ToDecimalStringParallel(this BigInteger value) { if (value == 0) return "0"; var digits = 10000; var divider = BigInteger.Pow(10, digits); var remainders = new BlockingCollection<BigInteger>(); var parts = new ConcurrentStack<string>(); var task = Task.Run(() => { foreach (var remainder in remainders.GetConsumingEnumerable()) { parts.Push(BigInteger.Abs(remainder).ToString().PadLeft(digits, '0')); } }); while (true) { BigInteger remainder; value = BigInteger.DivRem(value, divider, out remainder); if (value != 0) { remainders.Add(remainder); } else { remainders.CompleteAdding(); task.Wait(); parts.Push(remainder.ToString()); break; } } return String.Join("", parts); } 供您使用时,我会为所有文件递归获得

afinfo

使用find命令,将总秒数放入csv文件中(首先进入包含mp3文件的目录)

# install mp3info if not yet installed with
sudo apt-get install mp3info

然后在例如在LibreOffice中,并使用

将其汇总在底部(以获取小时数)
find . -name "*.mp3" -exec mp3info {} -p "%S\r\n" >> totalSeconds.csv \;

答案 12 :(得分:0)

ffprobe

ffprobe your_file.mp3 2>&1 | grep "Duration"

输出看起来像这样:

  

持续时间:00:44:33.50,开始:0.011995,比特率:128 kb /

答案 13 :(得分:0)

使用ffmpeg的ffprobe,可以高度精确地获取以秒为单位的原始持续时间,如下所示:

ffprobe -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "filename.mp3" 2>/dev/null

易于在后续脚本中使用的输出格式如下:

193.656236

在此基础上,以下内容将测量当前目录中所有.mp3文件的总持续时间(以秒为单位):

LENGTH=0; for file in *.mp3; do if [ -f "$file" ]; then LENGTH="$LENGTH+$(ffprobe -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$file" 2>/dev/null)"; fi; done; echo "$LENGTH" | bc

要测量多个扩展名的音频文件的总长度,可以附加另一个通配符:

LENGTH=0; for file in *.mp3 *.ogg; do if [ -f "$file" ]; then LENGTH="$LENGTH+$(ffprobe -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "$file" 2>/dev/null)"; fi; done; echo "$LENGTH" | bc

答案 14 :(得分:0)

如果您有兴趣使用soxi在目录中查找wav文件的总持续时间,则可以使用以下方法:

soxi -D input_dir/*.wav | python -c "import sys;print(sum(float(l) for l in sys.stdin))

根据您的输入目录更改input_dir。 如果要查找所有wav文件之间的最大/最小持续时间,请随时将sum更改为maxmin