使用Python和百度語(yǔ)音識(shí)別生成視頻字幕的實(shí)現(xiàn)
從視頻中提取音頻
安裝 moviepy
pip install moviepy
相關(guān)代碼:
audio_file = work_path + '\\out.wav' video = VideoFileClip(video_file) video.audio.write_audiofile(audio_file,ffmpeg_params=['-ar','16000','-ac','1'])
根據(jù)靜音對(duì)音頻分段
使用音頻庫(kù) pydub,安裝:
pip install pydub
第一種方法:
# 這里silence_thresh是認(rèn)定小于-70dBFS以下的為silence,發(fā)現(xiàn)小于 sound.dBFS * 1.3 部分超過(guò) 700毫秒,就進(jìn)行拆分。這樣子分割成一段一段的。 sounds = split_on_silence(sound, min_silence_len = 500, silence_thresh= sound.dBFS * 1.3) sec = 0 for i in range(len(sounds)): s = len(sounds[i]) sec += s print('split duration is ', sec) print('dBFS: {0}, max_dBFS: {1}, duration: {2}, split: {3}'.format(round(sound.dBFS,2),round(sound.max_dBFS,2),sound.duration_seconds,len(sounds)))
感覺(jué)分割的時(shí)間不對(duì),不好定位,我們換一種方法:
# 通過(guò)搜索靜音的方法將音頻分段 # 參考:https://wqian.net/blog/2018/1128-python-pydub-split-mp3-index.html timestamp_list = detect_nonsilent(sound,500,sound.dBFS*1.3,1) for i in range(len(timestamp_list)): d = timestamp_list[i][1] - timestamp_list[i][0] print("Section is :", timestamp_list[i], "duration is:", d) print('dBFS: {0}, max_dBFS: {1}, duration: {2}, split: {3}'.format(round(sound.dBFS,2),round(sound.max_dBFS,2),sound.duration_seconds,len(timestamp_list)))
輸出結(jié)果如下:
感覺(jué)這樣好處理一些
使用百度語(yǔ)音識(shí)別
現(xiàn)在百度智能云平臺(tái)創(chuàng)建一個(gè)應(yīng)用,獲取 API Key 和 Secret Key:
獲取 Access Token
使用百度 AI 產(chǎn)品需要授權(quán),一定量是免費(fèi)的,生成字幕夠用了。
''' 百度智能云獲取 Access Token ''' def fetch_token(): params = {'grant_type': 'client_credentials', 'client_id': API_KEY, 'client_secret': SECRET_KEY} post_data = urlencode(params) if (IS_PY3): 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.errno)) result_str = err.reason if (IS_PY3): 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()): print(SCOPE) if SCOPE and (not SCOPE in result['scope'].split(' ')): # SCOPE = False 忽略檢查 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')
使用 Raw 數(shù)據(jù)進(jìn)行合成
這里使用百度語(yǔ)音極速版來(lái)合成文字,因?yàn)楣俜浇榻B專有GPU服務(wù)集群,識(shí)別響應(yīng)速度較標(biāo)準(zhǔn)版API提升2倍及識(shí)別準(zhǔn)確率提升15%。適用于近場(chǎng)短語(yǔ)音交互,如手機(jī)語(yǔ)音搜索、聊天輸入等場(chǎng)景。 支持上傳完整的錄音文件,錄音文件時(shí)長(zhǎng)不超過(guò)60秒。實(shí)時(shí)返回識(shí)別結(jié)果
def asr_raw(speech_data, token): length = len(speech_data) if length == 0: # raise DemoError('file %s length read 0 bytes' % AUDIO_FILE) raise DemoError('file length read 0 bytes') params = {'cuid': CUID, 'token': token, 'dev_pid': DEV_PID} #測(cè)試自訓(xùn)練平臺(tái)需要打開以下信息 #params = {'cuid': CUID, 'token': token, 'dev_pid': DEV_PID, 'lm_id' : LM_ID} params_query = urlencode(params) headers = { 'Content-Type': 'audio/' + FORMAT + '; rate=' + str(RATE), 'Content-Length': length } url = ASR_URL + "?" + params_query # print post_data req = Request(ASR_URL + "?" + params_query, speech_data, headers) try: begin = timer() f = urlopen(req) result_str = f.read() # print("Request time cost %f" % (timer() - begin)) except URLError as err: # print('asr http response http code : ' + str(err.errno)) result_str = err.reason if (IS_PY3): result_str = str(result_str, 'utf-8') return result_str
生成字幕
字幕格式: https://www.cnblogs.com/tocy/p/subtitle-format-srt.html
生成字幕其實(shí)就是語(yǔ)音識(shí)別的應(yīng)用,將識(shí)別后的內(nèi)容按照 srt 字幕格式組裝起來(lái)就 OK 了。具體字幕格式的內(nèi)容可以參考上面的文章,代碼如下:
idx = 0 for i in range(len(timestamp_list)): d = timestamp_list[i][1] - timestamp_list[i][0] data = sound[timestamp_list[i][0]:timestamp_list[i][1]].raw_data str_rst = asr_raw(data, token) result = json.loads(str_rst) # print("rst is ", result) # print("rst is ", rst['err_no'][0]) if result['err_no'] == 0: text.append('{0}\n{1} --> {2}\n'.format(idx, format_time(timestamp_list[i][0]/ 1000), format_time(timestamp_list[i][1]/ 1000))) text.append( result['result'][0]) text.append('\n') idx = idx + 1 print(format_time(timestamp_list[i][0]/ 1000), "txt is ", result['result'][0]) with open(srt_file,"r+") as f: f.writelines(text)
總結(jié)
我在視頻網(wǎng)站下載了一個(gè)視頻來(lái)作測(cè)試,極速模式從速度和識(shí)別率來(lái)說(shuō)都是最好的,感覺(jué)比網(wǎng)易見外平臺(tái)還好用。
到此這篇關(guān)于使用Python和百度語(yǔ)音識(shí)別生成視頻字幕的文章就介紹到這了,更多相關(guān)Python 百度語(yǔ)音識(shí)別生成視頻字幕內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python數(shù)據(jù)分析之時(shí)間序列分析詳情
這篇文章主要介紹了python數(shù)據(jù)分析之時(shí)間序列分析詳情,時(shí)間序列分析是基于隨機(jī)過(guò)程理論和數(shù)理統(tǒng)計(jì)學(xué)方法,具體詳細(xì)內(nèi)容介紹,需要的小伙伴可以參考一下2022-08-08python自然語(yǔ)言編碼轉(zhuǎn)換模塊codecs介紹
這篇文章主要介紹了python自然語(yǔ)言編碼轉(zhuǎn)換模塊codecs介紹,codecs專門用作編碼轉(zhuǎn)換,通過(guò)它的接口是可以擴(kuò)展到其他關(guān)于代碼方面的轉(zhuǎn)換,需要的朋友可以參考下2015-04-04python創(chuàng)建文本文件的簡(jiǎn)單方法
在本篇內(nèi)容里小編給大家整理分享的是一篇關(guān)于python創(chuàng)建文本文件的簡(jiǎn)單方法,有需要的朋友們可以參考學(xué)習(xí)下。2020-08-08Python實(shí)現(xiàn)雙X軸雙Y軸繪圖的示例詳解
這篇文章主要介紹了如何利用fig.add_subplot和axes.twinx().twiny()方法實(shí)現(xiàn)雙X軸雙Y軸繪圖,文中的示例代碼講解詳細(xì),快跟隨小編一起動(dòng)手嘗試一下吧2022-04-04Python常見報(bào)錯(cuò)解決之SciPy和NumPy版本沖突
Scipy是基于Numpy的科學(xué)計(jì)算工具庫(kù),方便、易于使用、專為科學(xué)和工程設(shè)計(jì),是一個(gè)用于數(shù)學(xué)、科學(xué)、工程領(lǐng)域的常用軟件包,這篇文章主要給大家介紹了關(guān)于Python常見報(bào)錯(cuò)解決之SciPy和NumPy版本沖突的相關(guān)資料,需要的朋友可以參考下2024-03-03Python基于回溯法子集樹模板解決最佳作業(yè)調(diào)度問(wèn)題示例
這篇文章主要介紹了Python基于回溯法子集樹模板解決最佳作業(yè)調(diào)度問(wèn)題,簡(jiǎn)單說(shuō)明了作業(yè)調(diào)度問(wèn)題并結(jié)合實(shí)例形式給出了Python使用回溯法子集樹模板實(shí)現(xiàn)最佳作業(yè)調(diào)度問(wèn)題的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-09-09Django之第三方平臺(tái)QQ授權(quán)登錄的實(shí)現(xiàn)
本文主要介紹了Django之第三方平臺(tái)QQ授權(quán)登錄的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05Python使用configparser庫(kù)讀取配置文件
這篇文章主要介紹了Python使用configparser庫(kù)讀取配置文件,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02