Swift 没有声音

Swift 没有声音,swift,iphone,avfoundation,Swift,Iphone,Avfoundation,我已经尝试了一段时间,现在如何从iOS中的URLSessionDataTask提供的数据流实时音频 我已经声明了一个用于管理玩家操作的自定义类,它如下所示: import UIKit import AVFoundation class AudioDataPlayer: NSObject { //MARK:- Variables //MARK: Constants enum Status{ case playing case notPl

我已经尝试了一段时间,现在如何从iOS中的URLSessionDataTask提供的数据流实时音频

我已经声明了一个用于管理玩家操作的自定义类,它如下所示:

import UIKit
import AVFoundation


class AudioDataPlayer: NSObject {

    //MARK:- Variables
    //MARK: Constants
    enum Status{
        case playing
        case notPlaying
    }

    let audioPlayerQueue = DispatchQueue(label: "audioPlayerQueue", qos: DispatchQoS.userInteractive)


    //MARK: Vars
    private (set) var currentStatus:Status = .notPlaying

    private var audioEngine: AVAudioEngine = AVAudioEngine()
    private var streamingAudioPlayerNode: AVAudioPlayerNode = AVAudioPlayerNode()
    private (set) var streamingAudioFormat: AVAudioFormat = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: 48000, channels: 2, interleaved: false)!



    //MARK:- Constructor
    override init() {
        super.init()

    }



    //MARK:- Private methods



    //MARK:- Public methods
    func processData(_ data:Data) throws{

        if currentStatus == .notPlaying{

            do{

                try AVAudioSession.sharedInstance().setCategory(.playAndRecord, mode: .default, options: [.allowAirPlay])
                try AVAudioSession.sharedInstance().setActive(true)

                if #available(iOS 11.0, *) {
                    try audioEngine.enableManualRenderingMode(.realtime, format: streamingAudioFormat, maximumFrameCount: 3072)
                }

                audioEngine.attach(streamingAudioPlayerNode)
                audioEngine.connect(streamingAudioPlayerNode, to: audioEngine.mainMixerNode, format: streamingAudioFormat)

                currentStatus = .playing

            }
            catch{

                print("\(logClassName) ERROR -> \(error.localizedDescription)")

            }

        }

        audioPlayerQueue.async {

            if let audioPCMBuffer = data.makePCMBuffer(format: self.streamingAudioFormat){

                self.streamingAudioPlayerNode.scheduleBuffer(audioPCMBuffer, completionHandler: {

                   //TODO
                })

                if !self.audioEngine.isRunning{

                    try! self.audioEngine.start()
                    self.streamingAudioPlayerNode.play()

                }

            }
            else{

                print("\(self.logClassName) TEST -> Ignoring data to play ...")

            }

        }

    }

    func stop(){

        audioEngine.stop()
        audioEngine.detach(streamingAudioPlayerNode)
        currentStatus = .notPlaying

    }


}
管理传入数据的函数是'processData('data:data'),它从另一个类中这样调用:

let processingQueue = DispatchQueue(label: "processingQueue", qos: DispatchQoS.userInteractive)

var audioDataPlayer:AudioDataPlayer = AudioDataPlayer()

func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {

    processingQueue.async {

        try! self.audioDataPlayer.processData(data)

    }

}
我从论坛和apple documanetation网站上获得了代码。然而,也许我仍然不明白它是如何工作的,并且没有从设备发出声音

音频数据为48K、16位和2通道格式


有什么想法吗?

如果音频数据是16位(可以假设为整数),则需要使用
pcmFormatInt16
而不是
pcmFormatFloat32
初始化
AVAudioFormat


对于这种格式来说,非交错似乎有点奇怪,因此您可能必须将
交错
设置为
如果您的音频数据是16位(可以假设为整数),则需要使用
pcmFormatInt16
而不是
pcmFormatFloat32
初始化
AVAudioFormat


对于这种格式,非交错似乎有点奇怪,因此您可能必须将
交错
设置为

我尝试了您的建议,并得到以下错误-->019-02-14 08:10:46.177160+0000 MyAppl[307:10016]AUBase.cpp:832:DispatchSetProperty:ca_require:ValidFormat(inScope,inElement,newDesc)InvalidFormat连接StreamingAudioPlayerNode时出错您是否确实从url会话中获取了未压缩的原始音频样本,但没有任何标题信息等?所以它不是mp3或其他文件格式?我这样认为是因为我能够使用AudioFileWriteBytes将数据写入文件。值得一提的是,数据有不同的数组大小。@Reimondh您是如何修复
ValidFormat
错误的?有同样的问题。我尝试了你的建议,我得到了以下错误-->019-02-14 08:10:46.177160+0000 MyAppl[307:10016]AUBase.cpp:832:DispatchSetProperty:ca_require:ValidFormat(inScope,inElement,newDesc)invalidFormat连接StreamingAudioPalyerNode时发生错误你真的确定你得到的是原始的吗,url会话中没有任何标题信息等的未压缩音频样本?所以它不是mp3或其他文件格式?我这样认为是因为我能够使用AudioFileWriteBytes将数据写入文件。值得一提的是,数据有不同的数组大小。@Reimondh您是如何修复
ValidFormat
错误的?有同样的问题。