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

发布于 2024-12-27 17:22:17 字数 216 浏览 6 评论 0原文

我需要检查一组音频文件的持续时间。 有没有一种简单的方法可以在 unix 命令行上执行此操作?

> duration *

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

I need to check the duration of a group of audio files.
Is there a simple way to do this on the unix command-line?

> duration *

I have the amazing SoX app which has an option called stats that generates a set of audio info including duration. I am looking for a way to get only duration.
I am flexible on output format, could be any of sample length, hh:mm:ss, or seconds.
The latter would be my preference.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(20

み格子的夏天 2025-01-03 17:22:17
soxi -D filename
soxi -D *

Soxi查询音频文件的元数据; D 是持续时间选项。它支持通配符。 Soxi 的老大哥 sox 负责命令行音频处理。

soxi -D filename
soxi -D *

Soxi queries metadata of audio files; D is the duration option. It supports globbing. Soxi's big brother sox does command-line audio processing.

┈┾☆殇 2025-01-03 17:22:17
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 }'
mp3info -p "%m:%02s\n" filename

gives you the length of the specified file in mm:ss format (mm can be greater than 59). For just the total number of seconds in the file, you'd use:

mp3info -p "%S\n" filename

To get the total length of all the mp3 files in seconds, AWK can help:

mp3info -p "%S\n" *.mp3 | awk 'BEGIN { s = 0 }; { s = s + $1 }; END { print s }'
苦妄 2025-01-03 17:22:17
ffmpeg -i <audiofile> 2>&1 | grep Duration
ffmpeg -i <audiofile> 2>&1 | grep Duration
一身仙ぐ女味 2025-01-03 17:22:17

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

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

要计算本地目录下所有音频的时长,这个要点将帮助:

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

mediainfo will return to you the milliseconds of an audio file. Assuming the current directory only has audio files, the following

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

To calculate the duration of all audio in the local directory, this gist will help:

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
不交电费瞎发啥光 2025-01-03 17:22:17

使用 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

The raw duration in seconds can be obtained with a high degree of precision with the use of ffprobe of ffmpeg, as follows:

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

The output, easy to use in further scripting, is formatted like this:

193.656236

Extending upon that, the following will measure the total duration in seconds of all .mp3 files in the current directory:

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

And to measure the total length of audio files of several extensions, another wildcard may be appended:

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
亢潮 2025-01-03 17:22:17

在 OSX

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

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

包括文件路径:

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

on OSX

Print the length of each audio file in the current dir:

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

Include the filepath:

afinfo * | awk '/File:/ { song=$2 } /estimated duration/ { print song, $3 }'
傲世九天 2025-01-03 17:22:17

ffprobe

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

输出如下所示:

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

with ffprobe

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

The output looks like this:

Duration: 00:44:33.50, start: 0.011995, bitrate: 128 kb/

深海夜未眠 2025-01-03 17:22:17

除了 cdosborn 的 答案 之外,还要递归计算子文件夹中所有 .mp3 文件的长度当前目录并以天:小时:分钟:秒格式显示总和结果:

在zsh中:

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))}'

在bash或sh中:

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))}'

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

$ 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:05:06:58
$

In addition to cdosborn's answer, to calculate the length of all .mp3 files recursively in subfolders of current directory and show the total sum result in days:hours:minutes:seconds format:

In zsh:

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))}'

In bash or sh:

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))}'

The result is like this (7 days, 5 hours, 6 minutes, 58 seconds):

$ 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:05:06:58
$
永不分离 2025-01-03 17:22:17
sox --info -D file             --> duration in seconds
sox --info -d file             --> duration in HH:mm:ss.ss
sox --info file                --> metadata 
sox --info -D file             --> duration in seconds
sox --info -d file             --> duration in HH:mm:ss.ss
sox --info file                --> metadata 
清秋悲枫 2025-01-03 17:22:17

如果您有兴趣使用 soxi 和 python 查找目录中 wav 文件的总持续时间,您可以使用这个:

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

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

If you are interested in finding total duration of wav files in a directory using soxi and python you can use this:

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

change input_dir according to your input directory.
If you want to find max/min duration between all wav files feel free to change sum to max or min.

倾城月光淡如水﹏ 2025-01-03 17:22:17

基于 命令行 作者:syssyphus 适用于音频和视频文件:

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

A solution based on mplayer from commandlinefu by syssyphus that works with both audio and video files:

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

Get the total length of all video / audio in the current dir (and below) in H:m:s

Change the *.mp3 to whatever you want to match (e.g., *.avi, *.wav), you can remove it altogether if you want to check all files.

Example of output: 00:00:37

鲸落 2025-01-03 17:22:17

我在这里扩展了 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

I expanded on Navid Naderi's answer here, and created a bash function that will give you a summary of every file's running time, plus some time totals in various formats (seconds, minutes, or total running time).

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)) ))"
}

Output will look like:

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
零度℉ 2025-01-03 17:22:17

另一个基于 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

Another soxi based answer including the file names and duration in hours, minutes and seconds format.

$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
遗弃M 2025-01-03 17:22:17

mediainfo 可以做到这一点,但是 mediainfo 是那些有用的工具之一,但它的文档记录非常糟糕,以至于您几乎需要知道如何使用它才能学习如何使用它(在 Linux 世界中经常发生)。

经过几个小时的试验和反复阅读,我终于让它生成一个以逗号分隔的文件名及其持续时间(以毫秒为单位)的递归列表。

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

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

结果将输出到list.txt。

mediainfo can do this, but mediainfo is one of those useful tools that's so badly documented that you almost need to know how to use it in order to learn how to use it (happens a lot in the linux world).

After hours of trials and reading high and low, I finally got it to generate a recursive comma-separated list of file names and their duration in milliseconds.

cd to the starting directory and issue the following command:

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

The results will be output to list.txt.

梦初启 2025-01-03 17:22:17

对于 MP3 有很多选择。

说到 OGG,TinyTag 是我迄今为止找到的最好的。

Shell

$ python -m tinytag --format csv /some/music.mp3
> {"filename": "/some/music.mp3", "filesize": 30212227, "album": "Album", "albumartist": "Artist", "artist": "Artist", "audio_offset": null, "bitrate": 256, "channels": 2, "comment": null, "composer": null, "disc": "1", "disc_total": null, "duration": 10, "genre": null, "samplerate": 44100, "title": "Title", "track": "5", "track_total": null, "year": "2012"}

或 Python

from tinytag import TinyTag
tag = TinyTag.get('/some/music.mp3')
print('This track is by %s.' % tag.artist)
print('It is %f seconds long.' % tag.duration)

读取音频文件的标签、长度和封面图像
支持的格式

MP3 (ID3 v1, v1.1, v2.2, v2.3+)
Wave/RIFF
OGG
OPUS
FLAC
WMA
MP4/M4A/M4B
AIFF/AIFF-C

For MP3 there are many options.

When it comes to OGG, TinyTag is the best I found so far.

Shell

$ python -m tinytag --format csv /some/music.mp3
> {"filename": "/some/music.mp3", "filesize": 30212227, "album": "Album", "albumartist": "Artist", "artist": "Artist", "audio_offset": null, "bitrate": 256, "channels": 2, "comment": null, "composer": null, "disc": "1", "disc_total": null, "duration": 10, "genre": null, "samplerate": 44100, "title": "Title", "track": "5", "track_total": null, "year": "2012"}

Or Python

from tinytag import TinyTag
tag = TinyTag.get('/some/music.mp3')
print('This track is by %s.' % tag.artist)
print('It is %f seconds long.' % tag.duration)

Read tags, length and cover images of audio files
supported formats

MP3 (ID3 v1, v1.1, v2.2, v2.3+)
Wave/RIFF
OGG
OPUS
FLAC
WMA
MP4/M4A/M4B
AIFF/AIFF-C
双手揣兜 2025-01-03 17:22:17

Debian/Ubuntu 上的 FLAC 非常简单的单行代码,对几乎所有音频容器文件和 SoX 都很有用:

for i in *.flac ; do echo -ne "${i} - " ; soxi -d "${i}" ;  done

soxi -V

可以使用它,但随后您将需要 sedawk和 grep 将输出转换为紧凑形式。

Very simple single-liner for FLAC on Debian/Ubuntu, useful for almost any audio container files and SoX:

for i in *.flac ; do echo -ne "${i} - " ; soxi -d "${i}" ;  done

Also

soxi -V

could be used instead, but then you will need sed or awk and grep to turn the output in the compact form.

转瞬即逝 2025-01-03 17:22:17

(当你没有afinfo可供使用时)我

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

使用find命令递归地获取所有文件,将总秒数放入csv文件中(转到包含例如mp3文件的目录首先)

find . -name "*.mp3" -exec mp3info {} -p "%S\r\n" >> totalSeconds.csv \;

然后在 LibreOffice 中打开它并在底部总结(以获得小时数)

=SUM(A{start}:A{end})/60/60

(When you don't have afinfo at your disposal) I got it recursively for all my files

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

with the find command, put the total seconds to a csv file (go to the directory with your e.g. mp3 files first)

find . -name "*.mp3" -exec mp3info {} -p "%S\r\n" >> totalSeconds.csv \;

Then open it in e.g. in LibreOffice and sum it up at the bottom (to get the hours) with

=SUM(A{start}:A{end})/60/60
暮年 2025-01-03 17:22:17

使用ffprobe获取大多数音视频文件时长的方式,也可以配置为列表(这里以BBcode列表为例):

c=0 ; NAMEPREFIX="[*]" ; DELIMITER="." ; for f in *.flac ; do infstr=`ffprobe -show_entries format=duration -show_entries "format_tags=title" -sexagesimal -of compact=p=0:nk=1 "${f}" 2>/dev/null`; c=$((${c}+1)) ; echo -e "${NAMEPREFIX}${c}${DELIMITER}" $(sed -e 's/.*|//' <<<${infstr}) [$(sed -e 's/\..*//' <<<${infstr})] ; done

The way to obtain durations for most audio and video files using ffprobe, it is also configurable to make a list (the example here is for BBcode listing):

c=0 ; NAMEPREFIX="[*]" ; DELIMITER="." ; for f in *.flac ; do infstr=`ffprobe -show_entries format=duration -show_entries "format_tags=title" -sexagesimal -of compact=p=0:nk=1 "${f}" 2>/dev/null`; c=$((${c}+1)) ; echo -e "${NAMEPREFIX}${c}${DELIMITER}" $(sed -e 's/.*|//' <<<${infstr}) [$(sed -e 's/\..*//' <<<${infstr})] ; done
病女 2025-01-03 17:22:17

也许有点晚了,但这是我的版本。

# by dnetto

[[ "$#" -lt 1 ]] && echo -e "imput error\n\
gt;$0 *.mp3" && exit
echo "geting time of all songs\n"

declare td=0
declare th=0
declare tm=0
declare ts=0
function updateTotal
{
        [[ "$ts" -gt 60 ]] && tm=`echo $tm + $ts / 60 | bc` ; ts=`echo $ts % 60 | bc`
        [[ "$tm" -gt 60 ]] && th=`echo $th + $tm / 60 | bc` ; tm=`echo $tm % 60 | bc`
        [[ "$th" -gt 24 ]] && td=`echo $td + $th / 24 | bc`
}

for i in "$@"; do
        m=`mp3info -p %m $i`
        s=`mp3info -p %s $i`
        t=`mp3info -p %S $i`
        [[ "$color" = "" ]] && color="\033[38;5;199m" || color=""
        printf "$color%.2d:%.2d  -=- %s\033[0m\n" $m $s $i
        ts=`echo $ts + $t | bc`
        updateTotal
done
echo -e "\n=======================================================\n\ttotal time:"
printf "%d days %.2d hours %.2d minutes %.2d seconds" $td $th $tm $ts
echo -e "\n======================================================="                                                                            

如果你不想冗长,只需在里面注释 printf 即可获得总数

Maybe a little bit late, but this is my version.

# by dnetto

[[ "$#" -lt 1 ]] && echo -e "imput error\n\
gt;$0 *.mp3" && exit
echo "geting time of all songs\n"

declare td=0
declare th=0
declare tm=0
declare ts=0
function updateTotal
{
        [[ "$ts" -gt 60 ]] && tm=`echo $tm + $ts / 60 | bc` ; ts=`echo $ts % 60 | bc`
        [[ "$tm" -gt 60 ]] && th=`echo $th + $tm / 60 | bc` ; tm=`echo $tm % 60 | bc`
        [[ "$th" -gt 24 ]] && td=`echo $td + $th / 24 | bc`
}

for i in "$@"; do
        m=`mp3info -p %m $i`
        s=`mp3info -p %s $i`
        t=`mp3info -p %S $i`
        [[ "$color" = "" ]] && color="\033[38;5;199m" || color=""
        printf "$color%.2d:%.2d  -=- %s\033[0m\n" $m $s $i
        ts=`echo $ts + $t | bc`
        updateTotal
done
echo -e "\n=======================================================\n\ttotal time:"
printf "%d days %.2d hours %.2d minutes %.2d seconds" $td $th $tm $ts
echo -e "\n======================================================="                                                                            

if you don't wanna verbose, just comment printf inside to get only total

爱格式化 2025-01-03 17:22:17

扩展 kevin meinert 的答案,我已将脚本修改为:

  1. 未提供参数时默认列出当前目录中文件的持续时间
  2. 允许 -r 标志进行搜索递归地
  3. 允许任意数量的特定参数,例如 snare/*.wav soundtracks/starwars.wav (与之前的行为相同)
  4. 添加了一些 QoL 改进,例如修剪持续时间并删除了运行时间,因为我不在乎关于这一点,

我还将脚本添加到 ./.local/bin 而不是让它成为一个函数,因此我可以通过运行 wavdur 来在任何地方调用它

示例:

$ wavdur -r
Recursive mode enabled, searching for WAV files recursively.
00:00:21.89 | ./240627_0003.wav
00:01:16.88 | ./240627_0005.wav
00:00:22.26 | ./240627_0004.wav
00:02:24.27 | ./240627_0006.wav
00:00:28.21 | ./240627_0007.wav
00:00:14.63 | ./ambient/bacon-sizzling-2.wav
00:00:08.33 | ./ambient/bacon-sizzling.wav

修改后的脚本:

#!/bin/bash

if [[ "$#" -eq 0 ]]; then
  echo "No arguments provided, processing all WAV files in the current directory."
  files=$(find . -maxdepth 1 -type f -name "*.wav")
elif [[ "$1" == "-r" ]]; then
  echo "Recursive mode enabled, searching for WAV files recursively."
  files=$(find . -type f -name "*.wav")
else
  files="$@"
fi

if [[ -z "$files" ]]; then
  echo "No WAV files found."
  exit 1
fi

echo "hh:mm:ss:ms | filepath"
echo "----------------------" 

for i in $files; do
  val=`soxi -d "$i"`
  echo "$val | $i"
done

echo "$files" | xargs soxi -D | python3 -c "import sys;print(\"\ntotal sec:    \" +str( sum(float(l) for l in sys.stdin)))"
echo "$files" | xargs soxi -D | python3 -c "import sys;print(\"total min:    \" +str( sum(float(l) for l in sys.stdin)/60 ))"
#echo "$files" | xargs soxi -D | python3 -c "import sys;import datetime;print(\"running time: \" +str( datetime.timedelta(seconds=sum(float(l) for l in sys.stdin)) ))"

Expanding on kevin meinert's answer, I have modified the script to:

  1. Default to listing the duration of files in the current directory when no arguments are provided
  2. Allow the -r flag to search recursively
  3. Allow any number of specific arguments such as snare/*.wav soundtracks/starwars.wav (same as previous behavior)
  4. Added some QoL improvements like trimming duration and removed the running time as I didn't care about that

I also added the script to ./.local/bin rather than having it be a function, so I can call it anywhere by just running wavdur

Example:

$ wavdur -r
Recursive mode enabled, searching for WAV files recursively.
00:00:21.89 | ./240627_0003.wav
00:01:16.88 | ./240627_0005.wav
00:00:22.26 | ./240627_0004.wav
00:02:24.27 | ./240627_0006.wav
00:00:28.21 | ./240627_0007.wav
00:00:14.63 | ./ambient/bacon-sizzling-2.wav
00:00:08.33 | ./ambient/bacon-sizzling.wav

The modified script:

#!/bin/bash

if [[ "$#" -eq 0 ]]; then
  echo "No arguments provided, processing all WAV files in the current directory."
  files=$(find . -maxdepth 1 -type f -name "*.wav")
elif [[ "$1" == "-r" ]]; then
  echo "Recursive mode enabled, searching for WAV files recursively."
  files=$(find . -type f -name "*.wav")
else
  files="$@"
fi

if [[ -z "$files" ]]; then
  echo "No WAV files found."
  exit 1
fi

echo "hh:mm:ss:ms | filepath"
echo "----------------------" 

for i in $files; do
  val=`soxi -d "$i"`
  echo "$val | $i"
done

echo "$files" | xargs soxi -D | python3 -c "import sys;print(\"\ntotal sec:    \" +str( sum(float(l) for l in sys.stdin)))"
echo "$files" | xargs soxi -D | python3 -c "import sys;print(\"total min:    \" +str( sum(float(l) for l in sys.stdin)/60 ))"
#echo "$files" | xargs soxi -D | python3 -c "import sys;import datetime;print(\"running time: \" +str( datetime.timedelta(seconds=sum(float(l) for l in sys.stdin)) ))"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文