フォルダ内にある音声ファイルの合計を計算する

初めに

音声処理をする際にフォルダ内に音声ファイルがあるかを確認したいと思う時があります。その際に使用できる簡単なスクリプトを作ります

環境

  • L4 GPU
  • ubuntu22.04

準備

必要なライブラリを入れます

sudo apt update
sudo apt install ffmpeg
pip install pydub

対応音声ファイル

  • wav
  • mp3
  • ogg
  • opus

実行

以下で特定のフォルダ内の音声ファイルの合計を計算できるスクリプトを作成します。

import os
import sys
from pydub import AudioSegment
import wave
import multiprocessing
from functools import partial

def is_valid_audio_file(file_path):
    try:
        if file_path.lower().endswith(('.ogg', '.opus')):
            AudioSegment.from_file(file_path)
            return True
        else:
            with wave.open(file_path, 'rb') as wav_file:
                channels = wav_file.getnchannels()
                sample_width = wav_file.getsampwidth()
                frame_rate = wav_file.getframerate()
                
                if channels > 0 and sample_width > 0 and frame_rate > 0:
                    return True
    except Exception as e:
        print(f"ファイル '{os.path.basename(file_path)}' の検証中にエラーが発生しました: {e}")
    return False

def process_audio_file(file_path):
    if is_valid_audio_file(file_path):
        try:
            audio = AudioSegment.from_file(file_path)
            return len(audio)
        except Exception as e:
            print(f"ファイル '{os.path.basename(file_path)}' を読み込み中にエラーが発生しました: {e}")
    else:
        print(f"ファイル '{os.path.basename(file_path)}' は有効なオーディオファイルではありません。スキップします。")
    return 0

def calculate_total_duration(directory):
    supported_formats = ['.wav', '.mp3', '.ogg', '.opus']
    audio_files = []

    for root, dirs, files in os.walk(directory):
        for file in files:
            if any(file.lower().endswith(fmt) for fmt in supported_formats):
                audio_files.append(os.path.join(root, file))

    with multiprocessing.Pool() as pool:
        durations = pool.map(process_audio_file, audio_files)

    return sum(durations) / 1000  # ミリ秒を秒に変換

def format_duration(seconds):
    hours = seconds // 3600
    minutes = (seconds % 3600) // 60
    seconds = seconds % 60
    return f"{int(hours)}h {int(minutes)}m {int(seconds)}s"

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("使用方法: python script.py <音声ファイルが格納されているフォルダのパス>")
        sys.exit(1)

    directory_path = sys.argv[1]

    total_duration_seconds = calculate_total_duration(directory_path)
    formatted_duration = format_duration(total_duration_seconds)

    print(f"Total duration: {formatted_duration}")

上記は以下のように使用します

python sum_audio_time.py Data/

結果は以下のように出力されます

Total duration: 7h 53m 4s