讲师中心 微信公众号
AI工具推荐 视频效率加速

iOS 26语音API:使用Swift实现实时语音转文本

夏静大大_3930

夏静大大_3930

发布时间:2026-01-05 09:44:03

|

1155人浏览过

|

来源于php中文网

原创

在移动应用开发领域,语音识别技术正变得越来越重要。它不仅提升了用户体验,还为应用增加了新的交互方式。iOS 26 引入了强大的语音 API,为开发者提供了前所未有的便利。本文将深入探讨如何在Swift中使用 iOS 26 的语音 API,实现实时语音转文本功能,并提供详细的代码示例和步骤指南,帮助开发者快速上手。我们将从配置项目、获取权限,到实现核心的语音识别功能进行详细讲解,并分享一些最佳实践,确保你的应用能够以最佳状态使用这项技术。同时,我们也会探讨这一API的优点和局限性,以及如何在实际项目中有效地应用。

iOS 26语音API关键点

利用Swift实现iOS 26的实时语音转文本功能。

详细讲解配置项目和获取语音权限的步骤。

提供核心语音识别功能的代码示例。

分享提高语音识别准确率的最佳实践。

分析iOS 26语音API的优点和局限性。

探讨在实际项目中有效应用语音API的策略。

解释如何使用AudioKit进行音频处理

iOS 26语音API介绍及准备工作

什么是iOS 26语音API?

ios 26 语音 api 是一套强大的工具,允许开发者将语音识别功能集成到他们的应用程序中。通过这个 api,你可以实现实时语音转文本,让用户通过语音与你的应用进行交互。该 api 利用设备上的语音识别引擎,能够提供准确、快速的语音转录服务。

☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 多模态理解力帮你轻松跨越从0到1的创作门槛☜☜☜

iOS 26语音API:使用Swift实现实时语音转文本

这个API能够将语音转换为文字,并提供置信度评分,方便开发者了解识别的准确性,根据结果调整应用行为。利用最新的 iOS 26 语音 API,开发者可以为用户打造更加自然、智能的交互体验。

项目配置和权限获取

在使用 iOS 26 语音 API 之前,需要进行一些必要的项目配置和权限获取。首先,确保你的 Xcode 项目支持 iOS 26 或更高版本。然后,需要在 Info.plist 文件中添加麦克风使用权限描述,以便在应用运行时向用户请求麦克风访问权限。

具体步骤如下:

  1. 打开你的 Xcode 项目。
  2. 找到 Info.plist 文件。
  3. 添加 Privacy - Microphone Usage Description 键,并设置一个描述,解释你的应用为什么需要访问麦克风。例如,可以设置为 “允许应用使用麦克风录制音频,用于语音转文本功能”。
  4. 保存 Info.plist 文件。

完成以上步骤后,你的应用就可以在运行时请求麦克风访问权限了。需要注意的是,务必在用户明确需要使用语音功能时再请求权限,并提供清晰的理由,这样可以提高用户授权的可能性。

iOS 26语音API:使用Swift实现实时语音转文本

Swift代码实现语音转文本

音频捕获代码详解

为了捕获用户的语音,你需要使用 AVFoundation 框架。AVFoundation 提供了强大的音频处理功能,可以用来录制、播放和处理音频数据。以下是一个简单的音频捕获代码示例:

import Foundation
import AVFoundation

class AudioCapter {
   @preconcurrency import AVAudio
    nonisolated AudioCapter()
    // 音频引擎和其他变量
    let inputTapEventsStream: AsyncStream<AVAudioPCMBuffer, AVAudioTime>
    let inputTapEventsContinuation: AsyncStream<AVAudioPCMBuffer, AVAudioTime>.Continuation
    private let audioEngine = AVAudioEngine()
    private let audioSession = AVAudioSession.sharedInstance()

    let bufferSize: UInt32 = 1024

    init() throws {
        (self.inputTapEventsStream, self.inputTapEventsContinuation) = AsyncStream.makeStream(of: (AVAudioPCMBuffer, AVAudioTime).self)

        try self.configureAudioSession()
    }

    func configureAudioSession() throws {
        audioSession.setCategory(.playAndRecord, mode: .measurement, options: [.duckOthers, .defaultToSpeaker, .allowBluetoothHFP])
        try audioSession.setActive(true, options: .notifyOthersOnDeactivation)

        guard let availableInputs = audioSession.availableInputs,
              let builtInMicInput = availableInputs.first(where: { $0.portType == .builtInMic }) else {
            throw NSError(domain: "", code: 1)
        }
        try audioSession.setPreferredInput(builtInMicInput)

    }

    func startCapturingInput() async throws {
        // 确保应用获得了录音权限
        await self.checkRecordingPermission()
        self.audioEngine.reset()

        let inputNode = audioEngine.inputNode

        // 在input node安装tap
        let format = inputNode.outputFormat(forBus: 0)
        inputNode.removeTap(onBus: 0)
        inputNode.installTap(onBus: 0, bufferSize: bufferSize, format: format) { (buffer: AVAudioPCMBuffer, time: AVAudioTime) in
            self.inputTapEventsContinuation.yield((buffer, time))
        }

        audioEngine.prepare()
        try audioEngine.start()

    }
}

func checkRecordingPermission() async throws {
    switch AVAudioApplication.shared.recordPermission {
    case .undetermined:
        let result = await AVAudioApplication.requestRecordPermission()
        if !result {
            throw NSError(domain: "", code: 1)
        }
    case .denied:
        throw NSError(domain: "", code: 1)
    case .granted:
        return
    default:
        throw NSError(domain: "", code: 1)
    }
}

这段代码首先导入了 AVFoundation 框架,并创建了一个 AudioCapter 类。这个类负责配置音频会话、获取麦克风输入,并在输入节点上安装一个 tap。inputTapEventsStream 和 inputTapEventsContinuation是用于数据捕获的关键点,这里使用了Swift的AsyncStream用于异步处理音频数据流。

iOS 26语音API:使用Swift实现实时语音转文本

其中@preconcurrency import AVAudio这段代码主要用于解决 Swift 并发环境下的兼容性问题,它告诉编译器这是一个旧的框架,在执行并发检查时应该更加宽松。 在ios26以上的版本,使用这个可以兼容老框架,可以理解为对老的框架兼容性更好。

非孤立(nonisolated)关键字意味着该类不属于特定的角色(actor),并且可以被多个并发上下文访问。

配置音频会话(configureAudioSession) 配置音频会话是确保音频正确捕获的关键步骤。你需要设置会话的类别(category)、模式(mode)和选项(options),以适应你的应用场景。以下是 configureAudioSession 方法的代码示例:

func configureAudioSession() throws {
    audioSession.setCategory(.playAndRecord, mode: .measurement, options: [.duckOthers, .defaultToSpeaker, .allowBluetoothHFP])
    try audioSession.setActive(true, options: .notifyOthersOnDeactivation)

    guard let availableInputs = audioSession.availableInputs,
          let builtInMicInput = availableInputs.first(where: { $0.portType == .builtInMic }) else {
        throw NSError(domain: "", code: 1)
    }
    try audioSession.setPreferredInput(builtInMicInput)

}

这段代码设置了音频会话的类别为 playAndRecord,模式为 measurement,并添加了一些选项,例如 duckOthers(降低其他应用的音频音量)、defaultToSpeaker(默认使用扬声器)和 allowBluetoothHFP(允许使用蓝牙耳机)。然后,它激活了音频会话,并设置了首选的麦克风输入。

启动音频捕获(startCapturingInput) 启动音频捕获是开始录制音频的关键步骤。你需要确保应用获得了录音权限,然后重置音频引擎,并在输入节点上安装一个 tap。以下是 startCapturingInput 方法的代码示例:

func startCapturingInput() async throws {
    // 确保应用获得了录音权限
    await self.checkRecordingPermission()
    self.audioEngine.reset()

    let inputNode = audioEngine.inputNode

    // 在input node安装tap
    let format = inputNode.outputFormat(forBus: 0)
    inputNode.removeTap(onBus: 0)
    inputNode.installTap(onBus: 0, bufferSize: bufferSize, format: format) { (buffer: AVAudioPCMBuffer, time: AVAudioTime) in
        self.inputTapEventsContinuation.yield((buffer, time))
    }

    audioEngine.prepare()
    try audioEngine.start()

}

这段代码首先检查应用是否获得了录音权限(checkRecordingPermission),然后重置音频引擎,并在输入节点上安装一个 tap。这个 tap 会在每次有新的音频数据到达时被调用,并将音频数据传递给 inputTapEventsContinuation.yield 方法。

检查录音权限(checkRecordingPermission) 检查录音权限是确保应用能够正常录制音频的关键步骤。你需要使用 AVAudioApplication 类来检查和请求录音权限。以下是 checkRecordingPermission 方法的代码示例:

func checkRecordingPermission() async throws {
    switch AVAudioApplication.shared.recordPermission {
    case .undetermined:
        let result = await AVAudioApplication.requestRecordPermission()
        if !result {
            throw NSError(domain: "", code: 1)
        }
    case .denied:
        throw NSError(domain: "", code: 1)
    case .granted:
        return
    default:
        throw NSError(domain: "", code: 1)
    }
}

这段代码首先检查当前的录音权限状态。如果权限状态是 undetermined,则会向用户请求录音权限。如果用户拒绝了权限,则会抛出一个错误。如果权限状态是 granted,则会直接返回。

转录器代码详解

将捕获的音频转换为文本需要使用到Swift的Speech框架。

import SwiftUI
import Speech

class Transcriber {
    let transcriptionResults: AsyncSequence<SpeechTranscriber.Result, any Error>
    let analyzer: SpeechAnalyzer

    var bestAvailableAudioFormat: AVAudioFormat? = nil

    // 用于接受上游传来的buffer的输入
    let inputSteam: AsyncStream<AnalyzerInput, Never> = AsyncStream<AnalyzerInput, Never>()
    // 用于链接数据,AsyncStream的特性
    let inputContinuation: AsyncStream<AnalyzerInput, Never>.Continuation
    let preset: SpeechTranscriber.Preset = .timeIndexedProgressiveTranscription

    let locale: Locale = .autoupdatingCurrent
    let audioConverter: AVAudioConverter?

    typealias AnalyzerInput = SpeechTranscriber.AnalyzerInput

    init() async throws {

        // 创建AsyncStream
        (self.inputSteam, self.inputContinuation) = AsyncStream.makeStream(of: AnalyzerInput.self,bufferingPolicy: .bufferingNewest(1))

        self.analyzer = SpeechAnalyzer(modules: [transcriber], options: .init(priority: .userInitiated, modelRetention: .processLifetime))

        let bestAvailableAudioFormat = await SpeechAnalyzer.bestAvailableAudioFormat(compatibleWith: transcriber)
        self.bestAvailableAudioFormat = bestAvailableAudioFormat
        self.locale = Locale.autoupdatingCurrent
        // 配置转码器
        self.audioConverter = AVAudioConverter(from:self.bestAvailableAudioFormat!, to:AVAudioFormat(commonFormat:.pcmFormatInt16, sampleRate:44100, channels:1, interleaved:false)!)!   // 44100 sample rate, mono
        let isInstalled = await SpeechTranscriber.installedLocales.contains(locale)
        if !isInstalled {
            let installationRequest = try await AssetInventory.assetInstallationRequest(supporting: [transcriber!])
            try await installationRequest.downloadAndInstall()
        }
       transcriptionResults =  transcriber.results

        transcriber.transcriptionOptions = SpeechTranscriber.TranscriptionOptions(locale: self.locale,    // 使用当前语言环境
                                            // 优化识别效果

         reportingOptions: preset.reportingOptions,
 attributeOptions: preset.attributeOptions.union([.transcriptionConfidence])
)

    }

  private let transcriber = SpeechTranscriber()
}

Transcriber 类负责将音频转换为文本。

Browser Session Manager
Browser Session Manager

使用 Playwright 为 jimeng.jianying.com 管理浏览器会话,导入 cookies/localStorage 以自动化视频生成工作流,支持图片上传等功能

下载

iOS 26语音API:使用Swift实现实时语音转文本

transcriptionResults 是一个异步序列,用于发送转录结果。 analyzer 是用于分析音频的工具。 bestAvailableAudioFormat 变量用于存储最佳可用音频格式。 inputSteam 是用于接收音频缓冲区的异步流,其中定义了数据如何流入转录器。 该类会根据用户 intonation 语调实时调整转录结果,并提供置信度评分,开发者可以根据这个评分来调整应用的行为。

iOS 26 语音API使用指南

配置音频会话

音频会话是应用和系统之间进行音频交互的桥梁。合理的音频会话配置可以确保应用能够正确地捕获和播放音频。

  • 设置类别(category):
    • AVAudioSession.Category.playAndRecord:用于同时播放和录制音频。
    • AVAudioSession.Category.playback:用于播放音频。
    • AVAudioSession.Category.record:用于录制音频。
  • 设置模式(mode):
    • AVAudioSession.Mode.default:默认模式,适用于大多数应用场景。
    • AVAudioSession.Mode.measurement:用于精确测量音频数据。
  • 设置选项(options):
    • AVAudioSession.CategoryOptions.duckOthers:降低其他应用的音频音量。
    • AVAudioSession.CategoryOptions.defaultToSpeaker:默认使用扬声器。
    • AVAudioSession.CategoryOptions.allowBluetoothHFP:允许使用蓝牙耳机。

获取麦克风输入

要获取麦克风输入,需要使用 AVAudioSession 类的 availableInputs 属性。这个属性返回一个数组,包含了所有可用的音频输入设备。你需要遍历这个数组,找到类型为 builtInMic 的设备,并将其设置为首选输入设备。

guard let availableInputs = audioSession.availableInputs,
    let builtInMicInput = availableInputs.first(where: { $0.portType == .builtInMic }) else {
    throw NSError(domain: "", code: 1)
}
try audioSession.setPreferredInput(builtInMicInput)

这段代码首先获取所有可用的音频输入设备,然后找到类型为 builtInMic 的设备,并将其设置为首选输入设备。如果找不到内置麦克风,则会抛出一个错误。

在输入节点上安装 Tap

Tap 是 AVAudioNode 类的一个特性,允许你在音频数据流经过节点时拦截数据。你可以在输入节点上安装一个 tap,以便在每次有新的音频数据到达时进行处理。

let inputNode = audioEngine.inputNode
let format = inputNode.outputFormat(forBus: 0)
inputNode.removeTap(onBus: 0)
inputNode.installTap(onBus: 0, bufferSize: bufferSize, format: format) { (buffer: AVAudioPCMBuffer, time: AVAudioTime) in
    self.inputTapEventsContinuation.yield((buffer, time))
}

这段代码首先获取输入节点,然后移除之前安装的 tap(如果存在),并在输入节点上安装一个新的 tap。这个 tap 会在每次有新的音频数据到达时被调用,并将音频数据传递给 inputTapEventsContinuation.yield 方法。

重要提示: 要确保这个参数类型和AsyncStream中的参数相符合

配置和启动音频引擎

配置和启动音频引擎是开始录制音频的最后一步。你需要调用 audioEngine.prepare() 方法来准备音频引擎,然后调用 audioEngine.start() 方法来启动音频引擎。

audioEngine.prepare()
try audioEngine.start()

这段代码首先准备音频引擎,然后启动音频引擎。如果启动失败,则会抛出一个错误。

使用Speech框架进行转录

使用Speech 框架将捕获的音频数据转换为文本需要以下步骤:

  • 创建 SFSpeechRecognizer 实例:
let recognizer = SFSpeechRecognizer(locale: Locale.autoupdatingCurrent)!

这段代码创建了一个 SFSpeechRecognizer 实例,并设置了语言环境为当前设备使用的语言环境。

  • 创建 SFSpeechAudioBufferRecognitionRequest 实例:
let request = SFSpeechAudioBufferRecognitionRequest()

这段代码创建了一个 SFSpeechAudioBufferRecognitionRequest 实例,用于将音频数据传递给语音识别引擎。

  • 将音频数据传递给 SFSpeechAudioBufferRecognitionRequest 实例:
request.append(buffer)

这段代码将音频数据传递给 SFSpeechAudioBufferRecognitionRequest 实例。buffer 是一个 AVAudioPCMBuffer 实例,包含了捕获的音频数据。

  • 启动语音识别任务:
recognizer.recognitionTask(with: request) { (result, error) in
    if let error = error {
        print("语音识别失败:\(error.localizedDescription)\")
    } else if let result = result {
        print("语音识别结果:\(result.bestTranscription.formattedString)\")
    }
}

这段代码启动了一个语音识别任务,并在任务完成后执行一个闭包。如果语音识别失败,则会打印一个错误信息。如果语音识别成功,则会打印语音识别结果。

iOS 26语音API的优缺点分析

? Pros

实时性:提供实时语音转文本功能,用户可以立即看到识别结果。

准确性:利用设备上的语音识别引擎,提供较高的语音识别准确率。

易用性:API设计简洁易懂,开发者可以使用较少的代码实现复杂的语音识别功能。

灵活性:提供丰富的配置选项,允许开发者根据应用场景进行优化。

安全性:在设备上运行,无需将音频数据发送到云端,保护用户隐私。

? Cons

依赖设备性能:语音识别性能依赖于设备的处理能力。

需要用户授权:需要用户授权麦克风访问权限。

语言支持有限:目前只支持部分语言,需要根据应用场景选择合适的语言环境。

常见问题解答

如何提高语音识别的准确率?

提高语音识别准确率的方法有很多,以下是一些常用的技巧: 使用清晰的音频输入:确保麦克风录制到的音频清晰、无噪音。 设置正确的语言环境:确保 SFSpeechRecognizer 实例的语言环境与用户的口语一致。 优化语音识别参数:根据应用场景调整语音识别参数,例如 SFSpeechRecognitionRequest 的 shouldReportPartialResults 属性。 使用设备上的语音识别引擎:设备上的语音识别引擎通常比网络语音识别引擎更准确。

如何处理语音识别失败的情况?

语音识别失败的情况有很多,以下是一些常见的错误类型: SFSpeechRecognizerErrorDomain:语音识别器错误。 AVAudioSessionErrorDomain:音频会话错误。 kCLErrorDomain:定位服务错误。 针对不同的错误类型,可以采取不同的处理方法。例如,如果语音识别器错误,可以尝试重新启动语音识别任务。如果音频会话错误,可以尝试重新配置音频会话。如果定位服务错误,可以提示用户开启定位服务。

如何支持多种语言的语音识别?

要支持多种语言的语音识别,需要创建多个 SFSpeechRecognizer 实例,并为每个实例设置不同的语言环境。然后,根据用户的选择,使用相应的 SFSpeechRecognizer 实例进行语音识别。

相关问题

iOS 26 语音API 与旧版本的语音识别技术相比有哪些优势?

iOS 26 语音API 相较于旧版本的语音识别技术,在性能、准确性和易用性方面都有显著提升。新的 API 利用设备上的语音识别引擎,能够提供更快、更准确的语音转录服务。此外,iOS 26 语音 API 提供了更多的配置选项,允许开发者根据应用场景进行优化。最重要的是,新的 API 更加易于使用,开发者可以使用更少的代码实现复杂的语音识别功能。 以下是 iOS 26 语音 API 相较于旧版本的语音识别技术的一些主要优势: 更高的准确率:iOS 26 语音 API 利用设备上的语音识别引擎,能够提供更高的语音识别准确率。 更快的速度:iOS 26 语音 API 的语音识别速度更快,能够提供更流畅的用户体验。 更多的配置选项:iOS 26 语音 API 提供了更多的配置选项,允许开发者根据应用场景进行优化。 更易于使用:iOS 26 语音 API 更加易于使用,开发者可以使用更少的代码实现复杂的语音识别功能.

热门AI工具

更多
Lovart
Lovart Hot

一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

超级麦吉

一款通过数字员工协作完成调研、数据分析与文档制作的AI办公平台。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

相关专题

更多
Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

60

2026.10.28

Vite 如何搭配 Vue.js
Vite 如何搭配 Vue.js

Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。

40

2026.10.28

Vite 项目目录怎么看
Vite 项目目录怎么看

Vite项目目录专题汇集入口文件、src源码、public静态资源、路径别名、项目根目录和构建输出目录相关的已审核文章,帮助读者理解各文件夹的用途与引用方式。

160

2026.10.28

Gradle插件开发入门教程
Gradle插件开发入门教程

本专题介绍Gradle插件开发的基本流程,涵盖插件类编写、自定义任务注册、扩展参数设计和插件应用方法,帮助你理解插件如何组织构建逻辑,减少多个项目之间的重复配置。

140

2026.10.22

Gradle Wrapper配置教程
Gradle Wrapper配置教程

本专题介绍Gradle Wrapper的基本作用,涵盖文件组成、生成方法、版本配置和任务调用,帮助你理解项目如何使用指定的Gradle版本,减少不同开发环境带来的构建差异。

120

2026.10.22

Golangci-lint检查器使用教程
Golangci-lint检查器使用教程

本专题整理Golangci-lint常用Linters的用途与配置方法,覆盖错误处理、无效代码、安全、复杂度、命名和依赖检查,帮助项目合理选规则。

80

2026.10.22

Gradle怎么构建Java项目
Gradle怎么构建Java项目

本专题介绍Gradle Java项目构建方法,涵盖Java插件配置、依赖声明、源码编译、测试执行和打包检查,帮助你理解各阶段的任务关系,逐步完成项目构建。

60

2026.10.22

PHP时间戳漏洞修复教程
PHP时间戳漏洞修复教程

本专题汇总PHP常见时间戳漏洞,包括2038年溢出、时区漂移、时间戳伪造、重放攻击、时间盲注与日志审计失效等,并给出升级64位环境、使用 DateTimeImmutable、统一UTC、严格超时校验、预处理绑定、hash_equals 比对等修复方案,帮助开发者快速排查和加固时间相关代码。

80

2026.10.22

Golangci-lint配置文件与规则设置
Golangci-lint配置文件与规则设置

本专题聚焦Golangci-lint YAML配置文件,讲清运行参数、规则启停、目录排除、问题过滤及严重级别设置,便于团队统一检查标准。

40

2026.10.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WebSocket手册
WebSocket手册

共0课时 | 0人学习

HTML5/CSS3/JavaScript/ES6入门课程
HTML5/CSS3/JavaScript/ES6入门课程

共102课时 | 11万人学习

前端基础到实战(HTML5+CSS3+ES6+NPM)
前端基础到实战(HTML5+CSS3+ES6+NPM)

共162课时 | 28.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn