因業務需要,要求開發小程序語音識別功能。最后花了四天時間終於把這個坑給爬出來了。
一、微信開發者工具坑
小程序使用 wx.getRecorderManager(); 接口錄音,錄音直接就是acc或mp3格式(並不是silk格式,所以是能夠播放的,其他具體原因后面會講),最后使用的是mp3格式。本來mp3格式我認為是能夠直接播放的,當我用從 微信開發者工具 上錄的音上傳( wx.uploadFile(obj) )錄音文件后,發現用 Mac 無法打開進行播放,在這個坑中待了大概兩天的樣子,突然想到會不會是因為 微信開發者工具 錄的原因?所以果斷用手機錄音進行了測試。這一測試,發現手機錄得音能夠在電腦上直接進行播放,所以現在的錄音文件就是一個 正常的MP3文件。但是得要是在手機上錄得才能打開播放。
* 注: 為什么會在錄音能不能播放這個問題上待兩天? 因為在網上搜索的所有有關錄音的東西,都說其格式是silk,這個是沒辦法直接打開播放的,所以這個不能播放的文件我一直認為是因為它是silk才不能播放,然而當我看這個文件時,發現其的確是MP3的二進制文件。(silk文件:是一種webm格式的文件進行base64編碼后的文件,應該是個文本文件,但是這個是二進制文件,而且還無法打開播放)
二、文件轉格式的坑--FFmpeg 以及在PHP中使用exec() 執行FFmpeg命令
關於FFmpeg的安裝就是參考:centos 7.0 下安裝FFmpeg軟件 過程
在使用PHP 的exec() 執行外部命令時發現有幾個問題:
- php.ini中disable_functions 中把 exec 函數給禁用了,需要將其在PHP.ini 中刪去,並重啟php服務或者集成環境
- Apache的 www 用戶否是具有文件目錄的權限,添加權限的方法:參考:PHP 運行 mkdir() Permission Denied 的原因
最重要的一點:
$cmd_templat = '%s -y -i %s %s 2>&1'; $cmd = sprintf( $cmd_templat, FFMPEG_DIR, $BASE_DIR.$path, $new_name ); $info = null; $status = null; exec($cmd, $info, $status); sleep(1); chmod($new_name, 0777); if ( $status == 0 ) { return $new_name; }
每次在執行exec后,執行chmod時,發生錯誤,說沒有轉換后的文件。因此我在執行chmod之前,暫停了1秒鍾,到底為什么exec沒有等待結果的返回我也不清楚是什么情況了。
這些問題解決后,語音識別方面就特別好做了,這個就不寫了,具體代碼:
// 轉換音頻格式到允許的格式 function convert_to_allow($path, $to= 'wav') { global $BASE_DIR; $path = ltrim($path,'.'); $extra = explode('.', $path); $extra_name = array_pop( $extra ); $all_name = join( '.', $extra ); // 如果現在的擴展名與轉換后擴展名一樣,則直接返回 if( $extra_name && $extra_name === $to ){ return $BASE_DIR.$path; } $new_name = $BASE_DIR.$all_name.'.'.$to; if( file_exists( $new_name ) ){ $new_name = $BASE_DIR.$all_name.randString(6).'.'.$to; } $cmd_templat = '%s -y -i %s %s 2>&1'; $cmd = sprintf( $cmd_templat, FFMPEG_DIR, $BASE_DIR.$path, $new_name ); $info = null; $status = null; exec($cmd, $info, $status); sleep(1); chmod($new_name, 0777); if ( $status == 0 ) { return $new_name; } return false; }