使用AVAudioRecorder在后台录制语音(当我点按主页按钮时)

时间:2013-04-29 10:41:30

标签: objective-c xcode

我是IOS开发的新手。我正在尝试使用AVAudioRecorder在后台录制用户语音,但我向UIBackgroundModes添加“音频”,但这没有帮助。顺便说一句,一切都在前景中完美。当在后台时,计时器工作正常,但语音不记录。 如何从背景麦克风录制?这可能吗?

3 个答案:

答案 0 :(得分:4)

你可以。 Skype就是这样做的。

您可能需要在Info.plist中设置<key>UIBackgroundModes</key><array><string>audio</string></array>,并且您需要在切换应用之前确保音频会话处于活动/正在运行状态(假设您不会突然开始录制/播放音乐/当你的应用在后台播放时。)

The docs说“音频”可让您在后台播放音频,但这可能也适用于录制音频。如果它不起作用,你可以尝试一些事情:

  • 同时设置“voip”和“audio”。
  • 播放静音(这可能最容易使用音频队列API)。

此材料来自:iOS multitasking for an Audio Recording application

额外材料请参阅:he recording stops as soon as I press the "HOME" button Building Background-Aware Applications

答案 1 :(得分:1)

您需要在应用程序plist文件中将UIBackgroundModes设置为音频。

答案 2 :(得分:0)

是的,当应用程序在后台运行时,可以录制和播放两者。首先,您需要为您的应用启用后台模式,请使用以下步骤。

- 在Xcode导航器中选择项目文件。然后,从“功能”部分,打开“背景模式”子部分。在为您提供背景模式列表后,请在“音频和音频”上打勾。 Airplay开关。

- 使用以下代码在app的前景和后台状态下录制和播放音频。如果设备处于静默模式或用户锁定设备,下面的代码也会录制和播放音频。

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{
                let session = AVAudioSession.sharedInstance()

                try session.setCategory(AVAudioSessionCategoryPlayback)
                try session.setActive(true)

                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

    //let filePath = NSBundle.mainBundle().pathForResource("mySong", ofType: "mp3")!
    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
}
}

只需复制此代码并将其粘贴到空视图控制器swift文件中,创建三个按钮“Record”,“停止”,“播放”在xib文件或storyboard文件中,连接@IBOutlet和@IBAction。 在真实设备上测试此代码,因为您需要麦克风来录制音频。 我已经针对xCode 7和iOS 9及其工作进行了测试。