gpt4 book ai didi

ios - 从 CMSampleBuffer 播放音频

转载 作者:IT王子 更新时间:2023-10-29 05:53:49 25 4
gpt4 key购买 nike

我在 iOS 中为群组创建了一个视频聊天应用程序。我一直在寻找一些方法来分别控制不同参与者的音量。我找到了使用 RemoteAudioTrack 中的 isPlaybackEnabled 静音和取消静音的方法,但无法控制音量。

我也想过我们是否可以在AVAudioPlayer中使用它。我找到了 addSink。这是我从 here 中尝试过的:

class Audio: NSObject, AudioSink {
var a = 1
func renderSample(_ audioSample: CMSampleBuffer!) {
print("audio found", a)
a += 1

var audioBufferList = AudioBufferList()
var data = Data()
var blockBuffer : CMBlockBuffer?

CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(audioSample, bufferListSizeNeededOut: nil, bufferListOut: &audioBufferList, bufferListSize: MemoryLayout<AudioBufferList>.size, blockBufferAllocator: nil, blockBufferMemoryAllocator: nil, flags: 0, blockBufferOut: &blockBuffer)
let buffers = UnsafeBufferPointer<AudioBuffer>(start: &audioBufferList.mBuffers, count: Int(audioBufferList.mNumberBuffers))

for audioBuffer in buffers {
let frame = audioBuffer.mData?.assumingMemoryBound(to: UInt8.self)
data.append(frame!, count: Int(audioBuffer.mDataByteSize))
}

let player = try! AVAudioPlayer(data: data) //crash here
player.play()
}
}

但它在 let player = try! 时崩溃了! AVAudioPlayer(数据:数据)


编辑:
这是错误: fatal error :“尝试!”表达式意外引发错误:Error Domain=NSOSStatusErrorDomain Code=-39 "(null)": file

这是数据,所以我猜它没有被转换:

▿ 0 bytes
- count : 0
▿ pointer : 0x000000016d7ae160
- pointerValue : 6131736928
- bytes : 0 elements

这是audioSample:

<CMAudioFormatDescription 0x2815a3de0 [0x1bb2ef830]> {
mediaType:'soun'
mediaSubType:'lpcm'
mediaSpecific: {
ASBD: {
mSampleRate: 16000.000000
mFormatID: 'lpcm'
mFormatFlags: 0xc
mBytesPerPacket: 2
mFramesPerPacket: 1
mBytesPerFrame: 2
mChannelsPerFrame: 1
mBitsPerChannel: 16 }
cookie: {(null)}
ACL: {(null)}
FormatList Array: {(null)}
}
extensions: {(null)}
}

最佳答案

您可以从CMSampleBuffer 获取完整的数据缓冲区并将其转换为Data:

let blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer)
let blockBufferDataLength = CMBlockBufferGetDataLength(blockBuffer!)
var blockBufferData = [UInt8](repeating: 0, count: blockBufferDataLength)
let status = CMBlockBufferCopyDataBytes(blockBuffer!, atOffset: 0, dataLength: blockBufferDataLength, destination: &blockBufferData)
guard status == noErr else { return }
let data = Data(bytes: blockBufferData, count: blockBufferDataLength)

同时引用 AVAudioPlayer概述:

Use this class for audio playback unless you are playing audio captured from a network stream or require very low I/O latency.

所以我认为它不适合你。你最好使用 AVAudioEngineAudio Queue Services .

关于ios - 从 CMSampleBuffer 播放音频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57075466/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com