在 Swift iOS 中播放 PCM 文件

Posted

技术标签:

【中文标题】在 Swift iOS 中播放 PCM 文件【英文标题】:Playing a PCM file in Swift iOS 【发布时间】:2015-10-20 09:20:10 【问题描述】:

我想在 Swift 2.0 中使用 AVAudioEngine 和 AVAudioPlayerNode 播放 pcm 文件。我是音频编程的新手,不理解我的代码的问题:

    var audioEngine: AVAudioEngine = AVAudioEngine()
    var audioFilePlayer: AVAudioPlayerNode = AVAudioPlayerNode()


    @IBAction func playButton(sender: AnyObject) 

    var file = "file7.pcm"
    var fileManager = NSFileManager.defaultManager()

    var wayToFile = fileManager.URLsForDirectory(NSSearchPathDirectory.DocumentDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask)
    var passMusicFileURL: NSURL?

    if let documentPath: NSURL = wayToFile.first as NSURL! 
        let musicFile = documentPath.URLByAppendingPathComponent(file)

        passMusicFileURL = musicFile

        var audioFile = AVAudioFile()
        var audioBuffer = AVAudioPCMBuffer()

        do
            audioFile = try AVAudioFile(forReading: passMusicFileURL!)
            let audioFormat = audioFile.processingFormat
            let audioFrameCount = UInt32(audioFile.length)

            audioBuffer = AVAudioPCMBuffer(PCMFormat: audioFormat, frameCapacity: audioFrameCount)

         catch 
            print("error!!! ")
        

        do 
            try audioFile.readIntoBuffer(audioBuffer)
         catch _
            print("error")
        

        var mainMixer = audioEngine.mainMixerNode
        audioEngine.attachNode(audioFilePlayer)
        audioEngine.connect(audioFilePlayer, to:mainMixer, format: audioBuffer.format)

        do 
            try audioEngine.start()
         catch _

            print("error")
        

        audioFilePlayer.play()
        audioFilePlayer.scheduleBuffer(audioBuffer, atTime: nil, options: AVAudioPlayerNodeBufferOptions.Loops, completionHandler: nil)
    

我能够构建代码,但是当我尝试运行它时出现以下错误:

ERROR: [0x1a1b6e000] AVAudioFile.mm:32: AVAudioFileImpl: error 1954115647

我知道文件路径正确,文件存在。

有人知道我做错了什么吗?

【问题讨论】:

我忘了说它是16位线性pcm 您是否尝试过使用scheduleFile(_:at:completionHandler:) 【参考方案1】:

使用 Swift 4

 func playPCM(_ filefullpathstr: String) 
    do 
        let audioFile = try AVAudioFile(forReading: URL(fileURLWithPath: filefullpathstr))

        let audioFormat = audioFile.processingFormat
        let audioFrameCount = UInt32(audioFile.length)

        let audioFileBuffer = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity: audioFrameCount)

        try audioFile.read(into: audioFileBuffer!, frameCount: audioFrameCount)

        let mainMixer = audioEngine.mainMixerNode
        audioEngine.attach(audioFilePlayer)
        audioEngine.connect(audioFilePlayer, to:mainMixer, format: audioFileBuffer?.format)

        try audioEngine.start()
        audioFilePlayer.play()
        audioFilePlayer.scheduleBuffer(audioFileBuffer!, at: nil, options: [], completionHandler: 

            DispatchQueue.main.async 
                //do sth ui ...
            
        )
     catch 
        debugPrint(#line, error)
    

【讨论】:

以上是关于在 Swift iOS 中播放 PCM 文件的主要内容,如果未能解决你的问题,请参考以下文章

如何在 iOS 中添加带有 PCM 数据/缓冲区的可播放(如 wav、wmv)标头?

AudioUnit播放PCM问题

如何在 iOS 中播放来自服务器的流式 PCM 数据?

Swift iOS实现把PCM语音转成MP3格式

iOS语音对讲(三)FFmpeg实时解码AAC并播放PCM

ios 使用audioQueue 录音以及播放 (pcm)