今天是這子系列的最後一篇,因為Text-to-Speech沒有AutoML UI介面可以操作,無奈只好讓這邊結束這回合。
按照進度,這篇必須更深入介紹Text-to-Speech API,來看看今天的兩個主題吧。
下面這段code可以列出支援的語言,並提供不同種的發聲方式。
func ListVoices(w io.Writer) error {
ctx := context.Background()
client, err := texttospeech.NewClient(ctx)
if err != nil {
return err
}
// Performs the list voices request.
resp, err := client.ListVoices(ctx, &texttospeechpb.ListVoicesRequest{})
if err != nil {
return err
}
for _, voice := range resp.Voices {
// Display the voice's name. Example: tpc-vocoded
fmt.Fprintf(w, "Name: %v\n", voice.Name)
// Display the supported language codes for this voice. Example: "en-US"
for _, languageCode := range voice.LanguageCodes {
fmt.Fprintf(w, " Supported language: %v\n", languageCode)
}
// Display the SSML Voice Gender.
fmt.Fprintf(w, " SSML Voice Gender: %v\n", voice.SsmlGender.String())
// Display the natural sample rate hertz for this voice. Example: 24000
fmt.Fprintf(w, " Natural Sample Rate Hertz: %v\n",
voice.NaturalSampleRateHertz)
}
return nil
}
透過output可以看到,每個語言大概都會有兩三種發音方式,涵蓋男性及女性的聲音,不過還是沒有中文QQ。
這裡也可以聽到每個supported language的聲音:https://cloud.google.com/text-to-speech/docs/voices
這邊有個特別的東西SSML
,這到底是什麼呢?這可以讓我接續下一個主題!
先看看她長怎樣,我們再來介紹他:
<speak>
Here are <say-as interpret-as="characters">SSML</say-as> samples.
I can pause <break time="3s"/>.
I can play a sound
<audio src="https://www.example.com/MY_MP3_FILE.mp3">didn't get your MP3 audio file</audio>.
I can speak in cardinals. Your number is <say-as interpret-as="cardinal">10</say-as>.
Or I can speak in ordinals. You are <say-as interpret-as="ordinal">10</say-as> in line.
Or I can even speak in digits. The digits for ten are <say-as interpret-as="characters">10</say-as>.
I can also substitute phrases, like the <sub alias="World Wide Web Consortium">W3C</sub>.
Finally, I can speak a paragraph with two sentences.
<p><s>This is sentence one.</s><s>This is sentence two.</s></p>
</speak>
看起來就像是HTML,一種Markup language,透過一些tag
、attribute
去定義(合成)該怎麼念、該停多久。裡面包含
<speak>
root element<break>
停頓<say‑as>
要把內容當什麼唸出來<audio>
定義額外的audio file<p>,<s>
段落<sub>
內容該怎麼念<prosody>
定義速率音量<emphasis>
強調語氣<par>
把多個相關內容關聯在一起(實際上跟順序無關)<seq>
把多個相關內容關聯在一起(跟順序有關)<media>
par與seq內的tag,可定義內容的時間、淡入淡出之類的屬性另外我們也可以傳入SSML讓Text-to-speech發音,像是下面的例子:
func SSMLToSpeech(text string) {
var root string = "./testdata/text_to_speech"
// Instantiates a client.
ctx := context.Background()
client, err := texttospeech.NewClient(ctx)
if err != nil {
log.Fatal(err)
}
// 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_Ssml{Ssml: text},
},
// Build the voice request, select the language code ("en-US") and the SSML
// voice gender ("neutral").
Voice: &texttospeechpb.VoiceSelectionParams{
LanguageCode: "en-US",
SsmlGender: texttospeechpb.SsmlVoiceGender_FEMALE,
},
// 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(root+"/"+filename, resp.AudioContent, 0644)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Audio content written to file: %v\n", filename)
}
呼叫時則傳入SSML:
text_to_speech.SSMLToSpeech("<speak>The <say-as interpret-as=\"characters\">SSML</say-as>" +
"standard <break time=\"1s\"/>is defined by the" +
"<sub alias=\"World Wide Web Consortium\">W3C</sub>.</speak>")
透過上面的方式,就可以產生對應的Output音檔了。
忽然覺得Text-to-speech真是博大精深,竟然還多了個markup language SSML出來。
OK,因為這系列沒有AutoML UI可以操作,所以今天是子系列的最後一章,謝謝大家觀看。
code可以看我的github:https://github.com/josephMG/ithelp-2019/tree/Day-20