同时录制和播放音频

14

有人能帮我在iPhone上同时录制和播放音频吗?


2
请给我更多的描述。录音需要使用麦克风吗?同步需要多精确?你可以参考苹果的示例代码aurioTouch。 - Vanya
您可以在iOS设备上同时播放和录制(除第一代Touch外),使用Audio Unit RemoteIO或Audio Queue API。这些是较低级别的API,您必须自己处理传入缓冲区和传入PCM样本的出站缓冲区。请参阅苹果公司的aurioTouch示例应用程序以获取示例代码。 - hotpaw2
3个回答

9

您可以使用AVFoundation框架。它具有AVAudioPlayer用于播放音频文件和AVAudioRecorder用于录制。 请注意,录音机仅使用麦克风进行录制。 因此,同时播放音频文件并录制取决于麦克风对所播放音频的感知。


2

0

要在iOS中记录和播放音频文件,您可以使用AVFoundation框架。使用下面的Swift代码来记录和播放音频。 请记住,录音机将使用麦克风记录音频,因此请在设备上测试此代码。

import UIKit
import AVFoundation

extension String {

       func stringByAppendingPathComponent(path: String) -> String {

       let nsSt = self as NSString
       return nsSt.stringByAppendingPathComponent(path)
    }
}

class ViewController: UIViewController, AVAudioPlayerDelegate, AVAudioRecorderDelegate{

var audioPlayer : AVAudioPlayer!
var audioRecorder : AVAudioRecorder!

@IBOutlet var recordButton : UIButton!
@IBOutlet var playButton : UIButton!
@IBOutlet var stopButton : UIButton!

override func viewDidLoad() {
    super.viewDidLoad()

    self.recordButton.enabled = true
    self.playButton.enabled = false
    self.stopButton.enabled = false
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
}

//MARK: UIButton action methods

@IBAction func playButtonClicked(sender : AnyObject){

    let dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
    dispatch_async(dispatchQueue, {

        if let data = NSData(contentsOfFile: self.audioFilePath())
        {
            do{
                self.audioPlayer = try AVAudioPlayer(data: data)
                self.audioPlayer.delegate = self
                self.audioPlayer.prepareToPlay()
                self.audioPlayer.play()
            }
            catch{
                print("\(error)")
            }
        }
    });
}

@IBAction func stopButtonClicked(sender : AnyObject){

    if let player = self.audioPlayer{
        player.stop()
    }

    if let record = self.audioRecorder{

        record.stop()

        let session = AVAudioSession.sharedInstance()
        do{
            try session.setActive(false)
        }
        catch{
            print("\(error)")
        }
    }
}

@IBAction func recordButtonClicked(sender : AnyObject){

    let session = AVAudioSession.sharedInstance()

    do{
        try session.setCategory(AVAudioSessionCategoryPlayAndRecord)
        try session.setActive(true)
        session.requestRecordPermission({ (allowed : Bool) -> Void in

            if allowed {
                self.startRecording()
            }
            else{
                print("We don't have request permission for recording.")
            }
        })
    }
    catch{
        print("\(error)")
    }
}

func startRecording(){

    self.playButton.enabled = false
    self.recordButton.enabled = false
    self.stopButton.enabled = true

    do{

        let fileURL = NSURL(string: self.audioFilePath())!
        self.audioRecorder = try AVAudioRecorder(URL: fileURL, settings: self.audioRecorderSettings() as! [String : AnyObject])

        if let recorder = self.audioRecorder{
            recorder.delegate = self

            if recorder.record() && recorder.prepareToRecord(){
                print("Audio recording started successfully")
            }
        }
    }
    catch{
        print("\(error)")
    }
}

func audioFilePath() -> String{

    let path = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)[0]
    let filePath = path.stringByAppendingPathComponent("test.caf") as String

    return filePath
}

func audioRecorderSettings() -> NSDictionary{

    let settings = [AVFormatIDKey : NSNumber(int: Int32(kAudioFormatMPEG4AAC)), AVSampleRateKey : NSNumber(float: Float(16000.0)), AVNumberOfChannelsKey : NSNumber(int: 1), AVEncoderAudioQualityKey : NSNumber(int: Int32(AVAudioQuality.Medium.rawValue))]

    return settings
}

//MARK: AVAudioPlayerDelegate methods

func audioPlayerDidFinishPlaying(player: AVAudioPlayer, successfully flag: Bool) {

    if flag == true{
        print("Player stops playing successfully")
    }
    else{
        print("Player interrupted")
    }

    self.recordButton.enabled = true
    self.playButton.enabled = false
    self.stopButton.enabled = false
}

//MARK: AVAudioRecorderDelegate methods

func audioRecorderDidFinishRecording(recorder: AVAudioRecorder, successfully flag: Bool) {

    if flag == true{
        print("Recording stops successfully")
    }
    else{
        print("Stopping recording failed")
    }

    self.playButton.enabled = true
    self.recordButton.enabled = false
    self.stopButton.enabled = false
}
}

我已经在xCode 7.0和iOS 9上测试了这段代码。


我想录制输出音频(我指的是实时流音频或扬声器音频)。 - Hardik1344
iOS 12.4.1 中,当音频正在后台播放时(即应用程序不在前台时),此解决方案不会开始录制。 - Mike D3ViD Tyson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接