日常辦公中,我們經常要開會和寫會議紀要。傳統模式下,我們需要非常認真地聽會議中每一句話,記下自己認爲的核心的話,並在會後經過多次修改形成會議紀要。現在,聰明人已 經不那麼幹了,藉助幾百塊的訊飛錄音筆,我們可以一口氣錄下長達三小時的音頻,訊飛還能免費給這些錄音筆錄制的音頻轉成文本,且識別率相當高,可謂非常方便。
不過,假如我們沒買錄音筆,沒借到這樣的錄音筆或者剛好忘了帶,最後只能藉助用機來錄音的時候,面對這樣的音頻,該怎麼低價、快速轉文本,方便我們最後寫會議紀要之類的東東呢?
有錢有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產品,這差價不是掙得美滋滋?
快來關注本公衆號 獲取更多爬蟲、數據分析的知識!