split_audio_with_overlap.py ダウンロード/コピー
split_audio_with_overlap.py をダウンロード
split_audio_with_overlap.py
split_audio_with_overlap.py
1"""
2概要:
3 長い音声ファイルを指定された最大サイズでオーバーラップ付きで分割するスクリプト。
4
5詳細説明:
6 このスクリプトは、入力された音声ファイルを、コマンドライン引数またはスクリプト内の設定で指定された
7 最大ファイルサイズ(メガバイト)に基づき、固定長のチャンクに分割します。
8 分割時、連続するチャンク間には指定された秒数のオーバーラップを設けます。
9 これにより、音声の途切れを防ぎ、連続再生がスムーズになるように設計されています。
10 出力ファイルは連番で、入力ファイルと同じディレクトリ内の "split_fixed" サブディレクトリに保存されます。
11
12引数:
13 このスクリプトは以下のコマンドライン引数を受け取ります。
14 各引数は指定されない場合、スクリプト内のデフォルト値が適用されます。
15
16 input_audio_file: 分割対象の音声ファイルパス。(必須)
17 output_format: 出力ファイルのフォーマット(例: mp3, wav)。デフォルトは mp3。
18 bitrate: 出力ファイルのビットレート(例: 128k)。デフォルトは 128k。
19 max_size_mb: 1チャンクあたりの最大サイズ(MB)。デフォルトは 150.0。
20 overlap_sec: チャンク間のオーバーラップ時間(秒)。デフォルトは 60.0。
21
22関連リンク:
23 split_audio_with_overlap_usage
24"""
25import os
26import sys
27from pydub import AudioSegment
28
29# ====== 設定 ======
30output_dir = "split_fixed"
31output_format = "mp3" # 出力形式("mp3", "wav"など)
32bitrate = "128k" # 出力ビットレート
33max_size_mb = 150 # チャンク最大サイズ(MB)
34overlap_sec = 60 # オーバーラップ時間(秒)
35
36# ====== 引数処理 ======
37if len(sys.argv) < 2:
38 print("使い方: python fixed_split.py <input_audio_file>")
39 sys.exit(1)
40
41input_file = sys.argv[1] # 必須引数
42
43nargs = len(sys.argv)
44# 引数がある場合のみ、デフォルト値を上書き
45if nargs > 2: output_format = sys.argv[2]
46if nargs > 3: bitrate = sys.argv[3]
47if nargs > 4: max_size_mb = float(sys.argv[4])
48if nargs > 5: overlap_sec = float(sys.argv[5])
49
50if not os.path.isfile(input_file):
51 print(f"エラー: ファイルが見つかりません: {input_file}")
52 sys.exit(1)
53
54# ====== 音声読み込み ======
55ext = os.path.splitext(input_file)[1].lower().lstrip(".")
56print(f"\n音声ファイルを読み込み中...: {input_file} (.{ext})")
57audio = AudioSegment.from_file(input_file, format=ext)
58duration_sec = len(audio) // 1000
59
60# ====== 処理情報出力 ======
61print(f"出力ディレクトリ: {output_dir}")
62print(f"出力フォーマット: {output_format}")
63print(f"ビットレート: {bitrate}")
64print(f"オーバーラップ長: {overlap_sec}秒")
65print(f"最大サイズ: {max_size_mb}MB")
66print(f"音声長さ: {duration_sec} 秒")
67
68# ====== 出力ディレクトリ準備 ======
69dir = os.path.dirname(input_file)
70output_dir = os.path.join(dir, output_dir)
71print("output_dir:", output_dir)
72if not os.path.exists(output_dir):
73 os.makedirs(output_dir, exist_ok=True)
74
75# ====== チャンク長(秒)の見積もり ======
76kbps = int(bitrate.replace("k", ""))
77bytes_per_sec = kbps * 1000 // 8
78max_bytes = max_size_mb * 1024 * 1024
79max_chunk_sec = max_bytes // bytes_per_sec
80step = max_chunk_sec - overlap_sec # オーバーラップを考慮した前進幅
81
82print(f"推定チャンク長: 約 {max_chunk_sec} 秒(@{bitrate})")
83print(f"ステップ(次の開始位置): {step} 秒(オーバーラップ {overlap_sec} 秒)")
84print(f"\n分割開始: 約{max_chunk_sec}秒ごとに分割({overlap_sec}秒の重なりあり)")
85
86# ====== 分割処理 ======
87chunk_index = 0
88start_sec = 0
89filebody = os.path.splitext(os.path.basename(input_file))[0]
90
91while start_sec < duration_sec:
92 print(f"> チャンク {chunk_index + 1} 開始: {start_sec}秒")
93 end_sec = start_sec + max_chunk_sec
94 end_sec = min(end_sec, duration_sec) # 終端を超えない
95
96 # 切り出し(ミリ秒)
97 start_ms = start_sec * 1000
98 end_ms = end_sec * 1000
99 chunk = audio[start_ms:end_ms]
100
101 # ファイル保存
102 out_path = os.path.join(output_dir, f"{filebody}_{chunk_index:03}.{output_format}")
103 chunk.export(out_path, format=output_format, bitrate=bitrate)
104 print(f"> 保存: {out_path}({(end_sec - start_sec)} 秒)")
105
106 # 次の位置へ進む(オーバーラップ考慮)
107 start_sec += step
108 chunk_index += 1
109
110print("\n✅ サイズベースでオーバーラップ付き分割を完了しました。")
111input("\nPress ENTER to terminate>>\n")