## 資訊科技概論 、 資訊科學教學法 期末簡報
:::info
主題:Python實作 Google gTTS 文字轉語音 及 語音轉換文字
:::
:::success
指導教授:劉富容 教授
報告人:蔡紹文
簡報URL: https://hackmd.io/@jose168/BJ6Lc7HAd
:::
---
# 文字轉語音 模組
## Google gTTS
---
## 安裝gTTS 模組
::: success
<font color='red'>**pip install gtts**</font>
<font color='blue'>**在colab中請使用 !pip install gtts**</font>
:::
----
## 建立gTTS 物件
:::info
**程式中加入 gTTS 套件**
<font color='red'>**from gtts import gTTS**</font>
:::
----
### 建立 gTTS物件
:::info
<font color='red'>**ttsObj = gTTS(text=轉換的文字字串, lang=語言代碼\[, slow=布林值])**</font>
:::
1. $text$:代表要轉換的文字字串
2. $lang$:lang參數為ISO 639-1語言代碼,**zh-tw是中文、en是英文、ja是日文**等
3. $slow$:設定發音速度,**預設值為 False**,若設為 **True 會產生一個發音速度比較慢的 mp3 檔案**
----
## 將語音轉存為mp3檔
:::info
1. 呼叫 $gTTS$ 物件的 $save()$ 方法可以**將轉出來的語音儲存為 mp3 檔**
2. <font color='red'>**save() 的參數代表要儲存的檔名,可以指定儲存路徑,若未指定路徑則存在目前工作目錄。**</font>
:::
```python=1
from gtts import gTTS
tts = gTTS(text="您好,祝您有美好的一天", lang="zh-tw")
tts.save("問候.mp3")
```
---
## pygame 模組
:::info
1. 安裝 pygame: pip install pygame
2. 從 pygame模組 匯入mixer()函式庫
3. 利用mixer()函式庫的music物件之load()載入語音 mp3 檔案
4. 利用mixer()函式庫的music物件之play()播放語音 mp3 檔案
5. 在colab中無法執行:將產生的 mp3 下載後,在電腦或手機上執行
:::
----
# 播放 語音mp3 檔案
```python=1
from pygame import mixer
mixer.init()
mxier.music.load("問候.mp3")
mixer.music.play(loop=0)
```
----
## 以tempfile 模組暫存檔案
1. 文字轉換後的語音檔目的是為了播放,儲存的檔案名稱其實不重要
2. 可以使用tempfile 模組,以暫時命名的檔名來存檔,並且在語音播放結束後將此暫時存的檔案刪除。
3. <font color='red'>tempfile.NamedTemporaryFile(delete=True)會建立一個臨時的檔案名稱,並在結束後刪除此檔。</font>
4. 以下使用自訂函式talk()來處理以每5秒中日英文播放『您好,祝您有美好的一天』。
----
## 暫停檔案播放程式: 只能在有音效的local執行
```python=1
import tempfile
import time
from pygame import mixer
from gtts import gTTS
def talk(text, lang):
with tempfile.NamedTemporaryFile(delete=True) as f:
tts=gTTS(text=text, lang=lang)
tts.save("{}.mp3".format(f.name))
mixer.init()
mixer.music.load("{}.mp3".format(f.name))
mixer.music.play(loops=0)
talk("您好,祝您有美好的一天", "zh-tw")
time.sleep(5)
talk("Hello, have a nice day", "en")
time.sleep(5)
talk("良い一日を", "ja")
time.sleep(5)
```
----
# Google 語音轉換文字
:::info
**本機端的設備一定要有 Microphone 否則無法執行接收Microphone輸入語音資料後轉為文字輸出的運作**
:::
---
## 安裝PyAudio 模組: 麥克風收音
:::info
1. <font color='red'>**PyAudio 不支援Python 3.7,無法以 pip 直接安裝**</font>
2. 必須先下載:
PyAudio-0.2.11-cp37-cp37m-win_amd64.whl檔案,再以離線(手動)方式安裝。
https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyaudio
5. 開啟Windows Command 命令視窗(MAC OS: terminal),切入到PyAudio-0.2.11-cp37-cp37m-win_amd64.whl 下載目錄。
6. 安裝方式:
<font color='red'>**pip install PyAudio-0.2.11-cp37-cp37m-win_amd64.whl**</font>
:::
---
## 安裝SpeechRecognition 模組
1. 開啟AnacondaPrompt 命令視窗
2. 安裝 SpeechRecognition 模組: `pip install SpeechRecognition`
## 建立SpeechRecognition 物件
1. 匯入SpeechRecognition 模組: `import speech_recognition as sr`
2. 建立SpeechRecognition 物件: `SpeechRecognition 物件 = sr.Recognizer()`
## 設定靈敏度
1. 使用energy_threshold 屬性可以調整識別的敏感度
2. 較高的值表示靈敏度較低,較適合在嘈雜的環境中,此值通常在50 到4000 之間: `SpeechRecognition 物件.energy_threshod=4000`
## 打開麥克風並輸入語音
1. 以SpeechRecognition 的Microphone 方法打開麥克風,
2. 再以listen 方法取得麥克風的輸入,並存在audio 變數中。
```python=1
with sr.Microphone() as source:
sudio = r.listen(source)
```
## 語音轉換成文字
1. SpeechRecognition 模組支援的語音檔格式有 WAV、AIFF 及 FLAC。
2. SpeechRecognition 物件的recognize_google 方法可以將從麥克風輸入的語音轉換成文字。`SpeechRecognition 物件.recognize_google(語音變數[, language=語系])`
3. SpeechRecognition 模組預設的辨識語言為英語,若要辨識中文則要加上參數「language="zh-TW"」。例如語音變數為audio,以中文辨識的語法為:`r.recognize_google(audio, language="zh-TW")`
## 範例將中文語音輸入轉換成文字
1. 透過麥克風將我們說的話轉換成文字
2. 若輸入的語音是「結束」則結束程式
```python=1
# 匯入speech_recognition模組
import speech_recognition as sr
# 建立建立SpeechRecognition 物件
r = sr.Recognizer()
# 設定聲音辨識靈敏度
r.energy_threshod = 4000
while True:
try:
# 打開Microphone
with sr.Microphone() as source:
print("請開始說話:")
# 等待語音輸入
audio = r.listen(source)
# 將audio轉成繁體中文
text= r.recognize_google(audio, language="zh-TW")
print(text)
# 判斷是否有結束文字
if text=="結束": break
except sr.UnknownValueError:
print("語音無法辨識")
except sr.RequestError as e:
print("語音無法辨識{}".format(e))
```
# Google Translate文字翻譯
## 安裝googletrans
1. 要在程式中進行文字翻譯,必須先安裝googletrans 模組
2. 開啟Anaconda Prompt命令視窗,安裝googletrans 模組。`pip install googletrans`
## 建立Translator 物件
1. 首先要匯入Translator 模組:`from googletrans import Translator`
2. 建立Translator 物件: `Translator物件 = Translator()`
## 文字翻譯
1. Translator 物件的translate 方法可以將指定的文字翻譯成另一種語言的文字,text 屬性傳回翻譯的結果。
2. 語法: `翻譯結果變數 = translate(text, dest=語系, src=語系).text`
- text:要翻譯的文字字串
- dest:設定翻譯成哪種語言,zh-tw 是中文、en 是英文、ja 是日文,省略時預設為英文。
- src:設定被翻譯文字的語言,如果未指定語言,系統將嘗試自動識別被翻譯文字語言。
```python=1
translator = Translator()
print(translator.translate("您好").text)
```
## 安裝googletrans後無法正常執行
1. 出現錯誤: 'NoneType' object has no attribute 'group'
2. 解決方式:
- 解除安裝googletrans: pip uninstall googletrans
- 安裝google_trans_new: pip install google_trans_new
3. 測試:
- 在command mode 輸入python啟動python
- \>\>\> from google_trans_new import google_translator
- \>\>\> translator = google_translator()
- \>\>\> translate_text = translator.translate('Hola mundo!',lang_src='es',lang_tgt='en')
- \>\>\>print(translate_text)
- 輸出: Hello World!
4. 重新啟動python編輯器,如spyder
## 範例: 多國語言翻擇
1. 利用Googletrans 分別完成 中翻英、英翻中、英文翻譯成日文、日文翻譯成中文。
```python=1
from googletrans import Trsnslator
translator = Translator()
print(translator.translate("您好").text) # Hello
print(translator.translate("Hello", dest="zh-TW").text) # 你好
print(translator.translate("Hello", dest="ja").text) # こんにちは
print(translator.translate("こんにちは", dest="zh-TW", src="ja").text) # 你好
```
## 範例: 多國語言翻擇後用文字轉語音輸出
```python=1
from google_trans_new import google_translator
translator=google_translator()
from pygame import mixer
import tempfile
from gtts import gTTS
def talk(text, lang):
with tempfile.NamedTemporaryFile(delete=True) as f:
tts = gTTS(text=text, lang=lang)
tts.save("{}.mp3".format(f.name))
mixer.init()
mixer.music.load("{}.mp3".format(f.name))
mixer.music.play(loops=0)
import time
translate_text=translator.translate("你好", lang_src="zh-TW", lang_tgt="en")
talk(translate_text, "en")
time.sleep(5)
translate_text=translator.translate("Hello", lang_src="en", lang_tgt="zh-TW")
talk(translate_text, "zh-TW")
time.sleep(5)
translate_text=translator.translate("Hello", lang_src="en", lang_tgt="ko")
talk(translate_text, "ko")
time.sleep(5)
translate_text=translator.translate("你好", lang_src="zh-TW", lang_tgt="ja")
talk(translate_text, "ja")
time.sleep(5)
```
# 使用set_endevent 事件
1. mixer.music.play()在語音播放結束後會觸發mixer.music.set_endevent()事件,並發出一個訊息。
2. 例如: mixer.music.set_endevent(pygame.USEREVENT)發出pygame.USEREVENT訊息,pygame.USEREVENT是一個pygame內建的整數常數。
3. 可以自行定義發出的訊息。
4. 程式執行時會使用Microphone輸入,但聲音輸出也使用Microphone,造成指令相互干擾,以下程式利用mixer.music.set_endevent()來解決此問題。
```python=1
import tempfile
import pygame
import speech_recognition as sr
from pygame import mixer
from gtts import gTTS
mixer.init()
pygame.display.init()
def talk(text, lang):
with tempfile.NamedTemporaryFile(delete=True) as f:
tts = gTTS(text=text, lang=lang)
tts.save("{}.mp3".format(f.name))
mixer.music.load("{}.mp3".format(f.name))
mixer.music.set_endevent(pygame.USEREVENT)
mixer.music.play(loops=0)
isAllowed=True
while True:
try:
for event in pygame.event.get():
if event.type==pygame.USEREVENT:
isAllowed=True
except:
pass
if isAllowed:
try:
with sr.Microphone() as source:
print("開始說話:")
r = sr.Recognizer()
r.energy_threshod = 4000
audio = r.listen(source)
text = r.recognizer_google(audio, languafe="zh-TW")
print(text)
if "讀報" in listen_text:
talk("蘋果傳出將砸百億元擴大投資台灣",'zh-tw')
sr_flag=False # 不允許語音輸入
except sr.UnknownValueError:
print("語音無法辨識")
isAllowed=True
```
# 讀報機
1. 首先利用麥克風輸入的語音當作命令,輸入 讀報、翻譯、上一篇、下一篇、結束 等指令。
2. 收到 讀報 指令即以中文朗讀文章
3. 收到 翻譯 指令則會先將文章翻譯成英文,然後以英文朗讀文章
4. 上一篇、下一篇 可選擇上、下篇文章
5. 結束 指令則結束程式執行。
```python=1
import tempfile
import speech_recognition as sr
import pygame
from pygame import mixer
from googletrans import Translator
from gtts import gTTS
def talk(sentence,lang):
with tempfile.NamedTemporaryFile(delete=True) as f:
tts=gTTS(text=sentence, lang=lang)
tts.save('{}.mp3'.format(f.name))
mixer.music.load('{}.mp3'.format(f.name))
mixer.music.set_endevent(pygame.USEREVENT) # 語音播放結束事件
mixer.music.play(loops=0)
def google_translator(texts,target_lang):
translator = Translator()
return translator.translate(texts,dest=target_lang).text
mixer.init()
pygame.display.init()
news=[]
with open('news.txt','r',encoding='utf-8') as f:
for line in f:
news.append(line)
n=0 # 第幾篇文章
report=news[n]
print(report)
sr_flag=True # 允許語音輸入
while True:
try:
for event in pygame.event.get(): #讀取語音播放結束的事件
if event.type == pygame.USEREVENT: # 語音播放結束
sr_flag=True #允許語音輸入
except:
pass
if sr_flag==True:
try:
# 打開麥克風
with sr.Microphone() as source:
print("說些話吧: ")
r = sr.Recognizer()
# 設定聲音辨識的靈敏度
r.energy_threshold = 4000
audio = r.listen(source) #等待語音輸入
# 語音轉換為文字
listen_text = r.recognize_google(audio, language="zh-TW")
print(listen_text)
if "報" in listen_text:
print(report)
talk(report,'zh-tw')
sr_flag=False # 不允許語音輸入
elif "翻譯" in listen_text or "英文" in listen_text:
res_text = google_translator(report,target_lang='en')
print(res_text)
talk(res_text,'en')
sr_flag=False # 不允許語音輸入
elif "下一篇" in listen_text or "下" in listen_text:
n+=1
if n==len(news):
n=0
report=news[n]
print(report)
elif "上一篇" in listen_text or "上" in listen_text:
n-=1
if n<0:
n=len(news)-1
report=news[n]
print(report)
elif "結束" in listen_text or "停止" in listen_text \
or "拜" in listen_text:
break
else:
print("我不了解什麼是:" + listen_text )
talk("請再說一次!",'zh-tw')
sr_flag=False # 不允許語音輸入
except sr.UnknownValueError:
print("語音無法辨識")
sr_flag=True # 允許語音輸入
except sr.RequestError as e:
print("沒有語音輸入{0}" .format(e))
sr_flag=True # 允許語音輸入
```
{"metaMigratedAt":"2023-06-15T12:45:15.506Z","metaMigratedFrom":"YAML","title":"Google語音、翻譯與智慧讀報機","breaks":true,"description":"翻譯與智慧讀報機","contributors":"[{\"id\":\"240c1e7c-1eda-461f-8d55-5a4f00e12992\",\"add\":12814,\"del\":1522}]"}