日常辦公中,我們經常要開會和寫會議紀要。傳統模式下,我們需要非常認真地聽會議中每一句話,記下自己認為的核心的話,並在會後經過多次修改形成會議紀要。現在,聰明人已 經不那麼幹了,藉助幾百塊的訊飛錄音筆,我們可以一口氣錄下長達三小時的音訊,訊飛還能免費給這些錄音筆錄制的音訊轉成文字,且識別率相當高,可謂非常方便。
不過,假如我們沒買錄音筆,沒借到這樣的錄音筆或者剛好忘了帶,最後只能藉助用機來錄音的時候,面對這樣的音訊,該怎麼低價、快速轉文字,方便我們最後寫會議紀要之類的東東呢?
有錢有VIP的話,這不是問題。比如訊飛聽見,報價是0.33元/分鐘,差不多20塊一個小時,其他廠商提供的To C端的服務,基本價格也是大差不差。如果小爬沒有更省錢的方法,自然就不會有這篇博文了。接下來講講怎麼用廠商API來實現大段的音訊轉文字。
這裡以百度智慧雲提供的API介面為例,且看小爬如何寫Python指令碼,利用這些API,實現低價的音訊轉文字。看了下百度智慧雲的官網提供的服務,關於語音識別這塊,大概的AI能力有這些:
基於上面提到的場景,我們需要藉助的是【音訊檔轉寫】的能力,我們再簡單看下價格,如下圖所示:
計價方式多樣,但是總結就是兩句話:用的越多價格越低,最高單價也就是1.56元/時。看上去比To C的那些語音轉文字的價格實惠多了。那還等什麼,趕緊把程式碼整起來唄?
寫程式碼前,我們需要看看它的技術檔案:語音技術 (baidu.com),這裡面不僅有介面API,還提供的python的Demo範例。但是你要指望這Demo能直接用,就太天真了。
簡單點說,我們需要先在百度智慧雲上【音訊檔轉寫】的詳情頁,點選【立即使用】,按照說明,新建一個應用,勾選上需要的AI能力,這樣,我們就可以拿到百度給這個應用獨有的API_KEY以及SECRET_KEY。
由於音訊很長,所以轉文字需要一定的時間,百度給的介面做成非同步的了。也就是說我們需要兩個指令碼,其中一個用來建立轉音訊的任務,另一個指令碼用來請求結果。先來魔改官方給的Demo範例來建立任務,每次的請求之前,我們需要向API介面拿到單次請求的Token,獲取Access_token的程式碼大概如下:
import requests,json,time,ssl from urllib.request import urlopen,Request from urllib.error import URLError from urllib.parse import urlencode timer = time.perf_counter ssl._create_default_https_context = ssl._create_unverified_context #填寫百度控制檯中相關開通了「音訊檔轉寫」介面的應用的的API_KEY及SECRET_KEY API_KEY = 'Your API Key' SECRET_KEY = 'Your Secret Key' """ 獲取請求TOKEN start 通過開通音訊檔轉寫介面的百度應用的API_KEY及SECRET_KEY獲取請求token""" class DemoError(Exception): pass TOKEN_URL = 'https://openapi.baidu.com/oauth/2.0/token' # SCOPE = 'brain_bicc' # 有此scope表示有asr能力,沒有請在網頁裡勾選 bicc SCOPE = 'brain_asr_async' # 有此scope表示有asr能力,沒有請在網頁裡勾選 # SCOPE = 'brain_enhanced_asr' # 有此scope表示有asr能力,沒有請在網頁裡勾選 def fetch_token(): params = {'grant_type': 'client_credentials', 'client_id': API_KEY, 'client_secret': SECRET_KEY} post_data = urlencode(params) post_data = post_data.encode( 'utf-8') req = Request(TOKEN_URL, post_data) try: f = urlopen(req) result_str = f.read() except URLError as err: print('token http response http code : ' + str(err.code)) result_str = err.read() result_str = result_str.decode() # print(result_str) result = json.loads(result_str) # print(result) if ('access_token' in result.keys() and 'scope' in result.keys()): if not SCOPE in result['scope'].split(' '): raise DemoError('scope is not correct') # print('SUCCESS WITH TOKEN: %s ; EXPIRES IN SECONDS: %s' % (result['access_token'], result['expires_in'])) return result['access_token'] else: raise DemoError('MAYBE API_KEY or SECRET_KEY not correct: access_token or scope not found in token response') """ 獲取鑑權結束,TOKEN end """
拿到Access_Token後,我們就可以根據API建立任務了,範例程式碼如下:
""" 傳送識別請求 """ #待進行語音識別的音訊檔url地址,需要可公開存取。建議使用百度雲物件儲存(https://cloud.baidu.com/product/bos.html) def create_task(speech_url): url = 'https://aip.baidubce.com/rpc/2.0/aasr/v1/create' #建立音訊轉寫任務請求地址 body = { "speech_url": speech_url, "format": "wav", #音訊格式,支援pcm,wav,mp3,音訊格式轉化可通過開源ffmpeg工具(https://ai.baidu.com/ai-doc/SPEECH/7k38lxpwf)或音訊處理軟體 "pid": 1537, #模型pid,1537為普通話輸入法模型,1737為英語模型 "rate": 16000 #音訊取樣率,支援16000取樣率,音訊格式轉化可通過開源ffmpeg工具(https://ai.baidu.com/ai-doc/SPEECH/7k38lxpwf)或音訊處理軟體 } token = {"access_token":fetch_token()} headers = {'content-type': "application/json"} response = requests.post(url,params=token,data = json.dumps(body), headers = headers) # 返回請求結果資訊,獲得task_id,通過識別結果查詢介面,獲取識別結果 textMsg=response.json() print(textMsg) return textMsg.get("task_id")
需要注意的是,該API不支援讀原生的音訊檔,而是要求提起將音訊上傳到公網上,要支援公開存取,這個方法中的Speech_url引數,它指的是待進行語音識別的音訊檔url地址,官方建議使用百度雲物件儲存(https://cloud.baidu.com/product/bos.html),不過小爬在寫這個例子的時候,這個官網莫名其妙載入非常慢,體驗很差,具體原因不詳,最好小爬只好選擇了其他廠商的類似服務,比如七牛雲。不用擔心,對於普通使用者,有10GB的免費的每月儲存空間。另外,這個方法最終可以返回任務的Task_id,它的重要性不言而喻,我們就是通過它來得到最終的結果。
開通七牛雲賬號之後,我們按照提示,將待轉的音訊儲存到七牛雲端儲存伺服器 公開路徑。限於篇幅,小爬對具體的操作就不過多贅述了。這裡必須是公開路徑,否則百度的API沒法存取私有的七牛雲生成的儲存音訊的URL。你在擔心資訊暴露了對不對?哈哈,你的URL不到處分享,即使在公網上,也不會有人知道的。另外,如果實在擔心,我們可以利用它建立完任務併成功轉為文字後,再去賬號上刪除這段音訊,這下顧慮可以打消了吧?
萬事俱備後,我們需要結合檢視結果的api來獲取最終的文字,對了,獲取結果的API,同樣是需要事先申請Token的,您需要再次藉助上面提到的fetch_token方法。當token和task_id都準備好之後,剩下的事兒就簡單多了,範例如下:
""" 傳送查詢結果請求 """ #轉寫任務id列表,task_id是通過建立音訊轉寫任務時獲取到的,每個音訊任務對應的值 task_id_list = [ "task_id", ] for task_id in task_id_list: url = 'https://aip.baidubce.com/rpc/2.0/aasr/v1/query' #查詢音訊任務轉寫結果請求地址 body = { "task_ids": [task_id], } token = {"access_token":fetch_token()} headers = {'content-type': "application/json"} response = requests.post(url,params=token,data = json.dumps(body), headers = headers) print(json.dumps(response.json(), ensure_ascii=False))
趕緊學起來吧,可以幫您省下好多銀子呢,這些銀子用來幹啥不香呢?如果您技術過硬,還可以利用大廠的這些api搭建自己的AI服務,建立自己的【語音轉文字】To C產品,這差價不是掙得美滋滋?
快來關注本公眾號 獲取更多爬蟲、資料分析的知識!