AVAudioPlayer 在模拟器中播放录制的音频,但不在手机上

Posted

技术标签:

【中文标题】AVAudioPlayer 在模拟器中播放录制的音频,但不在手机上【英文标题】:AVAudioPlayer playing recorded audio in simulator but not on phone 【发布时间】:2018-04-19 23:32:59 【问题描述】:

我正在尝试创建一个简单地录制和播放音频的应用程序。我尝试了多种不同的音频播放方法,但在 iPhone 6 和 iPhone 8 Plus 上播放时似乎不起作用,但在模拟器上可以。

错误:

线程 1:致命错误:在展开可选值时意外发现 nil

这发生在 SoundPlayer 尝试播放时。控制台打印的错误是:

错误域=NSOSStatusErrorDomain 代码=2003334207 "(null)"

@IBOutlet weak var recordBtn: UIButton!
@IBOutlet weak var playBtn: UIButton!
var soundRecorder : AVAudioRecorder!
var soundPlayer : AVAudioPlayer!
var fileName = "audioFile0.aac"

var screenCounter = 0(全局变量)

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


override open func viewDidLoad() 
    super.viewDidLoad()
    if (screenCounter == 0)
    // Do any additional setup after loading the view, typically from a nib.
        setupRecorder()
        screenCounter += 1
    




func setupRecorder()
    let recordSettings = [ AVFormatIDKey : kAudioFormatMPEG4AAC
        , AVEncoderAudioQualityKey : AVAudioQuality.max.rawValue, AVEncoderBitRateKey : 320000, AVNumberOfChannelsKey : 2, AVSampleRateKey : 44100.0 ] as [String : Any]
    let _ : NSError?
    do
        soundRecorder = try AVAudioRecorder(url : getFileURL() as URL, settings : recordSettings)
    catch
        print("Something went wrong")
    
    soundRecorder.delegate = self
    soundRecorder.prepareToRecord()



func getCacheDirectory() -> String
    let paths = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
     return paths[0]


func getFileURL() -> NSURL
    let pathURL = NSURL(fileURLWithPath : getCacheDirectory()).appendingPathComponent(fileName)
    let pathString = pathURL?.path
    let filePath = NSURL(fileURLWithPath : pathString!)
    return filePath



@IBAction func record(_ sender: UIButton) 
    if sender.titleLabel?.text == "Record"
        soundRecorder.record()
        sender.setTitle("Stop", for : .normal)
        playBtn.isEnabled = false
    else
        soundRecorder.stop()
        sender.setTitle("Record", for : .normal)
        playBtn.isEnabled = false
    

@IBAction func playSound(_ sender: UIButton) 
    if sender.titleLabel?.text == "Play"
            recordBtn.isEnabled = false
            sender.setTitle("Stop", for : .normal)
            preparePlayer()
            soundPlayer.play()
    else
        soundPlayer.stop()
        sender.setTitle("Play", for : .normal)
    


func preparePlayer()
    let _ : NSError?
    do
        soundPlayer = try AVAudioPlayer(contentsOf : getFileURL() as URL)
    catch
        print(error)
    
    soundPlayer.delegate = self
    soundPlayer.prepareToPlay()
    soundPlayer.volume = 1.0



open func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) 
    playBtn.isEnabled = true

open func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) 
    recordBtn.isEnabled = true
    playBtn.setTitle("Play", for : .normal)

任何帮助将不胜感激。

更新

感谢您的所有建议!我最终在另一个论坛here 上找到了错误。似乎在录制和播放音频之间需要一个中介,称为音频会话。

【问题讨论】:

【参考方案1】:

尝试在 playSoung 方法之外初始化 soundPlayer。

var soundPlayer = AVAudioPlayer()

func preparePlayer() 
    ...

【讨论】:

如果您指的是 playSound - soundPlayer 未在其中初始化。如果您指的是 preparePlayer() - 它不能在外部初始化,除非 getFileURL() 生成目录以便它可以使用该音频【参考方案2】:

音频文件的 url 似乎是 nil。你可以试试这个FileManager

//func to give path(URL) to store the recording
    func getDirectory() -> URL 
        let path = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        let docDirectory = path[0]
        return docDirectory
    

你的文件 URL 完整路径应该是:

let path =   getDirectory().appendingPathComponent(fileName)

注意:由于我无法运行和测试您的代码,我不确定解决方案。让我知道结果。否则,我将删除我的帖子。

【讨论】:

以上是关于AVAudioPlayer 在模拟器中播放录制的音频,但不在手机上的主要内容,如果未能解决你的问题,请参考以下文章

录制音频并保存到文档目录后无法使用 AVAudioPlayer 播放音频文件

Swift AVAudioPlayer 不会播放用 AVAudioRecorder 录制的音频

关于使用 AVAudioPlayer 自动录制和自动播放 AVAudioRecorder

AVAudioRecorder 不保存文件

AvAudioPlayer 不工作?

使用 AVAudioRecorder 录制后,AVAudioPlayer 不通过扬声器播放