2016-02-17 13 views
2

В то время как я играю записанные аудио Я получаю эту ошибку:AVAudioPlayer работает на симуляторе, но не на реальном устройстве

fatal error: unexpectedly found nil while unwrapping an Optional value

на эту строку кода:

SoundPlayer = try AVAudioPlayer(contentsOfURL: getFileURL()) 

Но он прекрасно работает на симуляторе, кроме реальное устройство.

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:

enter image description here

Дополнительная информация:

  • Xcode версия: 7.2.1
  • устройства: iPhone 5s
  • IOS версия: 9.2.1

Примечание: Я смотрел на аналогичный SO решения, но ни один из них не помог мне. Некоторые из них из-за более старой версии Swift и устаревшего метода. Некоторые решения касались воспроизведения аудиофайла из пакета приложений, а некоторые из них использовали веб-адреса. Итак, этот случай отличается (Real Device vs Simulator)

Вот ссылка на исходный код на Google Drive.

ответ

4

На реальном устройстве, он должен setCategory() для AVAudioSession.sharedInstance()

И фиксированный проект может быть загружен here тоже.

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 для разрешения ввода (записи) и выхода (воспроизведения). Рефералы: Audio Session Programming Guide

+0

Не работает. Он даже перестал работать на Simulator. –

+0

Вы попробовали его на реальном устройстве? – Allen

+0

Да ... Сбой на одной строке кода –

Смежные вопросы