メインコンテンツまでスキップ

「Azure」タグの記事が1件件あります

全てのタグを見る

· 約6分
森田 有貴

最近、業務でリアルタイム文字起こし実装する機会がありまして、Nextjs と Azure の Speech SDK で実装したのでその知見を書いていこうと思います。

https://learn.microsoft.com/ja-jp/azure/ai-services/speech-service/speech-sdk

Deepgram や Open AI の Whisper、文字おこしを実装するための API や SDK は様々あります。 今回 Azure Speech SDK を選んだ理由は大きく分けて2つあり、「精度の高さ」と「話者認識」です。

Azure Speech SDK はかなり感動するレベルで高精度かつ高感度な文字起こしをしてくれます。また、公式ドキュメントには話者分離の機能についても書いてあり、これも業務上使いたい機能でした。

ちなみにDeepgramや、Whisperなどの選択肢もあったのですが、精度や話者分離の機能などの観点から見送ることになりました。

実装

APIキーの準備

まず Azure の API キーを準備しましょう。

Azure のサービスページからリソースの作成 image1

リソースの検索欄から Speech と入力 image2

こちらを選択 image3

プランを選択して作成 image4

適当に入力して image5

完了。リソースに移動して image6

キーの管理から image7

「キー1」と「場所/地域」を後で使うので保存しておきましょう。 image8

Nextjs の実装

フロントを作っていきましょう。

新しい Nextjs プロジェクトの作成

terminal
$ npx create-next-app
✔ What is your project named? … real-time-transcription
✔ Would you like to use TypeScript? … Yes
✔ Would you like to use ESLint? … Yes
✔ Would you like to use Tailwind CSS? … Yes
✔ Would you like to use `src/` directory? … Yes
✔ Would you like to use App Router? (recommended) … Yes
✔ Would you like to customize the default import alias (@/*)? … Yes
✔ What import alias would you like configured? … @/*
/real-time-transcription
$ npm i && npm run dev

image9

必要なライブラリのインストール

/real-time-transcription
$ npm i microsoft-cognitiveservices-speech-sdk

環境変数の設定

/real-time-transcription
$ vim .env.local

ここで先ほど取得した API キーを入力します。

/real-time-transcription/.env.local
NEXT_PUBLIC_AZURE_SPEECH_KEY="api key"
NEXT_PUBLIC_AZURE_SPEECH_REGION="region"

これで準備完了です。 では実際に作っていきましょう。


まず不要なものを削除していきます。

/src/app/layout.tsx
import { Inter } from "next/font/google";

const inter = Inter({ subsets: ["latin"] });

export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
);
}
/src/app/page.tsx
export default function Page() {
return <div>page</div>;
}

以下のようになれば OK image10


文字起こしコンポーネントの作成

新たに AzureSpeech コンポーネントを作成します。

/src/components/AzureSpeech.tsx
"use client";

import React, { useState, useEffect, useRef } from "react";
import * as sdk from "microsoft-cognitiveservices-speech-sdk";

const SPEECH_KEY = process.env.NEXT_PUBLIC_AZURE_SPEECH_KEY ?? "";
const SPEECH_REGION = process.env.NEXT_PUBLIC_AZURE_SPEECH_REGION ?? "";

export const AzureSpeech = () => {
const speechConfig = useRef<sdk.SpeechConfig | null>(null);
const audioConfig = useRef<sdk.AudioConfig | null>(null);
const recognizer = useRef<sdk.SpeechRecognizer | null>(null);

const [myTranscript, setMyTranscript] = useState("");
const [recognizingTranscript, setRecTranscript] = useState("");

useEffect(() => {
if (!SPEECH_KEY || !SPEECH_REGION) {
console.error("Speech key and region must be provided.");
return;
}

speechConfig.current = sdk.SpeechConfig.fromSubscription(
SPEECH_KEY,
SPEECH_REGION
);
speechConfig.current.speechRecognitionLanguage = "ja-JP";

audioConfig.current = sdk.AudioConfig.fromDefaultMicrophoneInput();
recognizer.current = new sdk.SpeechRecognizer(
speechConfig.current,
audioConfig.current
);

const processRecognizedTranscript = (
event: sdk.SpeechRecognitionEventArgs
) => {
const result = event.result;

if (result.reason === sdk.ResultReason.RecognizedSpeech) {
const transcript = result.text;
setMyTranscript(transcript);
}
};

const processRecognizingTranscript = (
event: sdk.SpeechRecognitionEventArgs
) => {
const result = event.result;
if (result.reason === sdk.ResultReason.RecognizingSpeech) {
const transcript = result.text;
setRecTranscript(transcript);
}
};

if (recognizer.current) {
recognizer.current.recognized = (
s: sdk.Recognizer,
e: sdk.SpeechRecognitionEventArgs
) => processRecognizedTranscript(e);
recognizer.current.recognizing = (
s: sdk.Recognizer,
e: sdk.SpeechRecognitionEventArgs
) => processRecognizingTranscript(e);
}
}, []);

return (
<div className="mt-8">
<div>
<div>Recognizing Transcript: {recognizingTranscript}</div>
<div>Recognized Transcript: {myTranscript}</div>
</div>
</div>
);
};

page.tsx をに AzureSpeech コンポーネントをインポートして表示します。

/src/app/page.tsx
src/app/page.tsx

import { AzureSpeech } from "./components/AzureSpeech";

export default function Page() {
return (
<div>
<AzureSpeech />
</div>
);
}

これで完成! ブラウザの設定からマイクとスピーカーを許可すると文字起こしが開始されます。 image11

Recognizing Transcript は文字起こし中の文字列が出力され、Recognized Transcript は文字起こしの内容が一区切りされたところで文を整形して出力してくれます。

ということで Azure Speech を用いた Nextjs での文字起こしの実装でした。


おまけ

冒頭で Azure Speech を選んだ理由として話者認識ができるという点を挙げました。 しかし公式ドキュメントをよく読んでみるとこんな記載が... image12

話者認識は申請をしないとできないみたいです。

というわけでワクワクドキドキで申請をしたのですが、見事に却下されました()

結局話者認識は出来ずじまいでした。

公式ドキュメントはちゃんと読みましょうね😢


おしまい。