泉缘泉 发表于 2025-3-15 15:36:07

iOS音频录制与波形展示实践

本文另有配套的精品资源,点击获取https://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif
简介:本DEMO介绍了在iOS平台上怎样实现录音功能及实在时波形图的展示。开辟者通过AVFoundation框架中的AVAudioRecorder类来控制录音过程,并利用AVAudioSession来管理音频会话。DEMO展示了录音设置的配置,包罗音频格式、采样率和声道数等,并提供了及时波形图的绘制方法,如利用AVAudioPlayer和AVAudioRecorder相关属性和方法。此外,DEMO还介绍了如那边理录音错误以及怎样更新波形图以实现动画效果。本DEMO是理解iOS音频编程和创建音频相关应用的实用起点。 https://help.apple.com/assets/63FE303FD870B608D107CC46/63FE3040D870B608D107CC4D/he_IL/955208eadb92951306813e8861fbf977.png
1. iOS录音功能实现

在移动应用开辟中,录音功能是一项常见的需求。对于iOS平台而言,开辟者们通常会依赖于AVFoundation框架来实现高质量的音频录制。录音功能的实现不但关乎到音频信号的捕获,还需要处理音频数据的存储和后续的处理。本章将展开讨论iOS平台上录音功能的实现要点,为开辟人员提供一个深入理解并应用AVFoundation框架的起点。
1.1 实现iOS录音功能的基本步骤

要实现iOS录音功能,我们通常需要遵循以下基本步骤:

[*] 哀求用户授权 :录音前需获取用户的麦克风利用权限。
[*] 设置AVAudioSession :配置音频会话,以确保录音可以在合适的情况和模式下举行。
[*] 初始化AVAudioRecorder :通过AVAudioRecorder类创建录音对象,设置录音参数。
[*] 开始和制止录音 :控制录音的开始和结束,并处理音频数据。
通过逐步介绍以上步骤,本章旨在帮助读者理解并掌握iOS录音功能的焦点实现方式。接下来的章节会深入探讨怎样利用AVFoundation框架,实现更加复杂的音频录制和处理。
2. AVFoundation框架应用深度解析

2.1 AVFoundation框架概述

2.1.1 AVFoundation框架的构成结构

AVFoundation框架是苹果公司提供的一套API,它答应开辟者在他们的应用程序中实现高质量的音视频捕获、播放和处理。它与CoreMedia和CoreAudio等底层框架紧密集成,使得开辟者可以轻松地实现复杂的多媒体功能。
AVFoundation的焦点是AVFoundation.framework,包罗多个模块,每个模块都有特定的功能。例如,AVCapture模块负责视频和音频的捕获;AVAsset模块则用于音视频的读取、写入和管理。开辟者可以通过这些模块创建自界说的音视频处理流程。
2.1.2 AVFoundation框架与iOS录音功能

AVFoundation框架在iOS录音功能中扮演着关键角色,它为开辟者提供了实现音频捕获和处理的高级接口。通过利用AVFoundation框架,开辟者可以非常轻易地在应用中实现基本的录音功能,如启动录音、制止录音以及录音状态的监听。
此外,AVFoundation框架还支持对音频文件的进一步处理,例如音量控制、音质调整、音频过滤器等。开辟者可以或许利用这些API创建高度个性化的录音应用,满足差异场景的需求。
2.2 AVFoundation框架中的音频处理基础

2.2.1 音频信号的捕获与处理流程

音频信号的捕获与处理是一个复杂的过程,涉及到硬件设备、操纵体系以及应用程序等多个层面。AVFoundation框架通过AVCaptureAudioDataOutput类简化了这一过程。开辟者可以利用此类实现音频数据的捕获。
捕获流程通常包罗以下几个步骤: 1. 初始化并配置音频会话(AVAudioSession)。 2. 创建一个音频输入对象,好比AVCaptureDeviceInput,并将其与音频会话关联。 3. 配置输出,利用AVCaptureAudioDataOutput或AVCaptureAudioFileOutput等。 4. 启动捕获,开始捕获音频数据流。 5. 处理捕获的数据,可以是及时处理或存储到文件中。
2.2.2 音频会话(AVAudioSession)的重要性

AVAudioSession是AVFoundation框架中不可或缺的一部分,它负责管理应用程序的音频举动。它答应应用控制音频的输入输出,以及与体系其他音频举动的交互。
对于录音应用来说,正确配置AVAudioSession至关重要。开辟者可以通过设置会话类别(如AVAudioSessionCategoryRecord)来告诉体系应用的音频举动,以确保在需要录音时,其他音频输出(如音乐播放)不会干扰录音过程。此外,还可以或许通过设置音频选项来控制录音过程中的中断举动,例如是否答应音频中断和是否响铃时制止录音。
do {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.record, mode: .measurement)
    try AVAudioSession.sharedInstance().setActive(true)
} catch {
    print("设置音频会话失败: \(error)")
}
代码块展示了怎样设置音频会话类别以及激活音频会话,这对于保证录音功能的稳固运行至关重要。参数阐明包罗设置类别为录制类别,模式为丈量模式,以及激活音频会话以答应录音操纵。
3. AVAudioSession设置与管理

为了深入探讨如安在iOS应用中实现高质量的录音功能,本章将专注于AVAudioSession的设置与管理。AVAudioSession是AVFoundation框架中的焦点组件,负责处理应用中音频的输入和输出,以及体系音频事件的集成。我们将详细了解怎样初始化和配置音频会话,以及怎样管理音频会话的生命周期,以确保音频录制的流通性和稳固性。
3.1 AVAudioSession的初始化与配置

3.1.1 设置音频会话类别

在iOS中,AVAudioSession的类别决定了应用怎样与其他音频运动共享音频硬件。选择正确的类别对于提供精良的用户体验至关重要。例如,应用在举行录音时应该利用AVAudioSessionCategoryRecord,这将确保体系会优先处理应用的音频输入,从而制止在录音时混入背景声音。
音频会话的类别包罗但不限于以下几种:


[*]AVAudioSessionCategorySoloAmbient: 默认类别,实用于播放音乐的背景音频。
[*]AVAudioSessionCategoryAmbient: 答应与其他音频应用共享音频输入和输出。
[*]AVAudioSessionCategoryRecord: 仅录音,不答应应用播放音频。
[*]AVAudioSessionCategoryPlayback: 仅播放音频,不答应应用录制音频。
[*]AVAudioSessionCategoryPlayAndRecord: 同时支持播放和录音。
设置音频会话类别的代码如下:
do {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playAndRecord)
    try AVAudioSession.sharedInstance().setActive(true)
} catch {
    print("设置音频会话类别失败: \(error)")
}
3.1.2 音频会话选项与激活

在设置完音频会话类别之后,紧接着需要配置音频会话的选项和激活会话。音频会话的选项答应应用控制音频会话的举动。例如,可以通过设置选项来决定应用在音频中断时的举动,如是否停息音频的播放和录制。
激活音频会话是关照体系当前应用需要利用音频输入或输出的过程。这一步骤至关重要,由于只有激活了音频会话,应用才气举行音频的录制或播放。
激活音频会话的代码如下:
do {
    try AVAudioSession.sharedInstance().setActive(true)
} catch {
    print("激活音频会话失败: \(error)")
}
3.2 音频会话的生命周期管理

音频会话的生命周期管理涉及多个方面,包罗管理音频中断与模式切换,以及处理音频会话的错误与关照。正确的生命周期管理可以确保应用在音频中断时可以或许恢复到正确的状态,而且可以或许优雅地处理音频会话中的错误情况。
3.2.1 管理音频中断与模式切换

当用户接打电话或者锁屏时,iOS体系会发送音频中断的关照。应用需要捕捉这些中断,并作出相应的相应。例如,应用可以在吸收到音频中断关照时停息录音,然后在中断结束时恢复录音。
管理音频中断的伪代码示例如下:
// 注册音频中断的通知
NotificationCenter.default.addObserver(self, selector: #selector(handleAudioInterruption), name: .AVAudioSessionInterruptionNotification, object: nil)

@objc func handleAudioInterruption(notification: Notification) {
    guard let userInfo = notification.userInfo else {
      return
    }
    let interruptionType = (userInfo as? UInt) ?? 0
    switch interruptionType {
    case AVAudioSessionInterruptionType.pause.rawValue:
      // 音频中断,暂停录音
      pauseRecording()
    case AVAudioSessionInterruptionType.began.rawValue:
      // 音频中断开始
      break
    case AVAudioSessionInterruptionType.end.rawValue:
      // 音频中断结束
      resumeRecording()
    default:
      break
    }
}

func pauseRecording() {
    // 暂停录音的具体实现
}

func resumeRecording() {
    // 恢复录音的具体实现
}
3.2.2 处理音频会话的错误与关照

在举行音频录制的过程中,应用大概会遇到各种错误情况,如录音权限未被授予、音频设备不可用等。应用需要监听这些错误,并给出相应的处理计谋。
错误处理的伪代码示例如下:
NotificationCenter.default.addObserver(self, selector: #selector(handleError), name: .AVAudioSessionSetActiveFailedNotification, object: nil)

@objc func handleError(notification: Notification) {
    guard let userInfo = notification.userInfo else {
      return
    }
    if let error = userInfo as? NSError {
      print("激活音频会话失败错误: \(error)")
    }
}

// 在适当的地方移除观察者
NotificationCenter.default.removeObserver(self)
此外,应用还可以注册其他相关的关照来监控音频会话的活跃状态,或者监控输入设备的可用性等。如许可以确保应用在音频会话状态发生变化时可以或许做出及时相应。
通过上述的配置与管理,应用可以有效地控制音频会话的生命周期,从而确保音频录制的质量和应用的稳固性。下一章将介绍怎样利用AVAudioRecorder举行音频录制,并探索怎样对录音功能举行高级配置。
4. AVAudioRecorder利用与配置

4.1 AVAudioRecorder的创建与配置

4.1.1 设置录音参数与格式

AVAudioRecorder是AVFoundation框架中用于录音的一个类。在创建AVAudioRecorder实例之前,首先需要确定录音参数和格式。录音参数包罗采样率、声道数、音频质量等,这些参数将直接影响录音的质量和文件大小。
let audioSettings = [
    AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
    AVSampleRateKey: 44100,
    AVNumberOfChannelsKey: 2,
    AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
] as

do {
    try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playAndRecord, mode: AVAudioSession.Mode.default)
    try AVAudioSession.sharedInstance().setActive(true)
    let audioFileURL = try FileManager.default.url(for: .applicationSupportDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("record.aac")
    audioRecorder = try AVAudioRecorder(url: audioFileURL, settings: audioSettings)
    audioRecorder?.prepareToRecord()
} catch {
    print("AVAudioRecorder initialization error: \(error.localizedDescription)")
}
在这段代码中,我们设置了音频文件的格式为MPEG-4 AAC,采样率为44.1kHz,双声道,并设置了较高的音频质量。之后初始化了音频会话,并激活了录音权限。我们还指定了录音文件的生存路径,并实验创建了AVAudioRecorder实例。
4.1.2 访问麦克风权限与录音流程

为了访问用户的麦克风,需要在项目的Info.plist文件中添加麦克风利用权限的描述。之后,在代码中哀求麦克风权限。
import AVFoundation

func requestMicrophonePermission() {
    let micPermission = AVAudioSession.sharedInstance().recordPermission()
    if micPermission == .undetermined {
      AVAudioSession.sharedInstance().requestRecordPermission { (granted) in
            if granted {
                print("Microphone permission granted")
            } else {
                print("Microphone permission denied")
            }
      }
    }
}
在实际的录音流程中,首先需要调用prepareToRecord()方法来准备录音。录音的开始、停息、继续和制止都是通过AVAudioRecorder的record()、pause()、resume()和stop()方法来控制的。
@IBAction func recordButtonPressed(_ sender: UIButton) {
    if audioRecorder?.isRecording == true {
      audioRecorder?.stop()
      sender.setImage(UIImage(systemName: "record.circle"), for: .normal)
    } else {
      audioRecorder?.record()
      sender.setImage(UIImage(systemName: "stop.circle"), for: .normal)
    }
}
以上代码片段展示了怎样通过一个按钮来控制录音的开始与制止,并更新按钮的图标以反映当前的录音状态。
4.2 录音功能的高级配置

4.2.1 多种音频源的选择与利用

在某些情况下,开辟者大概需要利用除了默认麦克风之外的其他音频源。例如,可以选择利用内置麦克风或外接麦克风等。要实现这一功能,需要先获取可用的音频输入设备,然后选择相应的设备。
let audioRoute = AVAudioSession.sharedInstance().currentRoute
let inputs = audioRoute.inputPorts
if let input = inputs?.first {
    let inputName = input.portType.description
    print("Available input: \(inputName)")
    let inputParams = [
      AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
      AVSampleRateKey: 44100,
      AVNumberOfChannelsKey: 1,
      AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue,
      AVAudioInputSelectorKey: input.portType
    ] as
    do {
      audioRecorder = try AVAudioRecorder(url: audioFileURL, settings: inputParams)
      audioRecorder?.prepareToRecord()
    } catch {
      print("Failed to create recorder with input port: \(error.localizedDescription)")
    }
}
这段代码获取了当前音频路由的输入设备,并实验设置录音器以利用选定的音频输入源。
4.2.2 自界说采样率与编码器

为了实现特定的应用需求,有时需要对录音的采样率和编码器举行自界说配置。下面的示例展示了怎样设置非标准的采样率和选择差异的编码器。
let customAudioSettings: = [
    AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
    AVSampleRateKey: 22050, // Custom sample rate
    AVNumberOfChannelsKey: 1,
    AVEncoderBitRateKey: 32000, // Custom bit rate
    AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue,
    AVLinearPCMBitDepthKey: 16,
    AVLinearPCMIsBigEndianKey: false,
    AVLinearPCMIsFloatKey: false,
    AVLinearPCMIsNonInterleaved: false
]

do {
    audioRecorder = try AVAudioRecorder(url: audioFileURL, settings: customAudioSettings)
    audioRecorder?.prepareToRecord()
} catch {
    print("Failed to create recorder with custom settings: \(error.localizedDescription)")
}
在上述代码中,我们将采样率设置为22.05kHz,并指定了32kbps的比特率以及MPEG-4 AAC编码格式。这些自界说设置答应开辟者在录音应用中实现更多样化的功能,以适应差异的利用场景和质量要求。
通过以上介绍,我们可以了解到在iOS平台实现录音功能并不是一件复杂的事情,但要到达高级应用的程度,需要对AVFoundation框架中相关的音频处理组件有深入的了解和机动运用。通过掌握AVAudioRecorder的高级配置,开辟者可以或许满足更多特定的业务需求,从而提拔应用的专业性和用户体验。
5. 及时波形图绘制与动画效果实现

及时波形图是音频处理中非常直观的一种表现形式,它可以或许帮助用户直观地了解音频数据的强度和颠簸。在iOS开辟中,我们常常需要结合动画效果来增强用户体验,使波形图变得更加生动和直观。
5.1 及时波形图绘制原理

5.1.1 音频数据的处理与分析

在绘制波形图之前,首先要对音频数据举行处理和分析。音频信号被录制下来后,会被分割成一系列的小样本。这些样本通常是以PCM(脉冲编码调制)格式存储的,代表了在特定时间隔断内的声波振幅。
在AVAudioRecorder的回调中获取这些样本数据,可以按照以下步骤举行处理:
func audioRecorderOutput(_ output: AVAudio recorder, didOutput audioBuffer: AVAudioBuffer, for writingTo file: AVAudio file) {
    // 1. 获取PCM数据
    let audioBufferList = AVAudioBufferList(
      bufferCount: 1,
      buffers:
    )
    let frameCount = audioBuffer.frameLength
    var floatBuffer = AudioBufferList(
      mNumberBuffers: 1,
      mBuffers: [AudioBuffer(
            mNumberChannels: 1,
            mDataByteSize: frameCount * MemoryLayout.size(ofValue: Float.self),
            mData: nil
      )]
    )
    // 2. 将数据从Int16转换为Float32
    AudioConverterPrime(self.converter!, AVAudio converterPrimeActionarming, 0)
    AudioConverterFillComplexBuffer(
      self.converter!,
      { _, bufferList, _ in
            bufferList.pointee.mNumberChannels = 1
            bufferList.pointee.mBuffers.mData = audioBufferList.mBuffers.mData
            bufferList.pointee.mBuffers.mDataByteSize = audioBufferList.mBuffers.mDataByteSize
            return noErr
      },
      &floatBuffer
    )
    // 3. 进行波形图绘制相关处理
    // ...
}
5.1.2 波形图的绘制方法与优化

绘制波形图通常利用UIBezierPath来举行,可以将音频样本的振幅转换为垂直方向的坐标,绘制出波形。优化方法包罗淘汰图形重绘的次数以及利用双缓冲等技能。
func drawWaveform() {
    // 创建路径
    let path = UIBezierPath()
    guard let waveformView = self.waveformView else { return }
    path.move(to: CGPoint(x: 0, y: waveformView.bounds.size.height / 2))
    let numberOfPoints = self.audioFrameCount
    let widthPerSample = waveformView.bounds.size.width / Double(numberOfPoints)
    for i in 0..<numberOfPoints {
      let sampleValue = self.audioFrameValues
      let x = widthPerSample * Double(i)
      let y = waveformView.bounds.size.height / 2 - sampleValue * waveformView.bounds.size.height
      if i == 0 {
            path.move(to: CGPoint(x: x, y: y))
      } else {
            path.addLine(to: CGPoint(x: x, y: y))
      }
    }
    path.addLine(to: CGPoint(x: waveformView.bounds.size.width, y: waveformView.bounds.size.height / 2))
    // 绘制路径
    waveformView.layer.addSublayer(CAShapeLayer())
    waveformView.layer.sublayers?.last?.path = path.cgPath
    waveformView.layer.sublayers?.last?.fillColor = UIColor.red.cgColor
}
5.2 波形图动画效果的实现

5.2.1 利用Core Animation创建动画

为了增强用户体验,我们可以利用Core Animation框架给波形图添加一些动画效果,例如淡入淡出、滑动更新等。
let animation = CABasicAnimation(keyPath: "position.y")
animation.duration = 1.0
animation.fromValue = waveformView.layer.position.y
animation.toValue = waveformView.layer.position.y - 100
waveformView.layer.add(animation, forKey: "slideAnimation")
5.2.2 动画与用户体验的结合

动画的运用要恰到好处,不要过于花哨,以保证应用的性能和用户的体验。我们可以结合用户的交互举动来触发动画,例如在用户触摸波形图时,让波形图产生相应的动态效果。
@objc func waveformTouched(_ sender: UIView) {
    UIView.animate(withDuration: 0.3) {
      self.waveformView.transform = CGAffineTransform(scaleX: 1.1, y: 1.1)
    }
    // 动画结束后恢复原状
    UIView.animate(withDuration: 0.3, delay: 0.3, options: .curveEaseInOut, animations: {
      self.waveformView.transform = .identity
    }, completion: nil)
}
在实现波形图动画效果时,要根据应用的场景和用户的举动举行公道的筹划,确保动画流通且不会干扰用户的主要操纵。同时,适时的反馈和动画效果可以提拔用户对应勤奋能的理解和印象,增强应用的吸引力和竞争力。
   本文另有配套的精品资源,点击获取https://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif
简介:本DEMO介绍了在iOS平台上怎样实现录音功能及实在时波形图的展示。开辟者通过AVFoundation框架中的AVAudioRecorder类来控制录音过程,并利用AVAudioSession来管理音频会话。DEMO展示了录音设置的配置,包罗音频格式、采样率和声道数等,并提供了及时波形图的绘制方法,如利用AVAudioPlayer和AVAudioRecorder相关属性和方法。此外,DEMO还介绍了如那边理录音错误以及怎样更新波形图以实现动画效果。本DEMO是理解iOS音频编程和创建音频相关应用的实用起点。
   本文另有配套的精品资源,点击获取https://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: iOS音频录制与波形展示实践