GoogleCloud Speech-to-Textをつかって音声を文字に変換する処理をおこないます。いまではYouTubeをみるとおすすめでPython関連の動画ばっかり出てきます。周りの人がPythonサイコーといっているかのような錯覚に陥ってしまいます。みなさんはどんな感じでしょうか?
Contents
C#で文字起こしアプリをつくる
Pythonをつかって文字起こしアプリの作成できるという動画をみたのでC#でも同じことができないかとやってみました。
まずはクイックスタート: クライアント ライブラリの使用にアクセスしてプロジェクトをつくります。そしてAPIサービスの有効化で「Speech-to-Text API」を検索して、これを有効化させます。有効化させたらサービスアカウントを作成して認証情報が書かれたJSONファイルをダウンロードします。
1ヵ月に60分までなら無料
このサービスは無制限に無料で使えるわけではありません。1ヵ月に60分までなら無料ですが、それを超えると課金の対象となります。といっても法外な金額を要求されるわけではありません。15秒超過するごとに0.006ドルなのでめちゃくちゃな使い方をしなければ気にする必要はないと思います。このようなものをつくると公開したくなるのですが、この場合はユーザーがめちゃくちゃな使い方をするかもしれないので、今回は完成品をwebで公開することはしません。デスクトップアプリとして作成します。
最近はTypeScriptやGASなどもネタにして記事を書くことが多かったのですが、久々にC#でデスクトップの作成です。
といっても情報が少ない。Python関連はよく引っかかるんだけどなあ。以下の動画を参考にやってみました。
文字が小さい。これではよく見えないけどこれまでに得たC#の知識を動員してなんとか動くものができました。
Google.Cloud.Speech.V1をインストール
まずNuGetで「Google.Cloud.Speech.V1」をインストールします。そして認証情報が書かれたJSONファイルを実行ファイルが生成されるフォルダと同じ場所にコピーします。プロジェクトに参加させてプロパティで[出力ディレクトリに常にコピーする]としておけばよいでしょう。
それではコードを書いていきましょう。文字起こしができるのはwavファイルだけです。
環境変数の設定
まず最初に認証情報が書かれたJsonファイルのパスを環境変数に設定しなければなりません。これを忘れるとエラーとなります。以下のコードではEnvironment.SetEnvironmentVariableメソッドをつかって環境変数を設定しています。環境変数はEnvironmentVariableTarget.Processで設定しているのでプロセスが終わったら無効になります。
言語の設定
それから音声はどの言語なのかも指定しなければなりません。日本語なら”ja-JP”、英語なら”en-US”です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
using Google.Cloud.Speech.V1; using Google.Protobuf; using System.IO; public partial class Form1 : Form { string SpeechToText(string filePath) { // プロセス環境変数の設定 string secretPath = Application.StartupPath + "\\secret.json"; System.Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", secretPath, EnvironmentVariableTarget.Process); // Google.Cloud.Speech関連は名前空間がわかるように省略しないで書いています。 Google.Cloud.Speech.V1.SpeechClient client = SpeechClient.Create(); Google.Cloud.Speech.V1.RecognitionConfig config = new RecognitionConfig(); config.Encoding = RecognitionConfig.Types.AudioEncoding.Linear16; config.LanguageCode = "ja-JP"; Google.Cloud.Speech.V1.RecognitionAudio audio = new RecognitionAudio(); System.IO.FileStream fileStream = new FileStream(filePath, FileMode.Open); Google.Protobuf.ByteString vs = ByteString.FromStream(fileStream); fileStream.Dispose(); audio.Content = vs; Google.Cloud.Speech.V1.RecognizeResponse responce = client.Recognize(config, audio); StringBuilder sb = new StringBuilder(); foreach (Google.Cloud.Speech.V1.SpeechRecognitionResult result in responce.Results) { foreach (Google.Cloud.Speech.V1.SpeechRecognitionAlternative alternative in result.Alternatives) sb.Append(alternative.Transcript + "\n"); } return sb.ToString(); } } |
できるのはwavファイルだけ
さて文字起こしができるのはwavファイルだけでは使いにくいです。他のファイル形式の場合はいったんwavファイルに変換してから処理をおこなうことにします。
ffmpegでwavに変換
他の形式のファイルをwavファイルに変換するためにここではffmpegを使います。ここからダウンロードしてください。
Zipファイルを解凍したらbinフォルダのなかにあるffmpeg.exeを実行ファイルがあるフォルダにコピーします。または任意の場所に保存してパスを通しておいてください。
ボタンをクリックするとダイアログが出現してファイルを選択し、選択されたファイルの音声が文字に変換されます。対応しているのはwavファイルとmp4ファイルだけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
public partial class Form1 : Form { private void button1_Click(object sender, EventArgs e) { string filePath = ""; OpenFileDialog dialog = new OpenFileDialog(); dialog.Filter = "音声ファイル(*.wav)|*.wav|音声ファイル(*.mp4)|*.mp4"; if (dialog.ShowDialog() == DialogResult.OK) filePath = dialog.FileName; dialog.Dispose(); if (filePath == "") return; string wavPath = ""; // wavファイルかどうか確認する。mp4ならffmpegをつかってwavファイルに変換する FileInfo info = new FileInfo(filePath); if (info.Extension.ToLower() == ".wav") wavPath = filePath; else if(info.Extension.ToLower() == ".mp4") { string arg1 = "-i \"" + filePath + "\" temp.mp3"; string arg2 = "-i temp.mp3 -vn -ac 1 -ar 44100 -acodec pcm_s16le -f wav temp.wav"; // mp3を経由してwavに変換する。この場合、作業ファイルは実行ファイルのフォルダ内に生成される Process p1 = System.Diagnostics.Process.Start("ffmpeg.exe", arg1); p1.WaitForExit(); Process p2 = System.Diagnostics.Process.Start("ffmpeg.exe", arg2); p2.WaitForExit(); wavPath = "temp.wav"; // いらないので削除 File.Delete("temp.mp3"); } try { textBox1.Text = SpeechToText(wavPath); } catch { MessageBox.Show("例外が発生しました", "エラー", MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { // いらないので削除 if(File.Exists("temp.wav")) File.Delete("temp.wav"); } MessageBox.Show("完了しました", "報告", MessageBoxButtons.OK, MessageBoxIcon.Information); } } |
ためしにどうなるかやってみましたが、普通に話をしているのであればだいたい文字として取得できます。歌を歌っている動画の歌詞を文字起こしできるかもやってみましたが、これはうまくいきませんでした。