一、云狐簡介
云狐語音識別軟體是基于百度智能云,由進擊的狐貍進行開發的一款軟體,注意,因為核心類代碼是2017年就已經寫好的了,所以使用的C# SDK包不是最新的,云狐目前支持的平臺是Windows系統平臺,使用時需要安裝微軟最新的.net framework ,云狐的主要功能是長時間的語音識別,支持時長超過一分鐘的各種型別的語音檔案識別,缺點就是速度較慢一些,
云狐視頻演示及代碼決議的視頻鏈接:
https://v.qq.com/x/page/j3023vgs9yz.html
云狐語音識別軟體下載:
https://blog.csdn.net/ciel_arc/article/details/103172138
另外,云狐和云貓實際上是姐妹軟體,因為他們都是基于百度智能云,用C#進行開發的,使用的是百度最新的人工智能技術,而且他們目前都是免費的,這里聯動一下,對云貓OCR和云狐語音感興趣的同學,可以百度搜索“云貓OCR”或“云狐語音” 進行了解,
二、云狐的簡單評測
云狐軟體自帶有計時功能,我們可以簡單做一下評測,從上文視頻演示的結果可以看出,1分鐘左右的語音檔案,云狐可以在10秒以內識別完畢,而30分鐘左右的語音檔案,云狐需要120秒即2分鐘左右,才能識別完畢,從中推算出識別速度大概是4秒/分鐘,
三、云狐軟體的代碼原理
百度智能云給出的長語音識別介面只支持一分鐘以內的語音檔案的識別,而對于超過一分鐘的語音檔案識別,我們需要怎么做呢?
云狐軟體的原理就是:把超過一分鐘的檔案進行切片,切成若干個小于或者等于一分鐘時長的語音檔案,對每個切片檔案呼叫百度云語音識別介面進行識別,再把結果串聯起來即可,
四、云狐的代碼簡明決議
(一)核心類foxSpeechDemo
namespace foxAudio2Word
{
class foxSpeechDemo
{
private readonly Asr _asrClient;
public foxSpeechDemo(string myAPIKey,string mySecretKey)
{
_asrClient = new Asr(myAPIKey,mySecretKey);
}
// 識別本地檔案
public string AsrData(string pcmFilePath)
{
var data = File.ReadAllBytes(pcmFilePath);
var result = _asrClient.Recognize(data, "pcm", 16000);
return result.ToString();
}
}
}
上面的代碼是根據百度SDK包檔案,進行少量改動實作的,注意為了簡便,這里貼出的代碼段可能跟具體的云狐實作代碼有一些出入,
不是任何一個語音檔案都可以交給百度智能云直接識別,檔案需要預處理,不然識別效果會很差,具體來說,作者用FFmpeg對語音檔案進行預處理,然后再用百度介面識別,FFmpeg的命令列預處理類似下面的形式:
ffmpeg -y -i 003_16k.wav -acodec pcm_s16le -f s16le -ac 1 -ar 16000 16k.pcm
(二)預處理的輔助函式
共有大概4個關于預處理的輔助函式,代碼如下:
1.此函式的主要功能是用C#程式自動執行命令列陳述句,它可執行任何陳述句的命令列,string cmdStr是形參,可以將命令列陳述句賦值給cmdStr進行執行,
private string myCmdFun(string cmdStr)
{
try
{
Process CmdProcess = new Process();
CmdProcess.StartInfo.FileName = "cmd.exe";
CmdProcess.StartInfo.CreateNoWindow = true; // 不創建新視窗
CmdProcess.StartInfo.UseShellExecute = false; //不啟用shell啟動行程
CmdProcess.StartInfo.RedirectStandardInput = true; // 重定向輸入
CmdProcess.StartInfo.RedirectStandardOutput = true; // 重定向標準輸出
CmdProcess.StartInfo.RedirectStandardError = true; // 重定向錯誤輸出
//CmdProcess.StartInfo.Arguments = "/c " + "=====cmd命令======";//“/C”表示執行完命令后馬上退出
//string cmdStr = "ffmpeg -y -i 003_16k.wav -acodec pcm_s16le -f s16le -ac 1 -ar 16000 16k.pcm";
CmdProcess.StartInfo.Arguments = "/c " + cmdStr;//“/C”表示執行完命令后馬上退出
CmdProcess.Start();//執行
string temp = CmdProcess.StandardOutput.ReadToEnd();//輸出
CmdProcess.WaitForExit();//等待程式執行完退出行程
CmdProcess.Close();//結束
return temp;
}
catch (Exception ex)
{
return ex.ToString();
}
}
2.此函式表示利用ffprobe命令列獲取語音檔案的時長資訊,以便對語音檔案進行分割,注意回傳值是整形變數,比如語音時長有1.5分鐘,這個函式就會回傳2 ,以此類推,
///
/// 獲取音頻檔案的持續時間資訊
///
///
///
private int foxGetAudioDuration(string filename)
{
//使用命令列要非常小心對空格的處理
string tempCmdStr = "ffprobe -v quiet -print_format json -show_streams "
+ filename;
string result = myCmdFun(tempCmdStr);
//結果使用json格式決議
JObject jo = (JObject)JsonConvert.DeserializeObject(result);
string audioDuration = jo["streams"][0]["duration"].ToString();
//直接回傳整形資料,單位是秒
int durationSecond = (int)Math.Ceiling(System.Convert.ToDouble(audioDuration));
//轉成分鐘表示
int durationMinute = (durationSecond / 60) + 1;
return durationMinute;
}
3.此函式主要功能是對語音檔案進行分割,時間單位是秒,比如我有一個2分鐘的語音檔案,程式就把這個檔案分成2塊,每塊60秒即1分鐘,以此類推,
///分割的時間單位應該是秒
///分割音頻檔案
private void foxAudioCut(string filename,int timePos,int duration,int fileIndex)
{
//string tempCmdStr = "ffmpeg -i 003_16k.wav -ss 10 -t 10 003_1.wav";
string tempCmdStr = "ffmpeg -y -i "+filename+
" -ss "+timePos.ToString()
+" -t "+duration.ToString()
+" "+ "temp\\" + fileIndex.ToString()+".wav";
myCmdFun(tempCmdStr);
}
4.此函式的主要功能是把切片檔案轉換成百度云能夠進行正常識別的檔案格式,
///
/// 把目標音頻檔案轉換為百度語音能夠識別的檔案
///
///
private string foxAudioConvert(string filename,int fileIndex)
{
//臨時作業夾目錄設定為“temp”
string resultFileName = "Convert_" + fileIndex.ToString() + ".wav";
//注意這句含有兩個“temp\\”
string tempCmdStr = "ffmpeg -y -i "+ "temp\\" + filename
+" -acodec pcm_s16le -ac 1 -ar 16000 "
+ "temp\\" +resultFileName;
myCmdFun(tempCmdStr);
return resultFileName;
}
(三)主函式的代碼邏輯
//注意:檔案路徑里面不能含有空格
string tempFilePath = Path.GetFullPath(openFileDialog1.FileName);
//獲取音頻檔案持續時間資訊
int duration = foxGetAudioDuration(tempFilePath);
//主要的長語音識別邏輯
//將音頻檔案分成塊,每塊的長度默認為1分鐘
for (int i = 0; i < duration; i++)
{
//首先分割檔案
foxAudioCut(tempFilePath, i * 60, 60, i);
//然后轉換格式
string tempConvertFileName = foxAudioConvert(i.ToString() + ".wav", i);
//最后進行識別
//tempResult += fd.AsrData("temp\\" + tempConvertFileName);
//決議json
string tempStr = fd.AsrData("temp\\" + tempConvertFileName);
JObject jo = (JObject)JsonConvert.DeserializeObject(tempStr);
if (jo["err_no"].ToString().Equals("0"))
{
string result = jo["result"][0].ToString();
tempResult += result;
}
}
richTextBox1.Text = tempResult;
上面是主函式里面的核心代碼段,里面有很多的注釋,大家可以仔細看看,主要功能就是整合預處理輔助函式的作用,把檔案切片并轉換格式,最后提交給百度智能云進行識別,并對識別結果進行決議,把json轉換成對人類友好的文本格式,
作者:kohakuarc
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/4060.html
標籤:其他
