Recorder錄音插件的使用

背景:語音識別需求,理所當然需要錄音,而且是PC端錄音,直接上Recorder,H5錄音的一個組件。

git官方鏈接

https://github.com/xiangyuecn/Recorder

官方使用示例

https://xiangyuecn.github.io/Recorder/

官方使用示例源碼

view-source:https://xiangyuecn.github.io/Recorder/QuickStart.html

1、依賴引入
// 錄音
import '../../lib/recorder/recorder.wav.min';
// 波形圖(可以忽略這個波形圖,只是爲了示例,波形圖用Recorder中推薦的就挺好的)
import WaveView from '../../lib/recorder/wavview';

我們這個老項目中以前有用過這個組件,是直接將人家的打包js放在了一個js文件中直接引入的,emm....我是直接複用的,哈哈。

推薦用import引入,按照官方文檔指引引入使用即可;

2、開始使用:聲明recorder對象

聲明一個全局的recorder對象,設置Recorder對象的一些屬性;

  • type: 輸出類型:mp3,wav

  • sampleRate: 採樣率;

  • bitRate: 比特率 wav:16或8位,MP3:8kbps 1k/s,8kbps 2k/s 錄音文件很小;

  • bufferSize: H5錄音時的AudioContext緩衝大小;

  • onProcess: 錄音實時回調,可在裏面設置波形圖,發送實時數據,獲取錄音時長,限制最長錄音等功能;

因爲錄音類型是wav,後端wav要求(16k,16bit,單通道)

recorder = useRef(window.Recorder({
    type: 'wav',
    sampleRate: 16000,
    bitRate: 16,
    bufferSize: 4096,
    onProcess: (
      buffers,	// 緩衝的PCM數據,爲從開始錄音到現在的所有pcm片段
      powerLevel,	// 當前緩衝的音量級別0-100
      bufferDuration,	// 已緩衝時長
      bufferSampleRate,		// 緩衝使用的採樣率
    ) => {
    	// 波形圖
      waveView.input(buffers[buffers.length - 1], powerLevel, bufferSampleRate);
      // 音頻轉換數據,即發送到後端的數據
      recordTransformData = window.Recorder.SampleData(buffers, bufferSampleRate, 16000,
        {
          index: recordTransformData ? recordTransformData.index : 0,
          offset: recordTransformData ? recordTransformData.offset : 0.0,
        });
      // socket發送數據(需要全局聲明,這裏僅作爲示例)
      socket.send(recordTransformData.data);
      // 獲取錄音時長
      setAudioDuration(bufferDuration);
      // 限制錄音1分鐘,若超出給出友好提示
      if (bufferDuration / 1000 >= 60) {
        message.error('您已錄製超過最大時長: 1分鐘。馬上爲您分析數據~');
        // 接近限制時間,停止錄音
        stopRecord(bufferDuration); // 傳參是因爲setAudioDuration在自動停止的時候沒有賦上值
      }
    },
  }), []);
3、點擊按鈕開始錄音

有了recoder錄音對象之後,我們就可以點擊按鈕開始錄音;

官方說明:open()和close()最好分開按鈕操作,但是需求不允許我們這樣;

open(): 打開錄音資源, 兩個參數。

  • True()
  • False(msg,isUserNotAllow)

特別說明下這裏遇到的問題,我起初用的時候沒有仔細看源碼,自己再點擊開始錄音之前多此一舉去判斷麥克風是否被禁用:

導致了一個bug:當停止錄音關閉錄音的時候瀏覽器錄音的小紅點還在,給人錯覺還在錄音,資源沒有釋放;

其實open方法的第二個回調就是這個作用,打開錄音失敗,可以進行友好提示;

start(): 開啓錄音

  const startRecord = useCallback(() => {
	 // Recorder.IsOpen函數表示,是否已經打開了錄音,所有工作都已經準備好了,就等接收音頻數據了;如果沒有打開,直接返回
    if (window.Recorder.IsOpen()) {
      return;
    }
    recorder.current.open(() => {
    	// 打開錄音成功的回調:
    	// 開始錄音
      recorder.current.start();
      // 波形圖
      waveView = WaveView({ el: canvasRef.current, linear1: [0, '#356CBC', 1, '#356CBC'], linear2: [0, '#356CBC', 1, '#356CBC'] });
    }, (msg, isUserNotAllow) => {
    	// 打開錄音失敗的回調
      if (isUserNotAllow) {
        message.warning('無法錄音:' + msg + ',請允許瀏覽器使用麥克風並重新評測', 5);
      } else {
        message.warning('無法錄音:' + msg, 5);
      }
    });
  }, [type]);

4、點擊按鈕關閉錄音

錄音完成的時候,需要點擊按鈕關閉錄音。

stop(): 停止錄音,結束錄音並返回錄音數據blob對象,有3個參數

  • True(blob,duration) blob:錄音數據audio/mp3|wav格式;duration:錄音時長,單位毫秒;

  • False(msg);

  • autoClose:false 可選,是否自動調用close,默認爲false

close():關閉錄音,釋放資源

const stopRecord = useCallback(() => {
	// 判斷錄音是否打開,如果沒有打開直接返回
    if (!window.Recorder.IsOpen()) {
      return;
    }
	socket.send('end');
    socket.close();
    recorder.current.stop((blob) => {
    	// 獲取錄音的url用來播放音頻
      const wavUrlStr = window.URL.createObjectURL(blob);
      setAudioUrl(wavUrlStr);
      // 關閉釋放錄音資源
      recorder.current.close(() => {
        recordTransformData = null;
      });
    }, () => {
      recorder.current.stop(() => {}, () => {}, false);
    }, false);
  }, [setIsRecording, setAudioUrl]);

5、特別說明

最後,這裏有一個需要注意的點,服務器渲染的話,頁面引入Recorder錄音組件的時候需要將ssr設置爲false,因爲服務器渲染的時候頁面在服務器上面是找不到Window對象的。

import dynamic from 'next/dynamic';
const Recorder = dynamic(() => import('./Recorder'), { ssr: false });

綜上所述,這就是我用五步法實現了錄音的功能,這個五步法適用於大多數簡單的錄音功能,並且錄音組件的源碼中有很多詳細的註釋,如果要添加額外的功能,可以詳細看下源碼再進行設置。

波形圖可以忽略哈;emm.....直接用Recoder文檔中推薦的就挺好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章