Skip to content

Instantly share code, notes, and snippets.

@masakielastic
Last active July 1, 2025 19:20
Show Gist options
  • Save masakielastic/5b3a494d5639e0021272d22bd8072410 to your computer and use it in GitHub Desktop.
Save masakielastic/5b3a494d5639e0021272d22bd8072410 to your computer and use it in GitHub Desktop.
VOICEVOX で作成した通知メッセージに BGM をつける

VOICEVOX で作成した通知メッセージに BGM をつける

スクリプトの使い方

python3 generate_notification.py --voice voice.wav --bgm bgm.mp3 --duration 30

VOICEVOX で生成する通知メッセージの例(30秒前後)

おつかれさまなのだ~。
ぼく、ずんだもんだよ!
さっきまで Claude Code くんががんばってくれてたおしごと、ぜんぶおわったのだ!
つぎに何をするか、もう決まってる? それともちょっと休憩する?
どっちにしても、まずは深呼吸して、リラックスなのだ~。
ぼくもずっと見守ってたよ! よくがんばったのだ~!

BGM サイトの例

  • DOVA-SYNDROME (YouTube で視聴可能)
import argparse
import subprocess
import os
import tempfile
def run(cmd):
print(f"Running: {' '.join(cmd)}")
subprocess.run(cmd, check=True)
def get_audio_duration(path):
result = subprocess.run(
['ffprobe', '-v', 'error', '-show_entries', 'format=duration',
'-of', 'default=noprint_wrappers=1:nokey=1', path],
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
)
return float(result.stdout.strip())
def main():
parser = argparse.ArgumentParser(description='VOICEVOX音声とBGMを合成して通知音を作成')
parser.add_argument('--voice', required=True, help='VOICEVOX 音声ファイル (wav)')
parser.add_argument('--bgm', required=True, help='BGM 音声ファイル (mp3/wav/etc)')
parser.add_argument('--duration', type=float, required=True, help='出力音声の長さ(秒)')
parser.add_argument('--output', default='output.wav', help='出力ファイル名 (wav)')
args = parser.parse_args()
with tempfile.TemporaryDirectory() as tmpdir:
bgm_wav = os.path.join(tmpdir, 'bgm.wav')
bgm_fade = os.path.join(tmpdir, 'bgm_fade.wav')
# BGM を wav 形式に変換
run(['ffmpeg', '-y', '-i', args.bgm, '-ar', '24000', '-ac', '1', bgm_wav])
# BGM の実際の長さを取得
bgm_duration = get_audio_duration(bgm_wav)
fade_start = max(0, args.duration - 5)
# フェードアウト & 音量調整(BGM: -5dB)
run([
'ffmpeg', '-y', '-i', bgm_wav,
'-af', f'volume=0.56,afade=t=out:st={fade_start}:d=5',
bgm_fade
])
# 合成(VOICE: +5dB) & トリミング
run([
'ffmpeg', '-y',
'-i', bgm_fade,
'-i', args.voice,
'-filter_complex', '[1]volume=1.78,adelay=0|0[voice];[0][voice]amix=inputs=2:duration=first:dropout_transition=2',
'-t', str(args.duration),
args.output
])
print(f"\n✅ 成功: {args.output}(長さ: 約 {args.duration} 秒)")
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment