Google Text-To-Speechで記事を音声ファイルに変換する

Blog Single

ウォーキング、ジョギング、満員電車などでスマホをいじれないけどイヤホンで音は聞けるという状態で文章を音声再生したいといったことはないでしょうか。

以前に書いた記事でGoogle Cloud Speech APIを用いて音声ファイルの文字起こしをするという記事を上げましたが、今回はその逆で、GoogleのText-to-Speech APIでテキストから音声ファイルへの変換を行います。

Cloud Text-to-Speech – 音声合成  | 公式ドキュメント

準備

GCPでのプロジェクトの作成、認証が必要ですが、その手順は前回の記事と同じですので、その手順に関しては前回の記事を参照してください。

今回も、GCP Consoleからサービスアカウントキー情報を含んだJSONファイルをダウンロードし、そのJSONファイルで認証を行う方法を利用します。

違う点としては、APIの有効化で、以前はCloud Speech APIを有効にしましたが、今回利用するのはCloud Text-to-Speech APIですので、そちらを選択します。

今回はGo言語を用いて作成しますが、公式のサンプルでは、C#、Java、Node.js、Python、Rubyなども用意されています。

ライブラリのインストール

Cloud Text-to-Apeech APIを利用するためのライブラリ

go get -u cloud.google.com/go/texttospeech/apiv1

今回は、投稿した記事をスクレイピングでテキストを取得して、そのテキストから音声ファイルを作成するため、スクレイピングに利用するライブラリもインストールします。

go get github.com/PuerkitoBio/goquery

プログラムの作成

プログラムは、Googleが用意しているサンプルプログラムを元に音声化するテキストと、言語設定を変えて、プログラムを作成します。

公式のサンプルプログラム

Go言語でのスクレイピングの詳細に関しては、以前に書いた記事を参考にしてください。

プログラム

main.go

package main

import (
    "context"
    "fmt"
    "io/ioutil"
    "log"

    texttospeech "cloud.google.com/go/texttospeech/apiv1"
    texttospeechpb "google.golang.org/genproto/googleapis/cloud/texttospeech/v1"

    "github.com/PuerkitoBio/goquery"
)

func main() {
    // Instantiates a client.
    ctx := context.Background()

    client, err := texttospeech.NewClient(ctx)
    if err != nil {
        log.Fatal(err)
    }

    text := fetchArticle("https://blog.fox-hound.tech/783/")

    // Perform the text-to-speech request on the text input with the selected
    // voice parameters and audio file type.
    req := texttospeechpb.SynthesizeSpeechRequest{
        // Set the text input to be synthesized.
        Input: &texttospeechpb.SynthesisInput{
            InputSource: &texttospeechpb.SynthesisInput_Text{Text: text},
        },
        // Build the voice request, select the language code ("en-US") and the SSML
        // voice gender ("neutral").
        Voice: &texttospeechpb.VoiceSelectionParams{
            LanguageCode: "ja-JP",
            SsmlGender:   texttospeechpb.SsmlVoiceGender_NEUTRAL,
        },
        // Select the type of audio file you want returned.
        AudioConfig: &texttospeechpb.AudioConfig{
            AudioEncoding: texttospeechpb.AudioEncoding_MP3,
        },
    }

    resp, err := client.SynthesizeSpeech(ctx, &req)
    if err != nil {
        log.Fatal(err)
    }

    // The resp's AudioContent is binary.
    filename := "output.mp3"
    err = ioutil.WriteFile(filename, resp.AudioContent, 0644)
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Audio content written to file: %v\n", filename)
}

// Fox Hound TechのURLから記事の文章を取得
func fetchArticle(url string) string {

    doc, err := goquery.NewDocument(url)
    if err != nil {
        fmt.Print("url scarapping failed")
    }
    title := doc.Find("#single-post-title").Text()
    text := doc.Find("div.entry-content").Text()

    return title + text
}

サンプルプログラムから変更した点は、音声ファイルに出力するテキストを取得する処理の追加と言語の設定をen-USからja-JPに変更した点だけです。

実際に実行して出力された音声ファイルはこちらです。

まとめ

出力された音声ファイルを聴いた印象は、>という記号を「より大きい」と読み上げていたりするのが気になったりはしましたが、想像していた以上に聞き取りやすい声で長文の読み上げなどにはかなり向いていると思います。

使い方によってはかなり便利に使えそうですし、GCPには他にも様々な便利なAPIなどが用意されているので、ぜひ使ってみてください。

参考

Quickstart: Using the Client Libraries  |  Cloud Text-to-Speech API  |  Google Cloud

Google Cloud Text-to-Speech の使い方 日本語テキストを読み上げさせてみよう | あぱーブログ

Posted by MatsumotoKazuki
PHPやJavaで開発を行っているエンジニア。 LOLというゲームの試合を観戦するのが好きです。

Other Posts: