Contents

william-weng/wwaudiofiletranscription

English | 正體中文

✨ [功能特色](https://peterpanswift.github.io/iphone-bezels/)

  • 支援將既有音訊檔案轉換成文字。
  • 支援指定語言與地區設定,例如 zh-TW、en-US、ja-JP。
  • 支援即時回傳暫時辨識結果。
  • 支援以 AsyncThrowingStream 接收連續辨識結果。
  • 支援自訂專有名詞與上下文詞彙。
  • 支援 SFSpeechRecognitionTaskHint 指定辨識用途。
  • 支援取消目前進行中的轉錄工作。
  • 支援使用者從「檔案」App 選取的 security-scoped URL。

📦 安裝

使用 Swift Package Manager

在 Xcode 中選擇:

File → Add Package Dependencies...

接著輸入套件 repository URL,選擇要使用的版本,並將套件加入 App target。

如果這是本地套件,也可以在 Xcode 中使用:

File → Add Package Dependencies... → Add Local...

🔐 權限設定

因為套件使用 Apple Speech framework 進行語音辨識,請在 App 的 Info.plist 加入以下設定:

<key>NSSpeechRecognitionUsageDescription</key>
<string>需要使用語音辨識將音訊檔案轉換成文字</string>

📌 公開屬性

| 名稱 | 型別 | 說明 | | --- | --- | --- | | isTranscribing | Bool | 指示目前是否正在進行音訊轉錄。 | | authorizationStatus | Bool | 目前的語音辨識授權狀態。 | | isAuthorized | Bool | 指示目前是否已取得語音辨識權限。 | | locale | Locale | 語音辨識器目前使用的語系。 |

🏗️ 公開 API

| API | 宣告 | 說明 | | --- | --- | --- | | init(locale:) | init(locale: Locale) | 建立音訊檔案轉錄器。 | | requestAuthorization() | requestAuthorization() async | 請求使用語音辨識的授權。 | | transcribe(audioFileURL:shouldReportPartialResults:contextualStrings:taskHint:result:) | transcribe(audioFileURL: URL, shouldReportPartialResults: Bool = false, contextualStrings: [String] = , taskHint: SFSpeechRecognitionTaskHint = .dictation, result: @escaping (Result<TranscriptResult, TranscriptError>) -> Void) | 建立音訊檔案轉錄器。 | | transcribe(audioFileURL:shouldReportPartialResults:contextualStrings:taskHint:) | transcribe(audioFileURL: URL, shouldReportPartialResults: Bool = false, contextualStrings: [String] = , taskHint: SFSpeechRecognitionTaskHint = .dictation) -> AsyncThrowingStream<TranscriptResult, any Error> | 建立音訊檔案轉錄器。 |

🚀 基本使用方式

建立轉錄器

import Speech

let transcriber = WWAudioFileTranscription(
    locale: Locale(identifier: "zh-TW")
)

請求語音辨識權限

Task {
    await transcriber.requestAuthorization()

    guard transcriber.isAuthorized else {
        print("尚未取得語音辨識權限")
        return
    }
}

requestAuthorization() 應該在開始轉錄前呼叫一次。授權狀態可以透過以下屬性查詢:

transcriber.authorizationStatus
transcriber.isAuthorized

🧠 自訂上下文詞彙

如果音訊中包含產品名稱、技術名詞、人名或其他專有名詞,可以傳入 contextualStrings:

let contextualStrings = [
    "SwiftUI",
    "AVFoundation",
    "SFSpeechRecognizer",
    "Swift Package Manager",
    "WWAudioFileTranscription"
]

transcriber.transcribe(
    audioFileURL: audioURL,
    shouldReportPartialResults: true,
    contextualStrings: contextualStrings
) { result in
    // 處理轉錄結果
}

這些詞彙會提供給 Speech framework 作為辨識時的上下文參考。

🌏 指定辨識語言

建立轉錄器時指定 Locale:

let traditionalChineseTranscriber = WWAudioFileTranscription(
    locale: Locale(identifier: "zh-TW")
)

let englishTranscriber = WWAudioFileTranscription(
    locale: Locale(identifier: "en-US")
)

let japaneseTranscriber = WWAudioFileTranscription(
    locale: Locale(identifier: "ja-JP")
)

請根據音訊內容選擇正確的語言,語言設定會直接影響辨識結果。

🧪 完整範例

import UIKit
import WWAudioFileTranscription

final class ViewController: UIViewController {
    
    @IBOutlet weak var resultLabel: UILabel!
    
    private let filename = "demo.wav"
    private let transcriber: WWAudioFileTranscription = .init(locale: .init(identifier: "en-US"))
    
    override func viewDidLoad() {
        super.viewDidLoad()
        Task { await transcriber.requestAuthorization() }
    }
    
    @IBAction func directTranscript(_ sender: UIButton) {
        
        let audioFileURL = Bundle.main.url(forResource: filename, withExtension: nil)!
        resultLabel.text = ""
        
        transcriber.transcribe(audioFileURL: audioFileURL) { [weak self] (result) in
            switch result {
            case .success(let transcription): self?.resultLabel.text = transcription.transcript
            case .failure(let error): self?.resultLabel.text = error.localizedDescription
            }
        }
    }
    
    @IBAction func liveTranscript(_ sender: UIButton) {
        
        let audioFileURL = Bundle.main.url(forResource: filename, withExtension: nil)!
        resultLabel.text = ""

        Task {
            do {
                for try await result in transcriber.transcribe(audioFileURL: audioFileURL, shouldReportPartialResults: true) {
                    resultLabel.text = result.transcript
                }
            } catch {
                resultLabel.text = error.localizedDescription
            }
        }
    }
}

⚠️ 注意事項

  • WWAudioFileTranscription 使用 @MainActor,請在主 actor 上建立與使用。
  • 開始轉錄前必須先呼叫 requestAuthorization()。
  • 轉錄器一次只處理一個音訊檔案。
  • 音訊檔案必須存在,且格式必須是 Speech framework 支援的格式。
  • shouldReportPartialResults 為 true 時,結果會多次回傳,請檢查 isFinal。
  • 語音辨識能力與可用語言會依裝置、系統版本及 Apple Speech service 狀態而有所不同。
  • Speech framework 的辨識處理可能涉及將音訊傳送至 Apple 的伺服器;請在 App 隱私權政策中清楚說明相關資料處理方式。
  • 如果 App 需要完全離線的語音辨識,請另外評估裝置端辨識能力或其他離線模型方案。

Package Metadata

Repository: william-weng/wwaudiofiletranscription

Default branch: main

README: README.md