🐙

OpenAI で Text to Speach を試した

2024/06/06に公開

はじめに

この記事では OpenAI の Text to Speach を試してみます。

https://platform.openai.com/docs/guides/text-to-speech

Text to Speech とは

OpenAI の Text to Speech とは指定されたテキストから音声を合成する API です。

入力として必要なのは以下の 3 つです。

  • モデル
    • 音声合成に使用するモデル
  • ボイス
    • 音声の特性を指定するためのパラメータ
  • テキスト
    • 音声合成するためのテキスト

また、サポートされている言語はこちらです。

出力は以下です。

  • 音声
    • サポートされている出力形式はこちらを参照ください。

また、OPen AI の Text to Speech API はリアルタイムにオーディオを配信できる Streaming に対応しています。つまり、すべて音声データが作成されるのを待つ必要はありません。

https://platform.openai.com/docs/guides/text-to-speech/streaming-real-time-audio

作業プロジェクトの準備

TypeScript の簡易プロジェクトを作成します。

長いので折りたたんでおきます。

package.json を作成

package.json を作成します。

$ mkdir -p openai-tts-sample
$ cd openai-tts-sample
$ pnpm init

package.json を変更します。

package.json
{
  "name": "openai-tts-sample",
  "version": "1.0.0",
  "description": "",
- "main": "index.js",
- "scripts": {
-   "test": "echo \"Error: no test specified\" && exit 1"
- },
- "keywords": [],
- "author": "",
- "license": "ISC"
+ "main": "index.ts",
+ "scripts": {
+   "typecheck": "tsc --noEmit",
+   "dev": "vite-node index.ts",
+   "build": "tsc"
+ },
+ "keywords": [],
+ "author": "",
}

TypeScript & vite-node をインストール

TypeScript と vite-node をインストールします。補足としてこちらの理由のため ts-node ではなく vite-node を利用します。

$ pnpm install -D typescript vite-node @types/node

TypeScriptの設定ファイルを作成

tsconfig.json を作成します。

$ npx tsc --init

tsconfig.json を上書きします。

tsconfig.json
{
  "compilerOptions": {
    /* Base Options: */
    "esModuleInterop": true,
    "skipLibCheck": true,
    "target": "ES2022",
    "allowJs": true,
    "resolveJsonModule": true,
    "moduleDetection": "force",
    "isolatedModules": true,

    /* Strictness */
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "checkJs": true,

    /* Bundled projects */
    "noEmit": true,
    "outDir": "dist",
    "module": "ESNext",
    "moduleResolution": "Bundler",
    "jsx": "preserve",
    "incremental": true,
    "sourceMap": true,
  },
  "include": ["**/*.ts", "**/*.js"],
  "exclude": ["node_modules", "dist"]
}

git を初期化します。

$ git init

.gitignore を作成します。

$ touch .gitignore
.gitignore
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build
dist/

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local
.env

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts

動作確認コードを作成

動作を確認するためのコードを作成します。

$ touch index.ts
index.ts
console.log('Hello, World');

型チェック

型チェックします。

$ pnpm run typecheck

動作確認

動作確認を実施します。

$ pnpm run dev

Hello, World

コミットします。

$ git add .
$ git commit -m "初回コミット"

OpenAI API キーを取得

OpenAI API キーの取得方法はこちらを参照してください。

https://zenn.dev/hayato94087/articles/85378e1f7bc0e5#openai-の-apiキーの取得

環境変数の設定

環境変数に OpenAI キーを追加します。<your-api-key> に自身の API キーを設定してください。

$ touch .env
.env
# OPENAI_API_KEY は OpenAI の API キーです。
OPENAI_API_KEY='<your-api-key>'

Node.js で環境変数を利用するために dotenv をインストールします。

$ pnpm i -D dotenv

コミットします。

$ touch .env.example
.env.example
# OPENAI_API_KEY は OpenAI の API キーです。
OPENAI_API_KEY='<your-api-key>'
$ git add .
$ git commit -m "環境変数を設定"

OpenAI API のデモを実行

インストール

$ pnpm install -D openai

コードの作成

$ touch openai-tts-demo01.ts
openai-tts-demo01.ts
import 'dotenv/config'

// ファイルシステムを扱うためのモジュール
import fs from "fs";

// ファイルパスを扱うためのモジュール
import path from "path";

// OpenAI SDKをインポート
import { OpenAI } from "openai";

// OpenAI SDKのインスタンスを生成
const openai = new OpenAI();

// OpenAI APIを利用してテキストから音声を生成する
const speechFile = path.resolve("./speech-demo01.mp3");

async function main() {
  // OpenAI APIを利用してテキストから音声を生成
  const mp3 = await openai.audio.speech.create({
    // モデルの指定
    model: "tts-1",
    // ボイスの指定
    voice: "alloy",
    // テキストの指定
    input: "Today is a wonderful day to build something people love!",
  });
  // ファイルパスを表示
  console.log(speechFile);
  // バッファをファイルに書き込む
  const buffer = Buffer.from(await mp3.arrayBuffer());
  // ファイルに書き込む
  await fs.promises.writeFile(speechFile, buffer);
}

// メイン関数を実行
main();

ローカルで実行します。

$ pnpm vite-node openai-tts-demo01.ts

コミットします。

$ git add .
$ git commit -m "OpenAI で Text to Speach を試す"

speech.mp3 が生成されていれば成功です。

コードの解説

環境変数を読み込むために dotenv/config をインポートしています。

import 'dotenv/config'

ファイルシステムを扱うためのモジュールとファイルパスを扱うためのモジュールをインポートしています。

import fs from "fs";
import path from "path";

OpenAI SDK をインポートしています。

import { OpenAI } from "openai";

OpenAI SDK のインスタンスを生成しています。

const openai = new OpenAI();

音声認識の結果を保存する音声ファイルのパスを定義しています。

const speechFile = path.resolve("./speech-demo01.mp3");

main 関数を定義しています。openai.audio.speech.create メソッドを利用してテキストから音声を生成しています。

  • モデルの指定
  • ボイスの指定
  • テキストの指定
const mp3 = await openai.audio.speech.create({
  model: "tts-1",
  voice: "alloy",
  input: "Today is a wonderful day to build something people love!",
});

ファイルパスを表示しています。

console.log(speechFile);

音声認識結果をファイルに書き込みます。

const buffer = Buffer.from(await mp3.arrayBuffer());
await fs.promises.writeFile(speechFile, buffer);

speech-demo01.mp3 が生成されていれば成功です。

日本語の音声を合成

日本語の音声を合成します。

コードの作成

$ touch openai-tts-demo02.ts
openai-tts-demo02.ts
import 'dotenv/config'

// ファイルシステムを扱うためのモジュール
import fs from "fs";

// ファイルパスを扱うためのモジュール
import path from "path";

// OpenAI SDKをインポート
import { OpenAI } from "openai";

// OpenAI SDKのインスタンスを生成
const openai = new OpenAI();

// OpenAI APIを利用してテキストから音声を生成する
const speechFile = path.resolve("./speech-demo02.mp3");

async function main() {
  // OpenAI APIを利用してテキストから音声を生成
  const mp3 = await openai.audio.speech.create({
    // モデルの指定
    model: "tts-1",
    // ボイスの指定
    voice: "alloy",
    // テキストの指定
    input: "えーと、はじめまして、私の名前は太郎です。みんな!はーじめましてー!!はーっはっはっは!!",
  });
  // ファイルパスを表示
  console.log(speechFile);
  // バッファをファイルに書き込む
  const buffer = Buffer.from(await mp3.arrayBuffer());
  // ファイルに書き込む
  await fs.promises.writeFile(speechFile, buffer);
}

// メイン関数を実行
main();

ローカルで実行します。

$ pnpm vite-node openai-tts-demo02.ts

コミットします。

$ git add .
$ git commit -m "OpenAI で 日本語を試す"

コードの解説

コードの解説ではありませんが、音声合成結果に関する考察です。

日本語の音声を聞くと、声に抑揚がなく、感情的な声は苦手なようです。また、笑い語で「はーっはっはっは!!」などは再現できません。

さいごに

OpenAI の Text to Speach を試してみました。日本語の音声合成は、感情的な声や抑揚のある声は苦手なようです。英語の音声合成は、日本語よりも自然な音声合成ができるようです。

作業リポジトリ

こちらが作業リポジトリです。

https://github.com/hayato94087/openai-tts-sample

Discussion