AVAudioPlayer在模拟器上工作,但不在Real Device上工作 [英] AVAudioPlayer working on Simulator but not on Real Device

查看:159
本文介绍了AVAudioPlayer在模拟器上工作,但不在Real Device上工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我播放录制的音频时,我收到此错误:

While I play recorded Audio I get this error:


致命错误:在解开可选值时意外发现nil

fatal error: unexpectedly found nil while unwrapping an Optional value

SoundPlayer = try AVAudioPlayer(contentsOfURL: getFileURL())

但除了真实设备外,它在Simulator上运行良好。

But it is working perfectly on Simulator except real device.

ViewController.Swift:

import UIKit
import AVFoundation

class ViewController: UIViewController, AVAudioPlayerDelegate, AVAudioRecorderDelegate {

    @IBOutlet var PlayBTN: UIButton!
    @IBOutlet var RecordBTN: UIButton!


    var soundRecorder : AVAudioRecorder!
    var SoundPlayer : AVAudioPlayer!

    var fileName = "audioFile.m4a"

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        setupRecorder()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func setupRecorder(){

        let recordSettings = [AVSampleRateKey : NSNumber(float: Float(44100.0)),
            AVFormatIDKey : NSNumber(int: Int32(kAudioFormatMPEG4AAC)),
            AVNumberOfChannelsKey : NSNumber(int: 1),
            AVEncoderAudioQualityKey : NSNumber(int: Int32(AVAudioQuality.Max.rawValue))]

        do{
            try soundRecorder = AVAudioRecorder(URL: getFileURL(), settings: recordSettings)
                soundRecorder.delegate = self
                soundRecorder.prepareToRecord()
        }
        catch let error as NSError {
            error.description
        }

    }

    func getCacheDirectory() -> String {

        let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true) 

        return paths[0]

    }

    func getFileURL() -> NSURL{
        let path  = (getCacheDirectory() as NSString).stringByAppendingPathComponent(fileName)

        let filePath = NSURL(fileURLWithPath: path)


        return filePath
    }


    @IBAction func Record(sender: UIButton) {

        if sender.titleLabel?.text == "Record"{

            soundRecorder.record()
            sender.setTitle("Stop", forState: .Normal)
            PlayBTN.enabled = false

        }
        else{

            soundRecorder.stop()
            sender.setTitle("Record", forState: .Normal)
            PlayBTN.enabled = false
        }

    }

    @IBAction func PlaySound(sender: UIButton) {

        if sender.titleLabel?.text == "Play" {

            RecordBTN.enabled = false
            sender.setTitle("Stop", forState: .Normal)

            preparePlayer()
            SoundPlayer.play()

        }
        else{

            SoundPlayer.stop()
            sender.setTitle("Play", forState: .Normal)

        }

    }

    func preparePlayer(){
        do{
            SoundPlayer = try AVAudioPlayer(contentsOfURL: getFileURL())
            SoundPlayer.delegate = self
            SoundPlayer.volume = 1.0
            SoundPlayer.prepareToPlay()
        }
        catch let error as NSError {
            error.description
        }
    }

    func audioRecorderDidFinishRecording(recorder: AVAudioRecorder, successfully flag: Bool) {
        PlayBTN.enabled = true
    }

    func audioPlayerDidFinishPlaying(player: AVAudioPlayer, successfully flag: Bool) {
        RecordBTN.enabled = true
        PlayBTN.setTitle("Play", forState: .Normal)
    }

    @IBAction func actDone(sender: AnyObject) {
        //viewRecorder.hidden = true

        let fm = NSFileManager.defaultManager()
        let documentsDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String

        do {
            let items = try fm.contentsOfDirectoryAtPath(documentsDirectory)

            for item in items {
                print(item)
            }
        }
        catch let error as NSError {
            error.description
        }
    }
}

ViewController.Swift的故事板文件:

其他信息:


  • Xcode版本:7.2.1

  • 设备:iPhone 5s

  • iOS版本:9.2.1

注意:我已经找到了类似的SO解决方案,但没有一个能帮助我。其中一些是由于较旧的Swift版本和不推荐使用的方法。一些解决方案涉及从应用程序包播放音频文件,一些使用Web URL。所以,这种情况不同( Real Device vs Simulator

Note: I have looked for similar SO solutions but none of them helped me. Some of them due to older Swift version and deprecated method. Some solutions were regarding playing audio file from application bundle and some of were using web URLs. So, this case is different(Real Device vs Simulator)

这是 Google云端硬盘

推荐答案

在真实设备上,它需要 setCategory() for AVAudioSession.sharedInstance( )

On a real device, it needs to setCategory() for AVAudioSession.sharedInstance()

可以下载一个固定的项目这里也是

And a fixed project can be downloaded here too.

func setupRecorder(){

        let audioSession = AVAudioSession.sharedInstance()
        do {
            try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord)
        } catch let error as NSError {
            print(error.description)
        }

        let recordSettings = [AVSampleRateKey : NSNumber(float: Float(44100.0)),
            AVFormatIDKey : NSNumber(int: Int32(kAudioFormatMPEG4AAC)),
            AVNumberOfChannelsKey : NSNumber(int: 1),
            AVEncoderAudioQualityKey : NSNumber(int: Int32(AVAudioQuality.Max.rawValue))]

        do{
            try soundRecorder = AVAudioRecorder(URL: getFileURL(), settings: recordSettings)
                soundRecorder.delegate = self
                soundRecorder.prepareToRecord()
        }
        catch let error as NSError {
            error.description
        }

    }

注意:音频会话是您的应用和iOS之间的中介,用于配置应用的音频行为。如果我们为 AVAudioSessionCategoryPlayAndRecord 设置类别,我们定义iOS音频行为以允许音频输入(录制)和输出(播放)。
参考:音频会话编程指南

NOTE: An audio session is the intermediary between your app and iOS used to configure your app’s audio behaviour. If we set category for AVAudioSessionCategoryPlayAndRecord, we define iOS audio behaviour to allow audio input (recording) and output (playback). Referred from: Audio Session Programming Guide

这篇关于AVAudioPlayer在模拟器上工作,但不在Real Device上工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆