Bash - 计算一个文件夹中所有mp3文件的长度

时间:2017-08-06 19:43:56

标签: bash sum mp3

我有以下命令返回mp3文件的文件名和长度:

mp3info -p "%f: %m:%02s\n" *.mp3

如何在bash脚本中使用它来返回给定目录中所有mp3文件的总长度(总和)?我想有以下符号:mm:ss

4 个答案:

答案 0 :(得分:3)

我会采用三步法:

  1. 而不是打印from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC driver = webdriver.Chrome() driver.get("https://redmart.com/bakery") wait = WebDriverWait(driver, 10) counter = 0 while True: try: wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "li.image-facets-pill"))) driver.find_elements_by_css_selector('img.image-facets-pill-image')[counter].click() counter += 1 except IndexError: break # driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") for elems in wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, "li.productPreview"))): name = elems.find_element_by_css_selector('h4[title] a').text price = elems.find_element_by_css_selector('span[class^="ProductPrice__"]').text print(name, price) driver.back() driver.quit() ,省略文件名并打印整个秒数
  2. 从结果中构建算术表达式,总计秒数
  3. 除以60,向下舍入得到分钟,计算剩余秒数。
  4. 第一步很简单

    filename.mp3: mm:ss\n

    将完成这项工作。现在,我们希望事情能够为我们提供表格

    的有效数字表达式

    时间1 + TIME2 + ....

    所以,

    mp3info -o '%S' 
    

    看起来很明智。

    然后,因为mp3info打印的最后一件事将是mp3info -o '%S + ' ,让我们添加一个零:

    +

    并在算术表达式中使用该字符串:

    "$(mp3info -o '%S + ') 0"
    

    现在,获取完整的会议记录:

    total_seconds=$(( $(mp3info -o '%S + ' *.mp3) 0 ))
    

    和剩下的秒数

    full_minutes=$(( total_seconds / 60 ))
    

    所以总脚本看起来像

    seconds=$(( total_seconds % 60 ))
    

答案 1 :(得分:3)

mp3info中的基本计算容易出错,因为元数据不是真实数据。使用sox(用于音频的瑞士军队工具),您可以直接从mp3文件中获取。

R=0
for a in *.mp3
do
  T="$(soxi -D $a 2>-)"
  echo $T
  [[ "$T" != "" ]] && R="$R + $T"
done
echo $R | bc

如果你想要几个小时

echo "($R) / 60" | bc

对于长长的mp3列表,最好在每个循环中加上持续时间

答案 2 :(得分:0)

当在仅包含音乐文件的目录中使用时,这种Bourne外壳式单衬套将在几秒钟内以非常高的精度输出其总长度:

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

修改为仅输出.mp3文件的长度(从而避免破坏位于我们音乐目录中的无害.docx文件),如下所示:

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

例如,如果我们只想输出带有几个不同文件扩展名的音频的总长度,那么我们也可以通过添加第二个通配符来做到这一点,同时避免使用可怕的,令人恐惧的.docx:

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

自然,必须安装ffmpeg才能使用其中任何一个。

答案 3 :(得分:0)

这是@albfan的类似答案的一种变体,具有描述性的变量名和语法突出显示。它适用于目录(相册)的整个目录。

#!/bin/bash

TOTAL=0

for ALBUM in *
do
    if [ -d "${ALBUM}" ] ; then
        ALBUM_TIME=0
        echo ${ALBUM}

        # Make `cd` quiet
        cd "${ALBUM}" &>/dev/null
        for TRACK in *.mp3; do
            TRACK_TIME="$(soxi -D "${TRACK}" 2>/dev/null)"
            # noisy
            # echo "Track duration: $TRACK_TIME"
            [[ "$TRACK_TIME" != "" ]] && ALBUM_TIME="$ALBUM_TIME + $TRACK_TIME"
        done
        # Convert summation to a single number for efficiency
        ALBUM_TIME=`echo $ALBUM_TIME | bc`
        # This has to be two stmts?
        echo -n "Album time (min): "; echo 'scale=2;' ${ALBUM_TIME} / 60 | bc
        echo # line break
        TOTAL="$TOTAL + $ALBUM_TIME"
        cd ..
    fi

    # Evaluate the expression
    TOTAL=`echo $TOTAL | bc`

done

echo -n "Total time (hrs): "; echo 'scale=2;' ${TOTAL} / 3600 | bc