トップへ(mam-mam.net/)

TEdgeBrowser(WebView2)でブラウザの音声認識機能をDelphiから使用する ~Delphiソースコード集

検索:

TEdgeBrowser(WebView2)でブラウザの音声認識機能(SpeechRecognition)をDelphiから使用する

Delphi 11.3(Community Edition)でTEdgeBrowserを使ってブラウザの音声認識機能(SpeechRecognition)を使用します。

(1)はじめに

Windows10の場合はMicrosoft WebView2 ランタイムのインストールを以下のURLを参照してインストールしてください。
https://mam-mam.net/delphi/tedgebrowser.html
「WebView2Loader.dll」も、
https://mam-mam.net/delphi/tedgebrowser.html を参照してください。

また、以下URLにある「WebView2_TLB.pas」を、本プロジェクトのフォルダに配置してください、
https://mam-mam.net/delphi/tedgebrowser_webview2.html

(2)プロジェクトの作成と保存

Delphi IDEを起動し、「ファイル」⇒「Windows VCLアプリケーション -Delphi」をクリックします
「ファイル」⇒「すべて保存 Ctrl+Shift+S」をクリックして、プロジェクト保存用フォルダを作成して ユニット(Unit1)とプロジェクト(Project1)を保存します
上述のように「WebView2_TLB.pas」をプロジェクトフォルダ内に配置してください。
次に、「プロジェクト」⇒「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)フォームの設計

フォームに、TEdgeBrowser×1個、TButton×1個と、TMemo1×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, Winapi.WebView2, Winapi.ActiveX,
  Vcl.StdCtrls, Vcl.Edge, WebView2_TLB;

type
  TForm1 = class(TForm)
    EdgeBrowser1: TEdgeBrowser;
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure EdgeBrowser1DevToolsProtocolEventReceived(
      Sender: TCustomEdgeBrowser; const CDPEventName,
      AParameterObjectAsJson: string);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

  //クラスヘルパーでプロパティFWebViewを読めるようにする
  TMyCustomEdgeBrowser = class helper for TCustomEdgeBrowser
    function GetCoreWebView():ICoreWebView2_3;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses System.JSON.Serializers, System.IOUtils;

{ TMyCustomEdgeBrowser }

//クラスヘルパーでプロパティFWebViewを読めるようにする
function TMyCustomEdgeBrowser.GetCoreWebView: ICoreWebView2_3;
begin
  with self do
    result:=WebView2_TLB.ICoreWebView2_3(FWebView);
end;


{ TForm1 }

procedure TForm1.Button1Click(Sender: TObject);
begin
  Button1.Enabled:=False;
  //Javascriptの音声認識を開始する
  EdgeBrowser1.ExecuteScript('SRecognition.start()');
end;

procedure TForm1.EdgeBrowser1DevToolsProtocolEventReceived(
  Sender: TCustomEdgeBrowser; const CDPEventName,
  AParameterObjectAsJson: string);
type
  TJsonMsg=record
    column:Integer;
    level:String;
    line:Integer;
    source:String;
    text:String;
    url:String;
  end;
  TJsonMessage=record
    message:TJsonMsg;
  end;
var s:TJsonSerializer;
    res:TJsonMessage;
begin
  s:=TJsonSerializer.Create;
  try
    res:=s.Deserialize<TJsonMessage>(AParameterObjectAsJson);
    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
  finally
    s.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var wb:ICoreWebView2_3;
    cachepath:string;
begin
  Memo1.Lines.Clear;
  Button1.Caption:='音声認識開始';
  Button1.Enabled:=False;

  cachepath:=ExtractFilePath(Application.ExeName)+'cache';
  //キャッシュを削除する
  if DirectoryExists(cachepath) then TDirectory.Delete(cachepath,true);

  //キャッシュのフォルダを指定する
  //ここに作成される「EBWebView」フォルダを削除すればキャッシュを消せる
  EdgeBrowser1.UserDataFolder:=cachepath;


  if not EdgeBrowser1.WebViewCreated then
  begin
    EdgeBrowser1.CreateWebView;
    while not EdgeBrowser1.WebViewCreated do
    begin
      sleep(100);
      application.ProcessMessages;
    end;
  end;

  //コンソールの使用を申請する
  EdgeBrowser1.DefaultInterface.CallDevToolsProtocolMethod(
    'Console.enable', '{}', nil);

  //コンソールにメッセージが出力された時に
  //[DevToolsProtocolEventReceived]イベンを発生させる
  EdgeBrowser1.SubscribeToCDPEvent('Console.messageAdded');

  //WebView2の取得
  wb:=EdgeBrowser1.GetCoreWebView;

  // https://demo/ を .\filesフォルダに割り当てます
  wb.SetVirtualHostNameToFolderMapping(
    'demo',
    PWideChar(ExtractFilePath(Application.ExeName)+'files'),
    COREWEBVIEW2_HOST_RESOURCE_ACCESS_KIND_ALLOW
  );
  //ローカルファイル \files\index.htmlを読みます
  EdgeBrowser1.Navigate('https://demo/index.html');
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に表示されます。