YouTubeの動画を文字起こしできたら、便利だと思いませんか?
それができれば、テキストを見て動画をみるかどうかを決めることができます。
一応、あるのはありますが、ちょっと違うのですよね・・・
求めているのは、動画の全文テキストを一覧でみたいのです。
そして、コピペで対応というのは、動画の数が多くなると厳しくなります。
そもそも、動画を全部見るのが面倒なのですよね。
早送りであっても、せいぜい2倍速です。
見る価値があるのどうかを動画をダラダラと見ずに判定したいです。
また、文字起こしができれば、検索も可能です。
しかし、技術的には可能なはずなのに、YouTubeはそれら(特に検索なんて便利なはず)を実装してくれません。
そりゃ、そうですよね。
YouTubeとしては、動画を長い時間視聴して欲しいですから。
そのため、自分で文字起こし(そこから、検索へ)機能を開発することにしました。
私と同じように考える人のために、仕様を記事にして残します。
本記事の内容
- YouTube動画の文字起こし機能の仕様
- 音声ダウンロード
- 音声ファイル分割
- 音声認識(音声⇒テキスト)
初めに全体の仕様を説明します。
そして、それぞれの機能ごとに説明していくという流れです。
では、まずは全体の仕様からの説明となります。
YouTube動画の文字起こし機能の仕様
目的は、YouTube動画の内容をテキスト情報にすることです。
テキスト化された情報を検索するなどは、また別の話となります。
この目的を実現するためには、次の機能が必要となります。
- YouTube動画から音声を抽出する ⇒ 音声ファイル
- 音声ファイルを音声認識できるサイズに分割する ⇒ 分割された音声ファイル
- 分割された音声ファイルを音声認識によりテキストに変換する ⇒ 断片テキスト
- 断片テキストを順番通りに結合する ⇒ 一つのテキストファイル
上記機能を一つづつ説明していきます。
なお、断片テキストを結合する機能は、説明するまでもない仕様のため省きます。
最初の機能説明は、「YouTube動画から音声を抽出する」です。
音声ダウンロード
「youtube-dl」を利用します。
このプログラムは、音声のみをYouTubeからダウンロードできます。
コマンドラインで機能するプログラムです。
GUIはありません。
そのため、プログラムから呼び出されることが前提ですね。
なお、Pythonで書かれているため、WindowsでもLinuxでもMacでも動きます。
早速ですが、利用するコマンドは以下です。
youtube-dl https://www.youtube.com/watch?v=QSxhMliOnCo -x --audio-format wav -o '管理可能な文字列.wav'
「-x」により、音声のみをダウンロードします。
音声フォーマットは、wavです。
これは、「–audio-format wav」で指定しています。
「-o ‘管理可能な文字列.wav’」は、保存ファイル名の指定です。
コマンドの呼び出し側で管理しておく必要があります。
そうしておかないと、保存ファイルを特定できませんからね。
その他にもオプションは多くあります。
興味がある方は調べてみてください。
上記のコマンドの実行結果。
# youtube-dl https://www.youtube.com/watch?v=QSxhMliOnCo -x --audio-format wav -o 'aiueo.wav' [youtube] QSxhMliOnCo: Downloading webpage [download] Destination: aiueo.wav [download] 100% of 19.78MiB in 00:02 [ffmpeg] Correcting container in "aiueo.wav" [ffmpeg] Post-process file aiueo.wav exists, skipping
上記結果を見てわかる通り、「youtube-dl」は「ffmpeg」のインストールが前提です。
そもそも、次の音声ファイル分割でもffmpegは利用します。
次は、この保存した音声ファイルを分割します。
音声ファイル分割
aiueo.wavは、上記動画から音声のみを保存したファイルです。
約21分ありますね。
このままのサイズでは、音声認識ができません。
大き過ぎるのです。
大きいとは、サイズではありません。
再生時間が長すぎる、変換後のテキスト文字数が多すぎるというものです。
サイズに関することは、次の記事で説明しています。
Pythonで文字起こし(音声認識)するために知ってくべきこと
上記記事内で説明している通り、音声ファイルの再生時間を3分(180秒)にする必要があります。
全体の再生時間が21分21秒なので、8ファイルに分割されます。
ただ、これをプログラムで判別したいのです。
では、再生時間が21分21秒というのをどうやって認識するのか?
ここで必要な機能を整理しましょう。
つまり、「音声ファイル分割」は以下の2機能に分けられるということです。
- 音声ファイルの再生時間を認識する
- 音声ファイルを3分毎に分割する
音声ファイルの再生時間を認識する
次のコマンド取得可能です。
ffmpegがインストール済みなら、利用可能です。
# ffprobe aiueo.wav -hide_banner -show_entries format=duration Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'aiueo.wav': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2mp41 encoder : Lavf57.41.100 Duration: 00:21:21.70, start: 0.000000, bitrate: 129 kb/s Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 127 kb/s (default) Metadata: handler_name : SoundHandler [FORMAT] duration=1281.696000 [/FORMAT]
本当は、ピンポイントで「duration=1281.696000」が欲しいのですけどね。
どうやら、これが限界のようです。
でも、正規表現で[FORMAT]と[/FORMAT]の間の情報をサクッと取得できるでしょう。
また、1281秒なので、21分21秒と同じことも確認できました。
音声ファイルを3分毎に分割する
1281秒÷180秒=7あまり21
この結果をもとにして、fmpegの仕様によりファイルを分割します。
ffmpeg -ss 0 -i aiueo.wav -t 180 aiueo_1.wav ffmpeg -ss 180 -i aiueo.wav -t 180 aiueo_2.wav ffmpeg -ss 360 -i aiueo.wav -t 180 aiueo_3.wav ffmpeg -ss 540 -i aiueo.wav -t 180 aiueo_4.wav ffmpeg -ss 720 -i aiueo.wav -t 180 aiueo_5.wav ffmpeg -ss 900 -i aiueo.wav -t 180 aiueo_6.wav ffmpeg -ss 1080 -i aiueo.wav -t 180 aiueo_7.wav ffmpeg -ss 1260 -i aiueo.wav -t 21 aiueo_8.wav
コマンドは、こうなります。
面倒ですけど、頑張って使いこなしましょう。
プログラムで書けば、次のような感じになります。
<?php $unit = 180;//3分 $q = 7;//商 $mod = 21;//あまり for($i=0; $i<=$q; $i++){ $no = $i + 1; if($i==$q){ $duration = $mod; }else{ $duration = $unit; } $cmd = "ffmpeg -ss " . $i*$unit . " -i aiueo.wav -t " . $duration . " aiueo_" . $no . ".wav"; } ?>
あとは、これらのコマンドを実行するだけです。
実行すれば、8個のファイルが作成されます。
音声認識(音声⇒テキスト)
音声認識は、次の記事をご覧ください。
Pythonで音声からテキストへ変換【SpeechRecognition】
次のプログラムを利用します。
# -*- coding: utf-8 -*- import speech_recognition as sr r = sr.Recognizer() with sr.AudioFile("1.wav") as source: audio = r.record(source) text = r.recognize_google(audio, language='ja-JP') print(text)
Pythonの中で全ファイルの処理をfor文で回すもよし。
または、PHPなどからPythonをファイルの数だけ呼ぶもよし。
お好きなようにコーディングしてください。
私は、メインがPHPです。
そのため、PHPの中で上記Pythonをファイル数分だけ呼びます。
その際は、ファイル名を変数で渡します。
まとめ
YouTubeの動画を文字起こしするための仕様を説明しました。
機能的には、これで十分です。
あとは、これを実際にどうやって実現するかだけです。
Python単独で組めば、そこまで権限的に面倒なことにはならいと思います。
ただ、PHPとの連携あたりで上手くいかない可能性があります。
コマンドラインとの連携もありますしね。
これは、実際にそれぞれの環境でやってみるしかないでしょう。
環境によって、ハマりそうな仕組みではあります。
この仕様に基づいて、実際に動くものができたときは記事にまとめます。
デモ画面ぐらいは用意したいですね。
追記 2021年11月8日
ジャンプカットを行えば、動画の再生時間が短くなります。
その動画編集を自動的に行う方法を次の記事で解説しています。