WhisperとNext.js(Edge Runtime)で文字起こし
公開日:2023/7/13更新日:2023/7/13
OpenAIのサービスの1つであるWhisperのAPIを使い、Next.jsのアプリケーションで文字起こしをする実践的な手順をご紹介します。
前提
Whisperを実用的に使うとなると、ユーザーがアップロードした音声データを受け取り、それを(加工して)APIに投げる、流れになります。
しかし、執筆時点、Next.jsのEdge Runtimeでは、ファイルの読み書きなどができないため、OpenAI公式のサンプルコードにあるようなfsモジュールを使ったファイルの読み込みができません。
そのため、ライブラリを使わず、FormDataに音声データやその他のパラメーターをセットしてAPIに投げる必要があります。
サーバサイド(API)のコード
/app/api/generate/route.ts
のファイルを作成し、クライアントサイドから<あなたのサイト>/api/generate
にPOST送信された場合の処理を記述します。
import { NextRequest, NextResponse } from "next/server";
export const runtime = "edge";
export async function POST(request: NextRequest) {
// クライアントサイドから送られてきたフォームデータを取得
const formData = await request.formData();
// フォームデータから音声データを取得
const resource = formData.get("resource") as File;
// Whisper-1モデルで日本語の文字起こしを行うためのフォームデータを作成
const transcriptionFormData = new FormData();
transcriptionFormData.set("file", resource); // 音声データをセット
transcriptionFormData.set("model", "whisper-1"); // モデルをwhisper-1にする
transcriptionFormData.set("language", "ja"); // 言語を日本語にする
// 文字起こしを実行
const res = await fetch("https://api.openai.com/v1/audio/transcriptions", {
headers: {
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
},
method: "POST",
body: transcriptionFormData,
});
// 文字起こしに失敗した場合はエラーメッセージを返す
if (!res.ok) {
return NextResponse.json({
success: false,
message: "文字起こしに失敗しました",
});
}
const json = await res.json();
const result = json.text; // 文字起こしの結果を取得
// ここでresultの値をバックエンドに保存したり、別のAPIに渡したり、何かしらの処理を行う
// 成功した場合は成功メッセージを返す
return NextResponse.json({
success: true,
message: "文字起こしに成功しました",
});
}
クライアントサイドのコード
/app/generate/components/Form.tsx
にフォームコンポーネントを作成します。
今回は便宜上、音声データの加工処理を省いていますが、例えば、mp4からmp3へ変換してからアップロードするなどの処理も可能です。
"use client";
export const Form = () => {
return (
<form
onSubmit={async (e) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
const res = await fetch(`${origin}/api/generate`, {
method: "POST",
body: formData,
});
alert(res.ok ? "Success" : "Something went wrong");
}}
className="flex flex-col gap-8"
>
<div className="flex flex-col">
<label>音声ファイル</label>
<input type="file" name="resource" accept="audio/*" required />
</div>
<div className="flex justify-center">
<button type="submit">
送信
</button>
</div>
</form>
);
};
/app/generate/page.tsx
を用意してフォームコンポーネントをインポートします。
import { Form } from "./components/Form";
export const runtime = "edge";
export default async function GeneratePostPage() {
return (
<div>
<Form />
</div>
);
}
Whisperの精度を高めるテクニック
特段何もしなくても、精度の高い文字起こしが低価格でできるのがWhisperのすごいところですが、ChatGPTと同じくプロンプトを使うこともできるので、一歩進んだ使い方が可能です。
例として、表記ゆれをなくすテクニックを別記事に紹介しているので、興味があれば参考にしてみてください。