简体   繁体   English

AVAudioPlayer在模拟器上工作但不在Real Device上工作

[英]AVAudioPlayer working on Simulator but not on Real Device

While I play recorded Audio I get this error: 当我播放录制的音频时,我收到此错误:

fatal error: unexpectedly found nil while unwrapping an Optional value 致命错误:在展开Optional值时意外发现nil

on this line of code: 在这行代码上:

SoundPlayer = try AVAudioPlayer(contentsOfURL: getFileURL())

But it is working perfectly on Simulator except real device. 但它在模拟器上完美运行,除了真实设备。

ViewController.Swift: 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
        }
    }
}

Storyboard file for ViewController.Swift: ViewController.Swift的Storyboard文件:

在此输入图像描述

Additional info: 附加信息:

  • Xcode version : 7.2.1 Xcode版本:7.2.1
  • Device : iPhone 5s 设备:iPhone 5s
  • iOS version : 9.2.1 iOS版本:9.2.1

Note: I have looked for similar SO solutions but none of them helped me. 注意:我已经寻找类似的SO解决方案,但没有一个帮助我。 Some of them due to older Swift version and deprecated method. 其中一些是由于较旧的Swift版本和不推荐使用的方法。 Some solutions were regarding playing audio file from application bundle and some of were using web URLs. 一些解决方案涉及从应用程序包播放音频文件,一些使用Web URL。 So, this case is different( Real Device vs Simulator ) 所以,这种情况不同( Real Device vs Simulator

Here is the link of source code on Google Drive . 以下是Google云端硬盘中源代码的链接。

On a real device, it needs to setCategory() for AVAudioSession.sharedInstance() 在真实设备上,需要为setCategory()设置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
        }

    }

NOTE: An audio session is the intermediary between your app and iOS used to configure your app's audio behaviour. 注意:音频会话是您的应用和iOS之间的中介,用于配置应用的音频行为。 If we set category for AVAudioSessionCategoryPlayAndRecord , we define iOS audio behaviour to allow audio input (recording) and output (playback). 如果我们为AVAudioSessionCategoryPlayAndRecord设置类别,我们定义iOS音频行为以允许音频输入(录制)和输出(播放)。 Referred from: Audio Session Programming Guide 参考: 音频会话编程指南

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用AVAudioPlayer播放的音频在iPhone Simulator中有效,但在Device中不起作用 - Audio played using AVAudioPlayer is working in iPhone Simulator but not in the Device 后台获取在模拟器中工作但在真实设备中不工作 - Background fetch working in simulator but not working in real device AVAudioPlayer崩溃模拟器但在设备上运行 - AVAudioPlayer crashing simulator but runs on device 电话间隙-在模拟器上无法在真实设备上工作 - Phone Gap - Working on Simulator not on real device free()使用iOS Simulator,但不能在实际设备上使用 - free() working with iOS Simulator but not on real device Expo 应用程序在 Expo Go 和 iOS 模拟器上工作,但在真实设备上崩溃 - Expo app working on Expo Go and iOS Simulator but crashes on real device 为什么线性梯度在模拟器中效果很好,但在真实设备上却不行 - Why is linear gradient working well in simulator but not on real device Flutter iOS 应用程序在模拟器中完美运行,但在真实设备中无法运行 - Flutter iOS app working perfect in simulator but not in real device UIImage在模拟器上显示,而不是在真实设备上显示 - UIImage is showing on simulator, not on a real device 使用真实设备作为模拟器和存储 - Using real device as simulator & storage
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM