我在iOS上启动音频会话时遇到问题

问题描述

尝试启动音频会话时出现以下错误

2020-08-24 15:48:35.590348-0300 MyApp[728:187819] [aid] AudioIssueDetectorNode.cpp:166:Initialize: Caught analyzer graph exception 1718775073 !mrf slice duration must be set before configure. in /Library/Caches/com.apple.xbs/Sources/AudioDSP/AudioDSP-366.38/CoreAudioUtility/Source/CADSP/DSPGraph/DSPGraph_Graph.cpp:628

2020-08-24 15:48:35.633035-0300 MyApp[728:187819] [aurioc] AURemoteIO.cpp:1590:Start: AUIOClient_StartIO Failed (-66637)

我的目标是从麦克风获取输入音频

到目前为止,我的代码

import Foundation
import AVFoundation

class AudioController {
    
    //    MARK: - Atributos
    var remoteIoUnit: AudioComponentInstance?
    var delegate: AudioControllerDelegate?
    
    var mBitsChannel: UInt32 = 8
    var mChannels: UInt32 = 1
    
    var packetCount: UInt16 = 0
    var timestamp:UInt32 = 0
    var ssrc:UInt32 = 0
    
    var rtpMode: RTPMode = RTPMode.PCMA

    // Iniciando instancia compartilhada
    static var sharedInstance = AudioController()
    
    func removeCurrentInstance() {
        if let remote = AudioController.sharedInstance.remoteIoUnit {
            AudioComponentInstancedispose(remote)
        }
    }
    
//    MARK: - Configuração de sessão de audio
    func prepare(specifiedSampleRate: Double,mode: RTPMode) -> Osstatus {
        
        removeCurrentInstance()
        
        rtpMode = mode
        var status = noErr
        
        let session = AVAudioSession.sharedInstance()
        
        session.requestRecordPermission {(granted) in
            if granted {
                print("Permissão de audio já foi concedida")
                do {
                    try session.setCategory(.playAndRecord)
                    try session.setPreferredioBufferDuration(1)
                } catch {
                    print(error.localizedDescription)
                }
            }else {
                print("Permissão de audio não foi concedida")
            }
        }

        // Inicio randonico para payload RTP
        packetCount = UInt16.random(in: UInt16.min..<100)
        timestamp   = UInt32.random(in: UInt32.min..<100)
        ssrc        = UInt32.random(in: UInt32.min..<100)
        
        var sampleRate = session.sampleRate
        print("hardware sample rate = \(sampleRate),using specified rate = \(specifiedSampleRate)")
        sampleRate = Double(specifiedSampleRate)
        
        // Descrição do remote unit
        var audioComponentDescription = AudioComponentDescription()
        audioComponentDescription.componentType = kAudioUnitType_Output;
        audioComponentDescription.componentSubType = kAudioUnitSubType_VoiceProcessingIO;
        audioComponentDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
        audioComponentDescription.componentFlags = 0;
        audioComponentDescription.componentFlagsMask = 0;
        
        // Buscando RemoteIO unit do hardware
        let remoteIOComponent = AudioComponentFindNext(nil,&audioComponentDescription)
        status = AudioComponentInstanceNew(remoteIOComponent!,&remoteIoUnit)
        if (status != noErr) {
            return status
        }
        
        let bus1 : AudioUnitElement = 1
        
        var turnON : UInt32 = 1
        var turnOFF: UInt32 = 0
        
        // Ativa a enTrada de audio do hardware
        status = AudioUnitSetProperty(remoteIoUnit!,kAudioOutputUnitProperty_EnableIO,kAudioUnitScope_Input,bus1,&turnON,UInt32(MemoryLayout.size(ofValue: turnON)))
        if (status != noErr) {
            return status
        }
        
        // Setando o formato da enTrada de audio do bus(1)
        var asbd = AudioStreamBasicDescription()
        asbd.mSampleRate = sampleRate
        
        switch mode {
        case .GSM:
            asbd.mFormatID = kAudioFormatMicrosoftGSM
            break
        case .PCMA:
            asbd.mFormatID = kAudioFormatALaw
            break
        case .PCMU:
            asbd.mFormatID = kAudioFormatULaw
            break
        }
        
        asbd.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked
        asbd.mBitsPerChannel = mBitsChannel
        asbd.mChannelsPerFrame = mChannels
        asbd.mFramesPerPacket = 1
        
        let bytes = (mBitsChannel / 8) * mChannels;
        
        asbd.mBytesPerPacket = bytes
        asbd.mBytesPerFrame = bytes
        
        status = AudioUnitSetProperty(remoteIoUnit!,kAudioUnitProperty_StreamFormat,kAudioUnitScope_Output,&asbd,UInt32(MemoryLayout<AudioStreamBasicDescription>.size))
        if (status != noErr) {
            return status
        }
        
        // Adicionando callback para gravação de audio
        var callbackStruct = AURenderCallbackStruct()
        callbackStruct.inputProc = recordingCallback
        callbackStruct.inputProcRefCon = nil
        
        status = AudioUnitSetProperty(remoteIoUnit!,kAudioOutputUnitProperty_SetInputCallback,kAudioUnitScope_Global,&callbackStruct,UInt32(MemoryLayout<AURenderCallbackStruct>.size));
        
        // Desativando processamento do audio automatico e cancelamento de ruido
        status = AudioUnitSetProperty(remoteIoUnit!,kAUVoiceIOProperty_BypassVoiceProcessing,&turnOFF,UInt32(MemoryLayout.size(ofValue: turnOFF)))
        
        status = AudioUnitSetProperty(remoteIoUnit!,kAUVoiceIOProperty_VoiceProcessingEnableAGC,UInt32(MemoryLayout.size(ofValue: turnOFF)))
        
        if (status != noErr) {
            return status
        }
        
        // Inicializa a intancia de audio do RemoteIO unit
        guard let remote = AudioController.sharedInstance.remoteIoUnit else {
            print("RemoteIO unit não pode ser inicializado")
            return noErr
        }
        return AudioUnitinitialize(remote)
    }
    
//    MARK: - Funções de inicio da sessão de audio
    func start() -> Osstatus {
        guard let remote = AudioController.sharedInstance.remoteIoUnit else {
            print("RemoteIO não inicializado a comunição de audio nao vai ser iniciada")
            return noErr
        }
        
        return AudioOutputUnitStart(remote)
    }
    
    func stop() -> Osstatus {
        guard let remote = AudioController.sharedInstance.remoteIoUnit else {
            print("RemoteIO não finalizado por que não existe nenhuma instancia")
            return noErr
        }
        
        return AudioOutputUnitStop(remote)
    }
}

当我并行启动rtsp视频连接时,此错误开始对我出现。如果我只是开始音频会话,那么一切正常,但是如果我开始播放rtsp视频和音频,则会收到上述错误

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)