このプログラムは、TSVファイルからテキストを読み込み、それぞれのテキストに対応する
画像と音声を自動で検索、もしくは生成し、それらを組み合わせてMP4形式の動画を自動生成するものです。
プログラムの解説
import os
import subprocess
from gtts import gTTS
from pydub import AudioSegment
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
import time
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
# パラメータ設定
OUTPUT_DIR = r”C:\Users\kosei\Downloads\denki”
TSV_FILE = r”C:\Users\kosei\Downloads\問題 – シート1 (1).tsv”
#TSV_FILE = input(“TSVファイルのパスを入力してください: “)
os.makedirs(OUTPUT_DIR, exist_ok=True)
# 言語設定
lang1 = ‘ja’ # 1番目の言語 (日本語)
lang2 = ‘ja’ # 2番目の言語 (英語)
# 空白の秒数指定
silence_duration = 2000 # 2秒の無音
# Chromeドライバーをセットアップする関数
def set_driver():
options = webdriver.ChromeOptions()
options.add_argument(‘–headless’)
return webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
# 文字サイズを大きくするための設定
FONT_SIZE = 30 # 文字サイズを大きくする
”’
# テキストを画像として保存する関数
def create_text_image(text, index, font_size=FONT_SIZE):
img_path = os.path.join(OUTPUT_DIR, f”image_{index:03d}.png”)
image = Image.new(‘RGB’, (640, 480), color=(255, 255, 255)) # 白背景
draw = ImageDraw.Draw(image)
font = ImageFont.truetype(r”C:\Windows\Fonts\msyh.ttc”, font_size) # フォントは色々な外国語で文字化けしないmsyhを使用
text_bbox = draw.textbbox((0, 0), text, font=font)
text_width = text_bbox[2] – text_bbox[0]
text_height = text_bbox[3] – text_bbox[1]
position = ((640 – text_width) // 2, (480 – text_height) // 2)
draw.text(position, text, fill=(0, 0, 0), font=font) # 黒文字でテキストを描画
image.save(img_path)
return img_path
”’
# フォントサイズ
FONT_SIZE = 20
# テキストを折り返す関数
def wrap_text(text, font, max_width):
words = text.split()
lines = []
current_line = “”
for word in words:
test_line = current_line + ” ” + word if current_line else word
text_width = font.getbbox(test_line)[2] # getbboxでテキストの幅を取得
if text_width > max_width: # 指定幅を超えたら改行
lines.append(current_line)
current_line = word
else:
current_line = test_line
if current_line:
lines.append(current_line)
return lines
# テキストを画像として保存する関数
def create_text_image(text, index, font_size=FONT_SIZE):
img_path = os.path.join(OUTPUT_DIR, f”image_{index:03d}.png”)
image = Image.new(‘RGB’, (640, 480), color=(255, 255, 255)) # 白背景
draw = ImageDraw.Draw(image)
font = ImageFont.truetype(r”C:\Windows\Fonts\msyh.ttc”, font_size)
max_width = 600 # 画像の横幅に対する最大テキスト幅
wrapped_text = wrap_text(text, font, max_width) # テキストを折り返し処理
# 各行の高さを取得
line_height = font.getbbox(“A”)[3] – font.getbbox(“A”)[1]
total_text_height = line_height * len(wrapped_text)
# テキストの描画開始位置(中央揃え)
y_offset = (480 – total_text_height) // 2
for line in wrapped_text:
text_width = font.getbbox(line)[2]
x_position = (640 – text_width) // 2
draw.text((x_position, y_offset), line, fill=(0, 0, 0), font=font)
y_offset += line_height
image.save(img_path)
return img_path
”’
# 日本語の単語をGoogle画像検索し、スクリーンショットを保存する関数
def save_screenshot(driver, word, index):
img_path = os.path.join(OUTPUT_DIR, f”image_{index:03d}.png”)
driver.get(f”https://www.google.com/search?hl=ja&tbm=isch&q={word}のイメージ -形容詞 -動詞 -名刺 -副詞 -前置詞 -接続詞”)
time.sleep(0.1)
screenshot = driver.get_screenshot_as_png()
image = Image.open(BytesIO(screenshot))
image.save(img_path)
return img_path
”’
# 日本語の単語をGoogle画像検索し、スクリーンショットを保存する関数
def save_screenshot(driver, word, index):
img_path = os.path.join(OUTPUT_DIR, f”image_{index:03d}.png”)
# 不要な文字を削除(-形容詞 など)
remove_words = [“形容詞:”, “:動詞:”, “名詞:”, “副詞:”, “前置詞:”, “接続詞:”]
clean_word = word
for remove_word in remove_words:
clean_word = clean_word.replace(remove_word, “”)
# Google画像検索を実行
driver.get(f”https://www.google.com/search?hl=ja&tbm=isch&q={clean_word} https://www.irasutoya.com”)
time.sleep(0.1)
# スクリーンショットを撮影
screenshot = driver.get_screenshot_as_png()
image = Image.open(BytesIO(screenshot))
image.save(img_path)
return img_path
# テキストを音声に変換して保存する関数
def generate_audio(text, lang, filename, retries=3):
path = os.path.join(OUTPUT_DIR, filename)
for _ in range(retries):
try:
tts = gTTS(text=text, lang=lang)
tts.save(path)
return path
except Exception as e:
print(f”エラーが発生しました: {e}. リトライします…”)
time.sleep(3)
raise Exception(“音声生成に失敗しました。”)
# 音声の長さを取得する関数
def get_audio_duration(audio_path):
audio = AudioSegment.from_file(audio_path)
return audio.duration_seconds
# TSVファイルを読み込む
with open(TSV_FILE, ‘r’, encoding=’utf-8′) as file:
tsv_data = [line.strip().split(‘\t’) for line in file]
# ドライバーのセットアップ
driver = set_driver()
# 各行について処理を実行
for index, row in enumerate(tsv_data):
ja_text = row[0] # 最初の列の日本語テキスト
en_text = row[1] # 2番目の列の英語テキスト
# 日本語のテキスト画像を作成
ja_text_image_path = create_text_image(ja_text, index * 2)
# 英語のスクリーンショットを保存
en_screenshot_path = save_screenshot(driver, en_text, index * 2 + 1)
# 日本語の音声を生成
japanese_audio_path = generate_audio(ja_text, lang1, f”audio_ja_{index}.mp3″)
# 英語の音声を生成
english_audio_path = generate_audio(en_text, lang2, f”audio_en_{index}.mp3″)
# 音声ファイルを結合する
japanese_audio = AudioSegment.from_file(japanese_audio_path)
english_audio = AudioSegment.from_file(english_audio_path)
silent_audio = AudioSegment.silent(duration=silence_duration) # 2秒の無音
combined_audio = japanese_audio + silent_audio + english_audio + silent_audio
combined_audio_path = os.path.join(OUTPUT_DIR, f”combined_audio_{index}.wav”)
combined_audio.export(combined_audio_path, format=”wav”)
# 音声の長さを取得
audio_duration = get_audio_duration(combined_audio_path)
# フレームレートを計算して設定
image_duration = (audio_duration / 2) # 各画像が表示される時間を2倍に設定
framerate = 1 / image_duration
# 画像リストファイルを作成
list_file_path = os.path.join(OUTPUT_DIR, f”images_list_{index}.txt”)
with open(list_file_path, ‘w’) as list_file:
list_file.write(f”file ‘{ja_text_image_path}’\n”)
list_file.write(f”duration {image_duration}\n”)
list_file.write(f”file ‘{en_screenshot_path}’\n”)
list_file.write(f”duration {image_duration}\n”)
# FFmpegコマンドを作成して実行
ffmpeg_cmd = [
“ffmpeg”,
“-f”, “concat”,
“-safe”, “0”,
“-i”, list_file_path, # 画像リストファイルを入力
“-i”, combined_audio_path, # 結合された音声ファイルのパスを入力
“-vf”, “scale=640:480,setsar=1”, # 画像のスケーリングとSARの設定
“-c:v”, “libx264”, # ビデオコーデックとしてH.264を使用する
“-r”, “30”, # 出力動画のフレームレートを30fpsに設定
“-pix_fmt”, “yuv420p”, # ピクセルフォーマットをYUV 4:2:0に設定
# “-shortest”, # 音声の長さに合わせて出力を終了する
os.path.join(OUTPUT_DIR, f”output_video_{index}.mp4″) # 出力動画ファイルのパスを指定
]
# コマンドの実行
try:
subprocess.run(ffmpeg_cmd, check=True)
print(f”動画の生成が完了しました: output_video_{index}.mp4″)
except subprocess.CalledProcessError as e:
print(f”エラーが発生しました: {e}”)
# ドライバーを終了
driver.quit()
1. 初期設定と準備
- 1. 初期設定と準備
必要なライブラリのインポート: プログラムの実行に必要なos
(ファイル・ディレクトリ操作),subprocess
(外部コマンド実行),gtts
(テキストから音声生成),pydub
(音声ファイル操作),PIL
(画像処理),io
(入出力操作),time
(時間関連),selenium
(Webブラウザ自動化),webdriver_manager
(WebDriver管理)を読み込みます。
パラメータの設定:OUTPUT_DIR
: 生成されたファイル(画像、音声、動画)を保存する出力ディレクトリのパスを設定します。TSV_FILE
: 読み込むTSVファイルのパスを設定します。os.makedirs(OUTPUT_DIR, exist_ok=True)
: 指定された出力ディレクトリが存在しない場合、新しく作成します。
言語設定:lang1
とlang2
で、それぞれ日本語と英語の言語コードを設定します。
無音時間の指定:silence_duration
で、音声結合時に挿入する無音の長さをミリ秒単位で設定します(例:2000ミリ秒 = 2秒)。
Chromeドライバー設定関数 (set_driver
): Selenium WebDriverを使用してChromeブラウザを操作するためのドライバーを初期化します。--headless
オプションを設定することで、ブラウザのGUIを表示せずにバックグラウンドで実行します。ChromeDriverManager().install()
を使って、適切なバージョンのChromeドライバーを自動でダウンロード・インストールします。
フォントサイズ設定:FONT_SIZE
で、テキストを画像として表示する際のフォントサイズを初期設定します。
2. テキスト画像生成関連関数
テキスト折り返し関数 (wrap_text
): 与えられたテキストとフォント、最大幅を基に、テキストを指定された幅で適切に改行する処理を行います。
これにより、長いテキストが画像からはみ出すのを防ぎます。
テキストを画像として保存する関数 (create_text_image
): 与えられたテキストをPNG画像として保存します。
白い背景に黒い文字でテキストを描画し、中央に配置します。wrap_text
関数を呼び出して、テキストを画像幅に合わせて折り返します。
フォントには、多言語対応のmsyh.ttc
(Microsoft YaHei UI)を使用しています。
3. スクリーンショット保存関数
Google画像検索しスクリーンショットを保存する関数 (save_screenshot
): 指定された単語をGoogle画像検索し、その検索結果画面のスクリーンショットをPNG画像として保存します。
検索クエリから不要な品詞情報(例:「-形容詞」)を削除して、より的確な検索結果を得るようにしています。https://www.irasutoya.com
のサイトに限定して検索するようになっています。
スクリーンショット取得後、画像ファイルとして保存します。
4. 音声生成関連関数
テキストを音声に変換して保存する関数 (generate_audio
): Google Text-to-Speech (gTTS
) を使用して、与えられたテキストを指定された言語で音声ファイル(MP3形式)に変換し、保存します。
エラーが発生した際には、リトライ処理を行うことで、一時的な問題に対応します。
音声の長さを取得する関数 (get_audio_duration
): 指定された音声ファイルの再生時間を秒単位で取得します。
5. メイン処理ループ
TSVファイルの読み込み: 指定されたTSV_FILE
を開き、各行をタブ区切りで分割してtsv_data
リストに読み込みます。
WebDriverのセットアップ:set_driver()
関数を呼び出し、Selenium WebDriverを初期化します。
各行に対する処理ループ:tsv_data
の各行(1行ごとに1つの項目とみなされる)に対して以下の処理を繰り返します。
日本語と英語のテキスト抽出: TSVの最初の列から日本語テキストを、2番目の列から英語テキストをそれぞれ抽出します。
日本語テキスト画像の作成: 日本語テキストを画像として作成し、ファイルパスを取得します。
英語スクリーンショットの保存: 英語テキスト(単語)を使ってGoogle画像検索を行い、そのスクリーンショットを保存し、ファイルパスを取得します。
日本語音声の生成: 日本語テキストから音声を生成し、ファイルパスを取得します。
英語音声の生成: 英語テキストから音声を生成し、ファイルパスを取得します。
音声ファイルの結合: 生成された日本語音声、指定された無音、英語音声、再び無音をこの順序で結合します。
結合された音声ファイルをWAV形式で保存します。
音声の長さ取得: 結合された音声ファイルの再生時間を取得します。
画像表示時間とフレームレートの計算: 取得した音声の長さを基に、各画像が表示される時間と、それに合わせて動画のフレームレートを計算します。
画像リストファイルの作成: FFmpegが動画を生成するために必要な、画像ファイルのリストとその表示時間を記述したテキストファイルを作成します。このファイルには、日本語テキスト画像と英語のスクリーンショットのパスが含まれます。
FFmpegコマンドの作成と実行:ffmpeg
コマンドを構築し、画像リストファイルと結合された音声ファイルを入力として、MP4形式の動画を生成します。
動画のスケール(640×480)、アスペクト比、ビデオコーデック、フレームレート、ピクセルフォーマットなどを設定します。subprocess.run
を使用してFFmpegコマンドを実行し、動画ファイルを出力します。
コマンド実行中にエラーが発生した場合、それを捕捉して表示します。
6. 終了処理
ドライバーの終了: すべての処理が完了したら、Selenium WebDriverを終了し、開いていたブラウザプロセスを閉じます。
このプログラムは、特に語学学習コンテンツの作成や、単語帳と音声・画像を組み合わせた教材の自動生成といった用途に役立つでしょう - コマンドシェルで下記のプログラムに必要なインストールコマンドの書き方
import os
import subprocess
from gtts import gTTS
from pydub import AudioSegment
from PIL import Image, ImageDraw, ImageFont
from io import BytesIO
import time
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.service import Service
必要なライブラリのインストールコマンド
このPythonプログラムを実行するために必要なライブラリは、pip
コマンドを使ってインストールできます。また、画像処理にはFFmpegという外部ツールも必要になります。
1. Pythonライブラリのインストール
コマンドプロンプトやターミナルを開いて、以下のコマンドを一行ずつ実行してください。
Bashpip install gtts pip install pydub pip install Pillow # PILはPillowというライブラリ名でインストールします pip install selenium pip install webdriver-manager
2. FFmpegのインストールpydub
で音声ファイルを処理したり、subprocess
で動画を生成するために、FFmpegというツールが必要です。これはPythonライブラリではないため、別途ダウンロードしてシステムパスを設定するか、実行ファイルのあるディレクトリに配置する必要があります。
FFmpegのインストール手順はOSによって異なりますが、一般的な手順は以下の通りです。
Windowsの場合:
FFmpegの公式ウェブサイト (https://ffmpeg.org/download.html) にアクセスします。
Windowsアイコンをクリックし、推奨されるビルドプロバイダー(例: gyan.dev)からffmpeg-release-full.7z
のようなファイルをダウンロードします。
ダウンロードした.7z
ファイルを解凍します(7-Zipなどのツールが必要です)。
解凍したフォルダ内のbin
フォルダ(例:ffmpeg-xxxx-full_build\bin
)にあるffmpeg.exe
のパスを環境変数Path
に追加します。 環境変数Path
への追加方法は、「Windows 環境変数 Path 追加」などで検索すると多くの情報が見つかります。
または、プログラムのPythonファイルと同じディレクトリにffmpeg.exe
を配置しても動作する場合があります。
macOSの場合: Homebrewを使っている場合、以下のコマンドで簡単にインストールできます。
Bashbrew install ffmpeg
Linuxの場合: ディストリビューションのパッケージマネージャーを使用します。
Debian/Ubuntu系: Bashsudo apt update sudo apt install ffmpeg
Fedora系: Bashsudo dnf install ffmpeg
3. Chromeブラウザのインストール
Seleniumとwebdriver-manager
はChromeブラウザを操作するために使用されるため、ご自身のPCにGoogle Chromeがインストールされている必要があります。もしインストールされていない場合は、以下の公式ページからダウンロードしてインストールしてください。
Google Chrome公式ダウンロードページ: https://www.google.com/intl/ja_jp/chrome/
これらのインストールが完了すれば、プログラムを実行できる準備が整います。
- パラメータの設定:
OUTPUT_DIR
: 生成されたファイル(画像、音声、動画)を保存する出力ディレクトリのパスを設定します。TSV_FILE
: 読み込むTSVファイルのパスを設定します。os.makedirs(OUTPUT_DIR, exist_ok=True)
: 指定された出力ディレクトリが存在しない場合、新しく作成します。
- 言語設定:
lang1
とlang2
で、それぞれ日本語と英語の言語コードを設定します。 - 無音時間の指定:
silence_duration
で、音声結合時に挿入する無音の長さをミリ秒単位で設定します(例:2000ミリ秒 = 2秒)。 - Chromeドライバー設定関数 (
set_driver
):- Selenium WebDriverを使用してChromeブラウザを操作するためのドライバーを初期化します。
--headless
オプションを設定することで、ブラウザのGUIを表示せずにバックグラウンドで実行します。ChromeDriverManager().install()
を使って、適切なバージョンのChromeドライバーを自動でダウンロード・インストールします。
- フォントサイズ設定:
FONT_SIZE
で、テキストを画像として表示する際のフォントサイズを初期設定します。
2. テキスト画像生成関連関数
- テキスト折り返し関数 (
wrap_text
):- 与えられたテキストとフォント、最大幅を基に、テキストを指定された幅で適切に改行する処理を行います。
- これにより、長いテキストが画像からはみ出すのを防ぎます。
- テキストを画像として保存する関数 (
create_text_image
):- 与えられたテキストをPNG画像として保存します。
- 白い背景に黒い文字でテキストを描画し、中央に配置します。
wrap_text
関数を呼び出して、テキストを画像幅に合わせて折り返します。- フォントには、多言語対応の
msyh.ttc
(Microsoft YaHei UI)を使用しています。
3. スクリーンショット保存関数
- Google画像検索しスクリーンショットを保存する関数 (
save_screenshot
):- 指定された単語をGoogle画像検索し、その検索結果画面のスクリーンショットをPNG画像として保存します。
- 検索クエリから不要な品詞情報(例:「-形容詞」)を削除して、より的確な検索結果を得るようにしています。
https://www.irasutoya.com
のサイトに限定して検索するようになっています。- スクリーンショット取得後、画像ファイルとして保存します。
4. 音声生成関連関数
- テキストを音声に変換して保存する関数 (
generate_audio
):- Google Text-to-Speech (
gTTS
) を使用して、与えられたテキストを指定された言語で音声ファイル(MP3形式)に変換し、保存します。 - エラーが発生した際には、リトライ処理を行うことで、一時的な問題に対応します。
- Google Text-to-Speech (
- 音声の長さを取得する関数 (
get_audio_duration
):- 指定された音声ファイルの再生時間を秒単位で取得します。
5. メイン処理ループ
- TSVファイルの読み込み:
- 指定された
TSV_FILE
を開き、各行をタブ区切りで分割してtsv_data
リストに読み込みます。
- 指定された
- WebDriverのセットアップ:
set_driver()
関数を呼び出し、Selenium WebDriverを初期化します。
- 各行に対する処理ループ:
tsv_data
の各行(1行ごとに1つの項目とみなされる)に対して以下の処理を繰り返します。
- 日本語と英語のテキスト抽出: TSVの最初の列から日本語テキストを、2番目の列から英語テキストをそれぞれ抽出します。
- 日本語テキスト画像の作成: 日本語テキストを画像として作成し、ファイルパスを取得します。
- 英語スクリーンショットの保存: 英語テキスト(単語)を使ってGoogle画像検索を行い、そのスクリーンショットを保存し、ファイルパスを取得します。
- 日本語音声の生成: 日本語テキストから音声を生成し、ファイルパスを取得します。
- 英語音声の生成: 英語テキストから音声を生成し、ファイルパスを取得します。
- 音声ファイルの結合:
- 生成された日本語音声、指定された無音、英語音声、再び無音をこの順序で結合します。
- 結合された音声ファイルをWAV形式で保存します。
- 音声の長さ取得: 結合された音声ファイルの再生時間を取得します。
- 画像表示時間とフレームレートの計算: 取得した音声の長さを基に、各画像が表示される時間と、それに合わせて動画のフレームレートを計算します。
- 画像リストファイルの作成: FFmpegが動画を生成するために必要な、画像ファイルのリストとその表示時間を記述したテキストファイルを作成します。このファイルには、日本語テキスト画像と英語のスクリーンショットのパスが含まれます。
- FFmpegコマンドの作成と実行:
ffmpeg
コマンドを構築し、画像リストファイルと結合された音声ファイルを入力として、MP4形式の動画を生成します。- 動画のスケール(640×480)、アスペクト比、ビデオコーデック、フレームレート、ピクセルフォーマットなどを設定します。
subprocess.run
を使用してFFmpegコマンドを実行し、動画ファイルを出力します。- コマンド実行中にエラーが発生した場合、それを捕捉して表示します。
6. 終了処理
- ドライバーの終了: すべての処理が完了したら、Selenium WebDriverを終了し、開いていたブラウザプロセスを閉じます。
このプログラムは、特に語学学習コンテンツの作成や、単語帳と音声・画像を組み合わせた教材の自動生成といった用途に役立つでしょう。
コメント