WhisperKit SwiftUI组件库:语音录制与转录UI封装

WhisperKit SwiftUI组件库:语音录制与转录UI封装

【免费下载链接】WhisperKit 适用于 Apple Silicon 的 Whisper 语音识别模型的设备端推理 【免费下载链接】WhisperKit 项目地址: https://gitcode.com/GitHub_Trending/wh/WhisperKit

WhisperKit是适用于Apple Silicon的Whisper语音识别模型的设备端推理框架,其SwiftUI组件库为开发者提供了完整的语音录制与转录UI解决方案。本文将详细介绍如何使用WhisperKit的SwiftUI组件快速构建语音交互界面,包含模型管理、实时录音、转录结果展示等核心功能模块。

组件架构概览

WhisperAX作为WhisperKit的官方示例应用,展示了如何使用SwiftUI构建完整的语音转录界面。该应用采用MVVM架构,核心UI组件集中在ContentView.swift中,主要包含以下模块:

  • 模型管理组件:负责Whisper模型的加载、选择与计算单元配置
  • 转录控制组件:处理录音状态切换与转录任务管理
  • 音频可视化组件:实时展示音频能量波形
  • 结果展示组件:区分已确认和未确认的转录文本

WhisperAX架构

核心视图结构通过NavigationSplitView实现多面板布局,左侧为功能菜单和模型设置,右侧为转录内容展示区域:

NavigationSplitView(columnVisibility: $columnVisibility) {
    // 左侧面板:模型选择与功能菜单
    VStack(alignment: .leading) {
        modelSelectorView
        List(menu) { item in /* 功能菜单 */ }
    }
} detail: {
    // 右侧面板:转录内容与控制
    VStack {
        transcriptionView
        controlsView
    }
}

核心UI组件详解

1. 模型选择器组件

模型选择器是用户与WhisperKit交互的入口,负责模型加载状态展示和计算资源配置。该组件通过状态变量modelState反映当前模型状态(未加载/加载中/已加载),并提供直观的视觉反馈:

var modelSelectorView: some View {
    VStack {
        HStack {
            Image(systemName: "circle.fill")
                .foregroundStyle(modelState == .loaded ? .green : (modelState == .unloaded ? .red : .yellow))
                .symbolEffect(.variableColor, isActive: modelState == .loading)
            Text(modelState.description)
            
            Picker("", selection: $selectedModel) {
                ForEach(availableModels, id: \.self) { model in
                    HStack {
                        let modelIcon = localModels.contains(model) ? "checkmark.circle" : "arrow.down.circle.dotted"
                        Image(systemName: modelIcon)
                        Text(model)
                    }
                }
            }
        }
        
        if modelState == .unloaded {
            Button("Load Model") { loadModel(selectedModel) }
                .buttonStyle(.borderedProminent)
        }
    }
}

组件还包含"Compute Units"展开面板,允许用户为音频编码器和解码器选择不同的计算单元(CPU/GPU/Neural Engine),以平衡性能和功耗:

计算单元配置

2. 转录控制组件

转录控制组件是用户交互的核心,通过大型圆形按钮实现录音状态切换,并提供文件导入功能:

var controlsView: some View {
    VStack {
        HStack {
            Button { selectFile() } label: {
                Text("FROM FILE")
                    .frame(minWidth: 70, minHeight: 70)
                    .overlay(Circle().stroke(Color.red))
            }
            
            Button(action: toggleRecording) {
                Image(systemName: isRecording ? "stop.circle.fill" : "mic.circle.fill")
                    .font(.system(size: 80))
                    .foregroundColor(isRecording ? .red : .blue)
            }
        }
    }
}

录音按钮使用系统图像和颜色变化直观反映当前状态,点击后触发toggleRecording方法,该方法会协调WhisperKit实例的录音状态:

func toggleRecording() {
    if isRecording {
        whisperKit?.audioProcessor.stopRecording()
        isRecording = false
    } else {
        do {
            try whisperKit?.audioProcessor.startRecording()
            isRecording = true
        } catch {
            showError(error)
        }
    }
}

3. 音频可视化组件

音频可视化组件通过水平滚动的柱状图实时展示音频能量,帮助用户判断录音是否正常进行:

ScrollView(.horizontal) {
    HStack(spacing: 1) {
        let startIndex = max(bufferEnergy.count - 300, 0)
        ForEach(Array(bufferEnergy.enumerated())[startIndex...], id: \.element) { _, energy in
            RoundedRectangle(cornerRadius: 2)
                .frame(width: 2, height: CGFloat(energy) * 24)
                .background(energy > Float(silenceThreshold) ? Color.green.opacity(0.2) : Color.red.opacity(0.2))
        }
    }
}
.defaultScrollAnchor(.trailing)

该组件通过bufferEnergy数组接收音频能量数据,只显示最近300个采样点,并使用不同颜色区分能量是否超过阈值,直观反映语音活动检测(VAD)状态。

4. 转录结果展示组件

结果展示组件根据转录模式(普通/流式)提供不同的展示方式。在流式模式下,使用不同样式区分已确认和假设的转录文本:

if enableEagerDecoding && isStreamMode {
    Text("\(timestampText) \(Text(confirmedText).fontWeight(.bold))\(Text(hypothesisText).fontWeight(.bold).foregroundColor(.gray))")
        .font(.headline)
        .multilineTextAlignment(.leading)
} else {
    ForEach(confirmedSegments) { segment in
        Text("\(timestampText)\(segment.text)")
            .fontWeight(.bold)
            .tint(.green)
    }
    ForEach(unconfirmedSegments) { segment in
        Text("\(timestampText)\(segment.text)")
            .fontWeight(.bold)
            .foregroundColor(.gray)
    }
}

组件支持时间戳显示,并通过颜色和字体粗细区分不同状态的转录结果,帮助用户直观了解转录进度和确定性。

状态管理与数据流

WhisperAX的UI状态管理采用SwiftUI的@State@AppStorage属性包装器,实现界面状态与业务逻辑的解耦。关键状态变量包括:

  • 录音状态@State private var isRecording: Bool = false
  • 转录状态@State private var isTranscribing: Bool = false
  • 模型状态@State private var modelState: ModelState = .unloaded
  • 用户偏好@AppStorage("selectedModel") private var selectedModel: String

数据流通过以下方式实现:

  1. 用户交互(如点击录音按钮)更新状态变量
  2. 状态变量变化触发UI更新
  3. UI操作通过闭包或方法调用WhisperKit核心功能
  4. WhisperKit处理结果通过回调更新状态变量

例如,转录结果更新流程:

// 1. 设置转录结果回调
whisperKit?.onTranscriptionUpdate = { segments, isFinal in
    DispatchQueue.main.async {
        if isFinal {
            confirmedSegments.append(contentsOf: segments)
        } else {
            unconfirmedSegments = segments
        }
    }
}

// 2. UI根据状态变化自动更新
ForEach(confirmedSegments) { segment in
    Text(segment.text)
        .tint(.green)
}
ForEach(unconfirmedSegments) { segment in
    Text(segment.text)
        .foregroundColor(.gray)
}

实战应用:构建自定义转录界面

基于WhisperKit组件库,构建自定义转录界面的基本步骤如下:

1. 集成WhisperKit框架

Package.swift中添加依赖:

dependencies: [
    .package(url: "https://gitcode.com/GitHub_Trending/wh/WhisperKit", from: "1.0.0")
]

2. 创建基础视图结构

struct CustomTranscribeView: View {
    @State private var whisperKit: WhisperKit?
    @State private var isRecording = false
    @State private var transcription = ""
    
    var body: some View {
        VStack {
            Text(transcription)
                .padding()
            
            Button(action: toggleRecording) {
                Image(systemName: isRecording ? "stop.circle.fill" : "mic.circle.fill")
                    .font(.system(size: 60))
            }
        }
        .onAppear {
            loadWhisperModel()
        }
    }
}

3. 实现模型加载与转录逻辑

func loadWhisperModel() {
    Task {
        do {
            whisperKit = try WhisperKit(modelPath: "path/to/model", computeOptions: .init())
            whisperKit?.onTranscriptionUpdate = { segments, _ in
                DispatchQueue.main.async {
                    transcription = segments.map { $0.text }.joined()
                }
            }
        } catch {
            print("模型加载失败: \(error)")
        }
    }
}

func toggleRecording() {
    if isRecording {
        whisperKit?.stopTranscription()
    } else {
        try? whisperKit?.startTranscription()
    }
    isRecording.toggle()
}

4. 添加音频可视化

// 添加音频能量状态
@State private var audioEnergy: [Float] = []

// 在初始化时设置音频能量回调
whisperKit?.onAudioEnergyUpdate = { energy in
    DispatchQueue.main.async {
        audioEnergy.append(energy)
        if audioEnergy.count > 100 {
            audioEnergy.removeFirst()
        }
    }
}

// 添加可视化视图
HStack(spacing: 2) {
    ForEach(audioEnergy, id: \.self) { energy in
        RoundedRectangle(cornerRadius: 1)
            .frame(width: 3, height: CGFloat(energy) * 40)
            .foregroundColor(.blue)
    }
}
.frame(height: 40)

性能优化与最佳实践

1. 状态管理优化

  • 避免过度使用@State,优先使用@StateObject管理复杂状态
  • 将大型视图拆分为小型View结构体,提高渲染性能
  • 使用@Binding减少状态传递层级

2. 计算资源配置

WhisperAX提供了计算单元选择功能,根据不同场景优化性能:

  • 快速响应:选择Neural Engine+GPU组合
  • 低功耗:选择CPU模式
  • 平衡模式:默认的CPU+Neural Engine组合

计算单元选择

3. 内存管理

  • 及时取消不再需要的转录任务:transcribeTask?.cancel()
  • 限制音频可视化数据长度:if audioEnergy.count > 300 { audioEnergy.removeFirst() }
  • 大文件转录时使用分段处理

总结

WhisperKit SwiftUI组件库为Apple Silicon设备提供了强大的语音录制与转录UI解决方案,主要优势包括:

  • 完整的组件生态:从模型管理到结果展示的全流程UI组件
  • 高度可定制:通过SwiftUI的声明式语法轻松定制界面
  • 性能优化:针对Apple Silicon优化的计算资源配置
  • 直观的用户体验:清晰的状态反馈和结果展示

官方示例应用WhisperAX提供了完整的实现参考,开发者可以在此基础上快速构建符合自身需求的语音转录应用。随着语音交互需求的增长,WhisperKit组件库将成为iOS/macOS开发者的重要工具。

通过本文介绍的组件和技术,您可以构建出既美观又高效的语音转录界面,为用户提供流畅的语音转文字体验。无论是会议记录、语音笔记还是实时字幕应用,WhisperKit都能提供强大的技术支持。

【免费下载链接】WhisperKit 适用于 Apple Silicon 的 Whisper 语音识别模型的设备端推理 【免费下载链接】WhisperKit 项目地址: https://gitcode.com/GitHub_Trending/wh/WhisperKit

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值