最近筆者のYoutubeチャンネルは30年以上前になるPanasonic NVDL1を使い出してから映像付きになり、ポッドキャストとの差別化が難しい・・・と思うようになりました。
そこでポッドキャストとYoutubeを分けていこう、でも手間はかけたくない、できれば、「しゃべって、投稿」がいい。。。
昨今のスタンドFMなどのアプリではBGMも自動でつけてくれるので基本的に誰でもしゃべて投稿でいい感じに仕上がりますが、やはりそこは音の専門家であるわけで、一応ちゃんと収録したい。
今回の記事では、Pythonを用いて自動的にポッドキャストの録音・編集・ミックスを行い、MP3形式のファイルとして出力するツールの構築手順を解説します。
本ツールは、以下のような機能を持っています。
- 録音機能
- 初めに Enter キーで録音開始し、Space キーで一時停止/再開、再度 Enter キーで録音終了。
- 編集機能
- 録音音声を正規化(ノーマライズ)し、指定したBGMとミックスします。
- BGMについては、個別に正規化したうえでさらに大幅に音量を下げ(今回は –16 dB のゲインを適用)、録音音声より5秒長くし、末尾5秒にフェードアウト処理を施します。
- 出力
- ミックス結果を320kbps/48kHzの高音質MP3として出力します。
このツールは、Pythonのオーディオ処理ライブラリである pyaudio、pydub、およびキーボード操作を検出する pynput を利用して構築しています。
Macユーザー、特にM1 Macの場合の注意点や環境構築方法についても記事内で言及しています。
環境構築と依存ライブラリ
今回のプロジェクトは、以下の手順で専用の仮想環境を作成し、依存ライブラリをインストールしています。
おそらくほとんどのケースで仮想環境を構築した方がいいです。
ライブラリの管理もしやすくなりますし、他にも画像映像系、トレードツールなど色々なジャンルでPythonは使えるわけですから管理のためにも仮想環境にしましょう。
- 新規仮想環境の作成 例:
cd /path/to/your/project
python3 -m venv autopodcast_env
仮想環境のアクティベート
source /path/to/your/project/autopodcast_env/bin/activate
依存ライブラリのインストール
以下のコマンドで必要なライブラリをインストールします(M1 Macの場合、HomebrewでPortAudioをインストールしておく必要があります)。
brew install portaudio
pip install pyaudio pynput pydub
FFmpegの設定
pydubがMP3出力のためにFFmpegを使用するので、FFmpegのパスが必要です。Macの場合、Homebrew経由でインストールされていれば、
AudioSegment.converter = '/opt/homebrew/bin/ffmpeg'
コード全体の解説
以下に、実際のコードを示します。なお、個人情報に関わるパスは以下のように任意のパスへ置き換えています:
- BGMファイルのパス:
/path/to/PodcastFull/01_SampleBGM.wav
- 出力ディレクトリ:
/path/to/PodcastFull
- プロジェクト内のファイルは
/path/to/your/project/autopodcast_env/autopodcast.py
という形です。
完成コード(autopodcast.py)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
自動ポッドキャスト生成ツール
概要:
- Enter キーで録音開始、Space キーで一時停止/再開、再度 Enter キーで録音終了
- 録音後、録音時間を表示し、Enter キーで編集開始を待機
- 編集処理:
1. 録音音声は個別に正規化(ヘッドルーム 0.1 dBFS)
2. 指定BGM("/path/to/PodcastFull/01_SampleBGM.wav")を別途正規化し、
その後 –16 dB のゲインを適用して、音量を大幅に下げる
3. BGMの長さを録音音声より5秒長くし、末尾5秒にフェードアウト処理
4. 録音音声とBGMをミックスし、320kbps/48kHz のMP3として出力
- 出力ファイル名は YYYYMMDD_HHMMSS.mp3 の形式で保存し、出力先は "/path/to/PodcastFull"
- ※ pydub用FFmpegのパスは '/opt/homebrew/bin/ffmpeg' に設定
依存ライブラリ:
- pyaudio
- pynput
- pydub
"""
import pyaudio
import threading
import time
import io
import os
from datetime import datetime
from pynput import keyboard
from pydub import AudioSegment, effects
# FFmpegのパス設定(pydub用)
AudioSegment.converter = '/opt/homebrew/bin/ffmpeg'
# 定数の設定
CHUNK = 1024 # 一度に読み込むフレーム数
FORMAT = pyaudio.paInt16 # 16bitフォーマット(安定性重視)
CHANNELS = 1 # 録音はモノラルで取得
RATE = 48000 # サンプルレート (48kHz)
BGM_FILE = '/path/to/PodcastFull/01_SampleBGM.wav'
OUTPUT_DIR = '/path/to/PodcastFull'
MP3_BITRATE = "320k"
# グローバル変数
recording = False # 録音開始フラグ
paused = False # 一時停止フラグ
finish_recording = False # 録音終了フラグ
# イベントオブジェクト(非同期制御用)
start_event = threading.Event()
stop_event = threading.Event()
def on_press(key):
"""
キーボード入力監視関数:
- Enter キー:録音開始/終了を制御
- Space キー:一時停止/再開を制御
"""
global recording, paused, finish_recording
try:
if key == keyboard.Key.enter:
if not recording:
recording = True
print("Recording started...")
start_event.set()
else:
finish_recording = True
stop_event.set()
print("Recording stopping...")
elif key == keyboard.Key.space:
if recording:
paused = not paused
if paused:
print("Recording paused. Press Space to resume.")
else:
print("Recording resumed.")
except Exception as e:
print("Error in key press:", e)
def record_audio():
"""
録音関数:
PyAudioを使用して録音データを取得し、録音時間とともに返す。
一時停止中はデータを読み捨て、最終的にはpause状態の時間はカウントしない。
"""
global paused, finish_recording
audio = pyaudio.PyAudio()
stream = audio.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
frames = []
total_frames = 0
pause_message_shown = False
while not finish_recording:
if paused:
if not pause_message_shown:
print("Recording is currently paused. Press Space to resume.")
pause_message_shown = True
stream.read(CHUNK)
continue
else:
pause_message_shown = False
try:
data = stream.read(CHUNK)
except Exception as e:
print("Error during recording:", e)
break
frames.append(data)
total_frames += CHUNK
stream.stop_stream()
stream.close()
audio.terminate()
recorded_time = total_frames / RATE
print(f"Actual recorded time: {recorded_time:.2f} seconds")
return b"".join(frames), recorded_time
def edit_and_export(recorded_audio, recorded_time):
"""
編集・エクスポート関数:
録音音声を正規化した後、指定BGMも正規化して–16dBのゲインを適用。
その後、BGMの長さを録音音声より5秒長く調整し、フェードアウトを適用。
最終的に、録音音声とBGMをミックスし、320kbps/48kHzのMP3として出力する。
"""
# 録音音声の変換とノーマライズ
audio_segment = AudioSegment.from_raw(
io.BytesIO(recorded_audio),
sample_width=pyaudio.get_sample_size(FORMAT),
frame_rate=RATE,
channels=CHANNELS
)
normalized_audio = effects.normalize(audio_segment, headroom=0.1)
# BGMの読み込みとノーマライズ(個別に処理)
bgm = AudioSegment.from_file(BGM_FILE)
normalized_bgm = effects.normalize(bgm, headroom=0.1)
# –16 dB のゲインを適用(これにより、BGMの音量は大幅に下がる)
adjusted_bgm = normalized_bgm.apply_gain(-16)
# 録音音声の長さ(ミリ秒)の取得と、BGMの5秒延長
rec_ms = len(normalized_audio)
target_bgm_length = rec_ms + 5000
if len(adjusted_bgm) >= target_bgm_length:
final_bgm = adjusted_bgm[:target_bgm_length]
else:
times = (target_bgm_length // len(adjusted_bgm)) + 1
final_bgm = (adjusted_bgm * times)[:target_bgm_length]
# BGMの末尾5秒にフェードアウトを適用
final_bgm = final_bgm.fade_out(5000)
# ミックス処理: BGM上に録音音声をオーバーレイ
mixed = final_bgm.overlay(normalized_audio, position=0)
mixed = mixed.set_frame_rate(RATE)
# 出力ファイル名の生成(YYYYMMDD_HHMMSS.mp3形式)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
output_filename = os.path.join(OUTPUT_DIR, f"{timestamp}.mp3")
mixed.export(output_filename, format="mp3", bitrate=MP3_BITRATE, parameters=["-ar", str(RATE)])
print(f"Exported mixed audio to: {output_filename}")
def main():
"""
メイン関数:
1. 録音待機状態から開始(Enter キー待機)
2. 録音開始・制御(Space/Enter キーを使用)
3. 録音終了後、編集待機(Enter キー待機)
4. 編集処理およびMP3出力
"""
print("Press Enter to start recording...")
listener = keyboard.Listener(on_press=on_press)
listener.start()
start_event.wait() # Enterキーで録音開始
recorded_audio, active_recording_time = record_audio()
print(f"Recorded time: {active_recording_time:.2f} seconds")
input("Press Enter to start editing...")
edit_and_export(recorded_audio, active_recording_time)
listener.stop()
if __name__ == '__main__':
main()
コード解説
- 録音部分
- pyaudio を使い、モノラルで48kHz、16bitの形式で音声を録音します。
- キーボード操作で録音の開始、一時停止、終了の制御を行い、録音中は一時停止状態のメッセージが表示されます。
- 編集部分
- pydub の
effects.normalize
により、録音音声とBGMを個別に正規化します。 - BGMに対しては、さらに
apply_gain(-16)
を適用して大幅に音量を下げ、録音音声のミックス時にBGMが支配的にならないように調整しています。
- pydub の
- ミックスと出力
- BGMは録音音声より5秒長く切り出し、末尾にフェードアウト処理を施します。
overlay()
関数で、BGM上に録音音声をオーバーレイしてミックスし、その結果を320kbps/48kHzのMP3ファイルとして出力します。
まとめ
この記事では、Pythonを活用して自動ポッドキャスト生成ツールを構築する方法を解説しました。
個別に正規化した録音音声とBGMをミックスし、簡単なキーボード操作で録音・編集を自動化するこのツールは、将来的にポッドキャスト制作の効率化に大いに役立つことでしょう。
また、記事内のコードサンプルでは、個人情報が含まれないように、ファイルパスは任意のパスに置き換えてあるため、読者の皆さんも安全に参考にできるようになっています。
皆さんも是非、自動ポッドキャスト生成ツールを作って、録音や編集の自動化に挑戦してみてください!
仮想環境での実行方法
- 仮想環境のアクティベート
source /path/to/your/project/autopodcast_env/bin/activate
スクリプトの実行
python /path/to/your/project/autopodcast_env/autopodcast.py
📌 当サイトは本物の音を追求し、次の世代へ“音の叡智”をつなぐことを目的としています。
💡 記事が役に立ったと感じたら、ぜひ以下のボタンからブックマーク(お気に入り登録)をお願いします。
⭐ ブックマーク・お気に入り登録📰 新着記事や特集の最新情報は、以下のSNSでも配信中です。
👍 応援の意味も込めて、SNSでのシェアや「いいね!」もとても励みになります。
🎙 “いい音を、次の時代へ”
それがこのウェブサイトの願いです。
🎧 音楽配信ブランド Curanz Sounds:
▶︎ オフィシャルサイトはこちら