1、雲狐簡介html
雲狐語音識別軟件是基於百度智能雲,由進擊的狐狸進行開發的一款軟件。注意,由於核心類代碼是2017年就已經寫好的了,因此使用的C# SDK包不是最新的。雲狐目前支持的平臺是Windows系統平臺,使用時須要安裝微軟最新的.net framework 。雲狐的主要功能是長時間的語音識別,支持時長超過一分鐘的各類類型的語音文件識別,缺點就是速度較慢一些。shell
雲狐視頻演示及代碼解析的視頻連接:json
https://v.qq.com/x/page/j3023vgs9yz.html函數
雲狐語音識別軟件下載:ui
https://blog.csdn.net/ciel_arc/article/details/103172138人工智能
另外,雲狐和雲貓其實是姐妹軟件,由於他們都是基於百度智能雲,用C#進行開發的,使用的是百度最新的人工智能技術。並且他們目前都是免費的。這裏聯動一下,對雲貓OCR和雲狐語音感興趣的同窗,能夠百度搜索「雲貓OCR」或「雲狐語音」 進行了解。spa
2、雲狐的簡單評測.net
雲狐軟件自帶有計時功能,咱們能夠簡單作一下評測。從上文視頻演示的結果能夠看出,1分鐘左右的語音文件,雲狐能夠在10秒之內識別完畢,而30分鐘左右的語音文件,雲狐須要120秒即2分鐘左右,才能識別完畢。從中推算出識別速度大概是4秒/分鐘。命令行
3、雲狐軟件的代碼原理code
百度智能雲給出的長語音識別接口只支持一分鐘之內的語音文件的識別。而對於超過一分鐘的語音文件識別,咱們須要怎麼作呢?
雲狐軟件的原理就是:把超過一分鐘的文件進行切片,切成若干個小於或者等於一分鐘時長的語音文件。對每一個切片文件調用百度雲語音識別接口進行識別,再把結果串聯起來便可。
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