如何利用AZure自動為視頻配音
簡 介: 本文測試了將AZure的文本生成的語音信號分割成不同的片段,適合進行視頻的后期配音。 分割利用了每一段語音之間的 0.5 秒中的間隔,這樣可以將每一段的語音對應的分割出來。
**關(guān)鍵詞
**: AZure
01 文字轉(zhuǎn)語音
一、背景介紹
??如下是Azure網(wǎng)站提供的文字轉(zhuǎn)換成語音的界面。 文本轉(zhuǎn)語音[1]

二、轉(zhuǎn)換步驟
??TEASOFT語音配音的轉(zhuǎn)換布置:
將TEASOFT配音導出;
轉(zhuǎn)換到Azure網(wǎng)站進行播放,同期使用 Audacity進行錄制;
將錄制的語音進行切分。使用時長完成切分,存儲在語音命名的 .MP3, .WAV 文件中;
??播放語音是完成這部分的語音播放。
1、TEASOFT導出文字
??利用BSIRFORM上的 “Action” 按鈕生成視頻配音文字。 具體操作: alt+點擊Action 。

??TEASOFT 生成文字時,每一個Action中的文字形成一行。并對每一行進行如下的處理:
將其中的句號“。”,修改成逗號“,”。
將其中的半角句號空格“. ”,修改成逗號空格。
??下面是轉(zhuǎn)化后的文字樣本。
今天在Youtube上,
看到一位Up主介紹了波形折疊電路,
并展示了它應用在電子音樂信號處理方面,
那么什么是波形折疊?
如何利用電路來實現(xiàn)呢?
首先討論一下什么是波形折疊?
以這三個波形為例進行說明,
對于三角信號波形,
如果它的幅值超過一個閾值,
上面的波形則鏡像折疊到閾值下面,
這就是波形折疊,
對于鋸齒信號波形,
同樣,
進行折疊之后,它變成了三角波,
對于方波信號,
信號折疊之后,
波形仍然是方波,
只是幅值下降,
波形沒有變化,
下面,
如何利用電路來實現(xiàn)呢?
視頻中給出了從簡單到復雜的實現(xiàn)方法,
下面對此進行測試一下,
下面搭建單管折疊電路,
總共有三個器件,
這是電路原理圖,NPN三極管使用8050.
從MSO24的信號源輸出500Hz,
峰峰值為5V的三角波,
藍色波形是輸出的波形,
這是讀入內(nèi)存后的波形數(shù)據(jù),
下面測量PNP折疊電路,
這是電路輸出波形,
從MSO24讀取的波形數(shù)據(jù),
將上面兩個電路并聯(lián)在一起,形成雙邊這點電路,
這對峰峰值為1V的三角波處理結(jié)果,
調(diào)整不同幅值,
可以看到折疊信號始終維持在正負0.25V之內(nèi),
本文討論了波形折疊電路,
根據(jù)Youtube上的UP主介紹的簡單點路,
搭建了基于三極管的波形折疊電路,
驗證了相關(guān)電路的工作原理,
2、AZure 文字轉(zhuǎn)換語音
??進入 AZure 文本轉(zhuǎn)語音界面。 文本轉(zhuǎn)語音[2] : https://azure.microsoft.com/zh-cn/products/cognitive-services/text-to-speech/#overview

??將上述文字拷貝到界面中的對話框內(nèi)。選擇合適的語言,語音,說話風格以及角色扮演等。

??使用 Audacity軟件進行錄制語音合成結(jié)果,并存儲到 .WAV 文件。

??下面是上述文本錄制后的 MP3文件。

三、語音分割
1、語音分割原理
??分割每個語音利用了每一段之間存在 0.675秒的時間間隔。 搜尋語音文件中所有長度大于等于 0.675 秒的時間間隔,將對應的數(shù)據(jù)存儲在各自的語音文件中。

2、語音分割算法
??根據(jù) ?電話雙音頻撥碼信號采集[2] 所采用的 Python 對于語音處理的相關(guān)算法,進行上述合成語音的分割。
(1)語音文件讀取
??讀取語音波形文件,獲得相應的參數(shù)和數(shù)據(jù)。
from?headm?import?*
from?scipy.io?import?wavfile
wavefile?=?r'D:\Temp\11.wav'
sample_rate,?sig?=?wavfile.read(wavefile)
printf(sample_rate,?shape(sig))
??保存的語音文件的采樣率為 44100Hz,通過數(shù)量長度除以采樣率,可以知道語音文件時間長度為 115.8s 。
44100 (5107840, 2)
??繪制其中一個聲道的數(shù)據(jù)波形如下:

(2)語音分割參數(shù)
??對于上述錄制的音頻文件波形進行分析,獲得語音分割參數(shù):
? ● ?語音分割參數(shù):
???靜音幅值
: ±25
???靜音時間長度
: 0.5s

3、語音分隔程序
(1)程序代碼
#!/usr/local/bin/python
#?-*-?coding:?gbk?-*-
#******************************
#?SPS.PY???????????????????????--?by?Dr.?ZhuoQing?2022-10-03
#???Seperate?speak?signal?into?segment.
#???Usage:??sps?wavefile?silencevalue(int)?silencetime(float)
#
#???Before?using?sps,?copy?all?voice?string?into?clipboard.
#
#?Note:
#******************************
from?headm?import?*
from?scipy.io?import?wavfile
from?pydub?import?AudioSegment
wavefile?=?r'D:\Temp\11.wav'
#------------------------------------------------------------
try:
????if?not?os.path.exists(r'd:\temp'):
????????os.makedirs(r'd:\temp')
????if?not?os.path.exists(r'd:\temp\VOICE'):
????????os.makedirs(r'd:\temp\VOICE')
except?OSError:
????printf("Error?:Creating?directory?of?data.")
#------------------------------------------------------------
silencevalue?=?25???????????????????#?Silence?max?value
silencetime??=?0.5??????????????????#
mp3flag?=?0
#------------------------------------------------------------
strall?=?[s.strip('\r')?for?s?in?clipboard.paste().split('\n')?if?len(s)?>?0]
for?s?in?sys.argv:
????fname?=?os.path.join(r'd:\temp',?'%s.WAV'%s)
????if?os.path.isfile(fname):
????????wavefile?=?fname
????????continue
????fname?=?os.path.join(r'd:\temp',?'%s.MP3'%s)
????if?os.path.isfile(fname):
????????wavefile?=?fname
????????mp3flag?=?1
????????continue
????if?s.isdigit():
????????silcencevalue?=?int(s)
????????if?silencevalue?>?1000:
????????????silencevalue?=?1000
????????continue
????if?s.replace('.',?'').isdigit():
????????silcentime?=?float(s)
printff(wavefile,?silencevalue,?silencetime)
#------------------------------------------------------------
if?mp3flag?==?0:
????sample_rate,?sig?=?wavfile.read(wavefile)
????sigdata?=?array(sig[:,0])
else:
????sample_rate?=?44100
????sound?=?AudioSegment.from_file(file=wavefile)
????left?=?sound.split_to_mono()[0]
????sig?=?frombuffer(left._data,?int16)
????sigdata?=?array(sig)
#------------------------------------------------------------
sigdata[(sigdata?>?-silencevalue)?&?(sigdata?<?silencevalue)]?=?0
sigdata[(sigdata?<=?-silencevalue)?|?(sigdata?>=?silencevalue)]?=?1
sigone?=?where(sigdata?==?1)[0]
sigdelta?=?array([x2-x1?for?x1,x2?in?zip(sigone[0:-1],?sigone[1:])])
deltamin?=?int(sample_rate*silencetime)
sigmax?=?where(sigdelta?>?deltamin)[0]
sigsegment?=[sigone[0]]
for?sm?in?sigmax:
????sigsegment.append(sigone[sm+1])
sigsegment.append(sigone[-1])
#------------------------------------------------------------
printff('Voice?Segment:%d'%len(sigsegment),?'Voice?String:%d'%len(strall))
printf('\a')
if?len(sigsegment)?-?len(strall)?!=?1:
????printf("Voice?String?Number?error?!\a")
????exit()
#------------------------------------------------------------
for?i?in?range(len(sigsegment)?-?1):
????startid?=?sigsegment[i]
????endid?=?sigsegment[i+1]?-?sample_rate*3//4
????wavefilename?=?'%04d.wav'%i
????if?i?<?len(strall):
????????sa?=?strall[i].replace(',',?'').replace(',','').replace('.','').replace('。',?'').replace(';','')
????????wavefilename?=?'%s.wav'%sa
????outfile?=?os.path.join(r'd:\temp\VOICE',?wavefilename)
????if?mp3flag?==?0:
????????wavfile.write(outfile,?sample_rate,?sig[startid:endid,?:])
????else:?wavfile.write(outfile,?sample_rate,?sig[startid:endid])
????printf(outfile)
tspbeep(1800,?100)
#------------------------------------------------------------
#????????END?OF?FILE?:?SPS.PY
#******************************
(2)程序用法
??在 sps 命令后面可以添加 wave 文件, 靜音幅度, 靜音時間等參數(shù)。 需要注意的是, 在使用 sps 之前,需要將聲音的文本拷貝到剪切板中。
??分割后的文件存儲在 d:\temp\VOICE 目錄中。
四、分割測試
??對于上述程序進行了測試,它準確的將所有的語音進行了分割。

※ 總??結(jié) ※
??本文測試了將AZure的文本生成的語音信號分割成不同的片段,適合進行視頻的后期配音。 分割利用了每一段語音之間的 0.5 秒中的間隔,這樣可以將每一段的語音對應的分割出來。
參考資料
[1]
文本轉(zhuǎn)語音: https://azure.microsoft.com/zh-cn/products/cognitive-services/text-to-speech/#overview
[2]電話雙音頻撥碼信號采集: https://blog.csdn.net/zhuoqingjoking97298/article/details/122606221?spm=1001.2014.3001.5501