iT邦幫忙

2023 iThome 鐵人賽

DAY 9
0

昨天,我們對Whisper模型進行了初步的探索和使用。今天,我們將結合這兩個部分,利用Whisper API將錄製的語音轉成文字。正如【Day - 8】所述,儘管市場上存在許多語音轉文字的技術,但Whisper以它強大的精確度而脫穎而出。讓我開始今天的挑戰吧!Let's Go!

驗證錄音格式

由於Whisper API有音訊格式的限制,例如:「mp3」、「mp4」、「mpeg」、「mpga」、「m4a」、「wav」和「webm」等,因此在串接之前,我們需要確認錄音套件所生成的音訊格式是什麼。
https://ithelp.ithome.com.tw/upload/images/20230909/20161663PE9rGimxKo.png
先在停止錄音的地方使用alert()來查看音訊的格式(mimeType):

//停止錄音
VoiceRecorder.stopRecording().then((result: RecordingData) => {
  if (result.value && result.value.recordDataBase64) {
    //查看音訊格式
    alert(result.value.mimeType);
  }
});

經過測試後,實際的音訊格式為「audio/aac」。
https://ithelp.ithome.com.tw/upload/images/20230909/20161663uhHHDMD9W8.jpg
其實這個插件在Github的Readme中也有說明了,音訊格式會依據不同的操作平台和瀏覽器有所不同。在Android和iOS平台上,音訊格式皆為「audio/aac」。
https://ithelp.ithome.com.tw/upload/images/20230909/20161663tj7XeV1MC9.png
另外,我也在網路上找到了一個Base64到Audio的轉換工具網頁,用以測試套件所產生的base64字串。透過測試,確定錄音檔是aac格式。而這個工具也提示我們,在Chrome上並不支援這種格式。
https://ithelp.ithome.com.tw/upload/images/20230909/20161663WLNCUrcJHh.png

串接API

Whisper API對音訊格式有特定限制,不幸的是,aac格式並未在它的支援範圍內。儘管如此,我還是決定嘗試看看。首先,我們需要為API建立Model。Whisper API的Response相當簡單,只一個text參數。
https://ithelp.ithome.com.tw/upload/images/20230909/2016166395HmzevivZ.png
建立一個chatgpt.model.ts的檔案,並依照Response的格式建立WhisperResponseModel

export interface WhisperResponseModel {
  text: string;
}

接著在voicerecording.component.ts中建立一個EventEmitter。我們在停止錄音的地方,觸發這個 EventEmitter來發送事件,並將值傳送到Home主頁:

@Output() getRecordingBase64Text: EventEmitter<RecordingData> = new EventEmitter<RecordingData>();
.
.
.
//停止錄音
VoiceRecorder.stopRecording().then((result: RecordingData) => {
  if (result.value && result.value.recordDataBase64) {
    this.getRecordingBase64Text.emit(result);
  }
});

在Home主頁的home.page.ts中,建立了一個OnGetRecordingBase64Text()的方法。這個方法首先將Base64字串轉換成Blob格式,然後放入FormData中。另外,由於呼叫OpenAI API需要Token,因此在此建立了一個HTTPHeader

//建立Http header
private headers = new HttpHeaders({
  'Authorization': 'Bearer {你的Token}'
});

constructor(private http: HttpClient) { }

OnGetRecordingBase64Text(recordingBase64Data: RecordingData) {
  const recordData = recordingBase64Data.value.recordDataBase64;
  const mimeType = recordingBase64Data.value.mimeType;
  //將Base64字串轉為Blob
  const byteCharacters = atob(recordData);
  const byteNumbers = new Array(byteCharacters.length);
  for (let i = 0; i < byteCharacters.length; i++) {
    byteNumbers[i] = byteCharacters.charCodeAt(i);
  }
  const byteArray = new Uint8Array(byteNumbers);
  const blob = new Blob([byteArray], { type: mimeType });
  //建立FormData
  const formData = new FormData();
  formData.append('file', blob, 'audio.m4a');
  formData.append('model', 'whisper-1');
  formData.append('language', 'en');

  //Whisper API
  this.http.post<WhisperResponseModel>('https://api.openai.com/v1/audio/transcriptions', formData, { headers: this.headers }).subscribe(result => alert(result.text));
}

當需要使用HttpClient服務時,別忘了在專案中匯入HttpClientModule。若專案是Standalone,則是在main.ts檔案內加入importProvidersFrom(HttpClientModule)或Angular 15開始可以使用的provideHttpClient()。這樣才能順利使用HttpClient服務來進行HTTP請求:

bootstrapApplication(AppComponent, {
  providers: [
    { provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
    importProvidersFrom(IonicModule.forRoot({})),
    provideRouter(routes),
    //importProvidersFrom(HttpClientModule),
    //Since Angular 15
    provideHttpClient(),
  ],
});

最後在Home頁面的home.page.html上,將事件綁定:

<app-voicerecording (getRecordingBase64Text)="OnGetRecordingBase64Text($event)"></app-voicerecording>

測試後,得到API Response 400 Error,錯誤內容說明:「無效的檔案格式」。
https://ithelp.ithome.com.tw/upload/images/20230909/20161663WC3LWJqEHc.png
不死心的我,嘗試將Base64數據保存為wav檔案,然後再將其放入Blob中。然而,由於這個過程並未涉及真正的音訊轉檔,原始音訊的格式依然是aac。結果如我所預料的,這種方法並未奏效。

結語

果然不出意外的話就要出意外了!今天可說是充滿困難的一天,特別是與audio/aac音訊格式有關的問題,這讓我耗費了許多時間和精力。最初是希望能在JavaScript端解決音訊轉檔的問題。雖然有一些在本地可以使用的音訊轉檔JavaScript套件,但大部分都是基於Node.js建構的,而且我也沒有找到可用的音訊轉檔API。但是,這些困難也激發了我尋找新方向和創新解決方案的決心,我們將在明天,持續面對並且克服這些挑戰!



Github專案程式碼:Ionic結合ChatGPT - Day9


上一篇
【Day - 8】Open AI API - 認識GPT和Whisper
下一篇
【Day - 10】ASP.NET Web API - 用FFmpeg打造音訊轉換服務
系列文
Ionic結合ChatGPT - 30天打造AI英語口說導師APP30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言