webview4delphi(WebView2)でブラウザの音声認識機能(SpeechRecognition)をDelphiから使用する
Delphi 11.3(Community Edition)でwebview4delphiを使ってブラウザの音声認識機能(SpeechRecognition)を使用します。
(1)はじめに
Windows10の場合はMicrosoft WebView2 ランタイムのインストールを以下のURLを参照してインストールしてください。
https://mam-mam.net/delphi/tedgebrowser.html
「WebView2Loader.dll」も、
https://mam-mam.net/delphi/tedgebrowser.html
を参照してください。
webview4delphiのインストールは以下を参考にDelphiにインストールしてください
https://mam-mam.net/delphi/tedgebrowser_webview4delphi.html
(2)プロジェクトの作成と保存
Delphi IDEを起動し、「ファイル」⇒「Windows VCLアプリケーション -Delphi」をクリックします「ファイル」⇒「すべて保存 Ctrl+Shift+S」をクリックして、プロジェクト保存用フォルダを作成して ユニット(Unit1)とプロジェクト(Project1)を保存します
次に、「プロジェクト」⇒「Project1をビルト Shift+F9」をクリックして事前に一度コンパイルしておきます。(フォルダが生成される)
プロジェクトフォルダ内の「win32\degub」フォルダに「files」フォルダを作成します。
「win32\degub\files」フォルダ内に、以下のHTMLファイル「index.html」を作成してUTF-8で保存してください。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> </head> <body> <script> var SRecognition=null; window.addEventListener("load",function(){ if(window.webkitSpeechRecognition){ SRecognition = new window.webkitSpeechRecognition(); }else if(window.SpeechRecognition){ SRecognition = new window.SpeechRecognition(); } if(SRecognition!=null){ console.log("event:load");//■ロード成功 SRecognition.continuous = false; SRecognition.interimResults = false; SRecognition.lang="ja-JP"; //音声認識が完了した時のイベント SRecognition.addEventListener("result",function(event){ //let txt=document.getElementById("recognitionResult"); //txt.innerHTML+=event.results[0][0].transcript+"\n"; //txt.scrollTop=txt.scrollHeight; console.log("message:"+event.results[0][0].transcript);//■音声認識成功 SRecognition.stop(); }); //音声認識がエラー時のイベント SRecognition.addEventListener("error",function(event){ console.log("event:error");//■音声認識エラー }); SRecognition.addEventListener("end",function(event){ console.log("event:end");//■音声認識終了 }); SRecognition.addEventListener("start",function(event){ console.log("event:start");//■音声認識開始 }); SRecognition.addEventListener("audiostart",function(event){ console.log("event:audiostart");//■音声認識開始 }); //対応している場合は「音声認識開始」ボタンを使用可能にする document.getElementById("recognitionStart").addEventListener("click",function(){ SRecognition.start(); }); }else{ //未対応の場合は「音声認識開始」ボタンを使用不可にする document.getElementById("recognitionStart").setAttribute("disabled","true"); console.log("event:disabled");//■音声認識未対応 } }); </script> </body> </html>
(3)フォームの設計
フォームにTButton×1個と、TMemo1×1個、TWVBrowser×1個、TWVWindowParent×1個をドラッグ&ドロップします
(4)ソースコードの記述
フォームのButton1をダブルクリックしてソースコードを記述します。
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.JSON.Serializers, uWVWinControl, uWVWindowParent, uWVBrowserBase, uWVBrowser, uWVTypes, uWVConstants, uWVTypeLibrary, uWVLoader, uWVInterfaces, uWVCoreWebView2Args, uWVLibFunctions, uWVCoreWebView2CookieList, uWVCoreWebView2Cookie, uWVCoreWebView2HttpRequestHeaders, uWVCoreWebView2, System.Json, System.IOUtils; type TForm1 = class(TForm) WVBrowser1: TWVBrowser; WVWindowParent1: TWVWindowParent; Button1: TButton; Memo1: TMemo; procedure FormCreate(Sender: TObject); procedure WVBrowser1AfterCreated(Sender: TObject); procedure WVBrowser1DevToolsProtocolEventReceived(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2DevToolsProtocolEventReceivedEventArgs; const aEventName: wvstring; aEventID: Integer); procedure Button1Click(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.dfm} procedure TForm1.Button1Click(Sender: TObject); begin Button1.Enabled:=False; //Javascriptの音声認識を開始する WVBrowser1.ExecuteScript('SRecognition.start()',1); end; procedure TForm1.FormCreate(Sender: TObject); var ct:integer; begin Button1.Enabled:=False; Button1.Caption:='音声認識開始'; WVWindowParent1.Browser:=WVBrowser1; if GlobalWebView2Loader.InitializationError then begin ShowMessage(GlobalWebView2Loader.ErrorMessage); end else begin ct:=0; while (ct<20) and (not GlobalWebView2Loader.Initialized) do begin sleep(500); Application.ProcessMessages; inc(ct); end; if GlobalWebView2Loader.Initialized then begin WVBrowser1.CreateBrowser(WVWindowParent1.Handle); //参考: //ユーザーエージェントをWebView以外に変更するとGoogleログインも可能 WVBrowser1.UserAgent:= 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)'+ ' AppleWebKit/537.36 (KHTML, like Gecko)'+ ' Chrome/101.0.4951.64 Safari/537.36 Edg/101.0.1210.53'; end else begin ShowMessage('WebView2初期化失敗'); end; end; end; procedure TForm1.WVBrowser1AfterCreated(Sender: TObject); begin //以下必須 WVWindowParent1.UpdateSize; //ローカルの「files」ディレクトリを「https://demo」に割り当てる WVBrowser1.CoreWebView2.SetVirtualHostNameToFolderMapping( 'demo', PWideChar(ExtractFilePath(Application.ExeName)+'files'), COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_ALLOW ); //コンソールの使用を申請する WVBrowser1.CallDevToolsProtocolMethod( 'Console.enable', '{}', 0 ); //コンソールにメッセージが出力された時に //[OnDevToolsProtocolEventReceived]イベントEventID=1としてを発生させる WVBrowser1.SubscribeToDevToolsProtocolEvent('Console.messageAdded',1); //ローカルPCにある「.\files\index.html」を表示させる WVBrowser1.Navigate('https://demo/index.html'); end; procedure TForm1.WVBrowser1DevToolsProtocolEventReceived(Sender: TObject; const aWebView: ICoreWebView2; const aArgs: ICoreWebView2DevToolsProtocolEventReceivedEventArgs; const aEventName: wvstring; aEventID: Integer); type TJsonMsg=record column:Integer; level:String; line:Integer; source:String; text:String; url:String; end; TJsonMessage=record message:TJsonMsg; end; var pwc:PWideChar; s:TJsonSerializer; res:TJsonMessage; begin if aEventID=1 then begin aArgs.Get_ParameterObjectAsJson(pwc); s:=TJsonSerializer.Create; res:=s.Deserialize<TJsonMessage>(pwc); if res.message.text='event:load' then begin Button1.Enabled:=True; Memo1.Lines.Add('ロードされました'); end else if res.message.text='event:end' then begin Button1.Enabled:=True; Memo1.Lines.Add('音声認識終了'); end else if res.message.text='event:audiostart' then begin Memo1.Lines.Add('マイクに向かって話してください'); end else if pos('message:',res.message.text,1)>0 then begin Memo1.Lines.Add( '「'+res.message.text.Substring(8)+'」' ); end; s.free; end; end; initialization var cachepath:string; begin cachepath:=ExtractFilePath(Application.ExeName) + 'cache'; //キャッシュを削除する if DirectoryExists(cachepath) then TDirectory.Delete(cachepath,true); // GlobalWebView2Loaderをロードして初期化 GlobalWebView2Loader := TWVLoader.Create(nil); //キャッシュやクッキー等の保存場所を指定する GlobalWebView2Loader.UserDataFolder := cachepath; GlobalWebView2Loader.StartWebView2; end; end.
(5)「WebView2Loader.dll」ファイルを実行ファイルと同じフォルダ内にコピーする
「C:\Program Files (x86)\Embarcadero\Studio\22.0\Redist\win32\WebView2Loader.dll」
ファイルを、実行ファイルと同じフォルダ内(プロジェクト保存フォルダ\Win32\Debug)にコピーします
(A)「Debug」ビルトで 「Windows 32ビット」 |
プロジェクト保存フォルダ\Win32\Debug |
(B)「Debug」ビルトで 「Windows 64ビット」 |
プロジェクト保存フォルダ\Win64\Debug |
(C)「Release」ビルトで 「Windows 32ビット」 |
プロジェクト保存フォルダ\Win32\Release |
(D)「Release」ビルトで 「Windows 64ビット」 |
プロジェクト保存フォルダ\Win64\Release |
(6)実行する
マイクをPCに取り付けてください。(ノートPC等、既にマイクが内臓されている場合はそれを使用してもOKです)
「実行」⇒「実行」をクリックすると実行します。
しばらく待つと「音声認識開始(Button1)」ボタンが有効になります。
「音声認識開始(Button1)」ボタンをクリックすると、Memo1に「マイクに向かって話してください」と表示されますので、実際にマイクに向かって何か話してください。
マイクの使用を求めるダイアログが表示された場合は「許可」をクリックしてください。
マイクから音声認識が成功した場合はその文字がMemo1に表示されます。