Loading [MathJax]/jax/output/CommonHTML/config.js
社区首页 >问答首页 >AKPlayer在channelCount条件下从缓冲区播放时崩溃

AKPlayer在channelCount条件下从缓冲区播放时崩溃
EN

Stack Overflow用户
提问于 2018-10-27 23:05:32
回答 1查看 706关注 0票数 3

我很难使下面的场景像预期的那样工作(下面将提供代码)。

  1. 记录我的麦克风输入并将一个AVAudioPCMBuffer存储在内存中,这是用AVAudioPCMBuffer扩展方法copy(from buffer: AVAudioPCMBuffer, readOffset: AVAudioFrameCount = default, frames: AVAudioFrameCount = default)完成的。--我确实在录音的末尾得到了缓冲器。
  2. 当记录结束时,将缓冲区传递给AKPlayer并播放。这里有一个代码片段来演示我所做的事情(我知道这不是完整的应用程序代码,如果需要的话,我可以分享):

代码语言:javascript
代码运行次数:0
复制
private var player: AKPlayer = AKPlayer()
self.player.buffering = .always

// in the record complete callbak:
self.player.buffer = self.bufferRecorder?.pcmBuffer
self.player.volume = 1
self.player.play()
  • 请注意,平台是连接到混频器,这是最终连接到AudioKit输出。

当我检查和调试应用程序时,我可以看到缓冲区的长度是正确的,并且我的所有输出/输入设置都使用相同的处理格式(采样速率、通道、比特率等)以及记录的缓冲区,但我的应用程序仍然在这一行崩溃:

代码语言:javascript
代码运行次数:0
复制
2018-10-28 08:40:32.625001+0200 BeatmanApp[71037:6731884] [avae] AVAEInternal.h:70:_AVAE_Check: 
required condition is false: [AVAudioPlayerNode.mm:665:ScheduleBuffer: (_outputFormat.channelCount == buffer.format.channelCount)]

当我调试和遍历AudioKit代码时,我可以看到断线在AKPlayer+Playback.swift上的line 162上,在方法:playerNode.scheduleBuffer上。

更多可能有用的信息:

  • 记录的缓冲区长达16秒。
  • 当我试图将缓冲区直接传递给点击方法中的播放器节点时,我确实听到了从麦克风到扬声器的延迟,但它确实回放了。
  • 我试着在调用游戏方法之前对玩家进行呼叫准备,没有任何帮助。

谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-01 21:58:30

好吧,这是超级不酷的调试会话。我必须研究AVAudioEngine以及如何在那里实现这种场景,当然,这不是我正在寻找的最终结果。这个探索帮助我理解了如何用AudioKit来解决这个问题(我的应用程序的一半是使用AudioKit的工具实现的,所以用AVFoundation重写它是没有意义的)。

AFFoundation 解决方案:

代码语言:javascript
代码运行次数:0
复制
private let engine = AVAudioEngine()
private let bufferSize = 1024
private let p: AVAudioPlayerNode = AVAudioPlayerNode()

let audioSession = AVAudioSession.sharedInstance()
do {
    try audioSession.setCategory(.playAndRecord, mode: .default, options: .defaultToSpeaker)
} catch {
    print("Setting category to AVAudioSessionCategoryPlayback failed.")
}

let inputNode = self.engine.inputNode
engine.connect(inputNode, to: engine.mainMixerNode, format: inputNode.inputFormat(forBus: 0))
// !!! the following lines are the key to the solution.
// !!! the player has to be attached to the engine before actually connected
engine.attach(p) 
engine.connect(p, to: engine.mainMixerNode, format: inputNode.inputFormat(forBus: 0)) 

do {
    try engine.start()
} catch {
    print("could not start engine \(error.localizedDescription)")
}

recordBufferAndPlay(duration: 4)

recordBufferAndPlay函数:

代码语言:javascript
代码运行次数:0
复制
func recordBufferAndPlay(duration: Double){
    let inputNode = self.engine.inputNode
    let total: Double = AVAudioSession.sharedInstance().sampleRate * duration
    let totalBufferSize: UInt32 = UInt32(total)

    let recordedBuffer : AVAudioPCMBuffer! = AVAudioPCMBuffer(pcmFormat: inputNode.inputFormat(forBus: 0), frameCapacity: totalBufferSize)

    var alreadyRecorded = 0
    inputNode.installTap(onBus: 0, bufferSize: 256, format: inputNode.inputFormat(forBus: 0)) {
        (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in
        recordedBuffer.copy(from: buffer) // this helper function is taken from audio kit!
        alreadyRecorded = alreadyRecorded + Int(buffer.frameLength)
        print(alreadyRecorded, totalBufferSize)
        if(alreadyRecorded >= totalBufferSize){
            inputNode.removeTap(onBus: 0)
            self.p.scheduleBuffer(recordedBuffer, at: nil, options: .loops, completionHandler: {
                print("completed playing")
            })
            self.p.play()
        }
    }
}

AudioKit 解决方案:

因此,在AudioKit解决方案中,应该在AKPlayer对象上调用这些行。请注意,这应该在您实际启动引擎之前完成。

代码语言:javascript
代码运行次数:0
复制
self.player.buffering = .always
AudioKit.engine.attach(self.player.playerNode)
AudioKit.engine.connect(self.player.playerNode, to: self.mixer.inputNode, format: AudioKit.engine.inputNode.outputFormat(forBus: 0))

记录的完成方式与在AVAudioEngine中所做的非常相似,而是在节点(麦克风或其他节点)上安装一个点击,并记录PCM示例的缓冲区。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53029148

复制
相关文章
MySQL浮点数与定点数
浮点数一般用于表示含有小数部分的数值。当一个字段被定义为浮点类型后,如果插入数据的精度超过该列定义的实际精度,则插入值会被四舍五入到实际定义的精度值,然后插入,四舍五入的过程不会报错。在MySQL中float和double用来表示浮点数。
秋白
2019/02/21
1.3K0
MySQL浮点数与定点数
zTree实现访问到第一节点在相同水平当前所选节点数目
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/117238.html原文链接:https://javaforall.cn
全栈程序员站长
2022/07/06
4190
zTree实现访问到第一节点在相同水平当前所选节点数目
定点数与浮点数表示
定点数与浮点数据表示 <1> 定点数据表示 可表示定点小数和整数 表现形式:X<sub>0</sub>.X<sub>1</sub>X<sub>2</sub>X<sub>3</sub> ... X<sub>n</sub>(定点小数) 定点小数的表示数的范围(补码为例):-1 $\leq$ x $\leq$ 1-2<sup>n</sup> 定点整数表示数的范围(补码为例): -2<sup>n</sup> $\leq$ x $\leq$ 2<sup>n</sup> - 1 顶点数据表示数的不足:数据表示范围受
ruochen
2021/05/16
8390
定点数与浮点数表示
基于System Generator的浮点数与定点数设计(实现与分析)
打开System Generator,然后将第一次设计的滤波器文件Copy一份然后进行一些更改,或直接新建模型,以可以参考前几篇文章
狂人V
2020/06/29
8250
编辑器对于内存的使用——数据的保存与访问使用(浮点数篇)
在上一篇文章中我们已经讨论了整形在编辑器中是如何使用和保存的了,详情请见这篇文章——
比特大冒险
2023/04/16
2890
编辑器对于内存的使用——数据的保存与访问使用(浮点数篇)
☆打卡算法☆LeetCode 149. 直线上最多的点数 算法解析
给你一个数组 points ,其中 points[i] = [xi, yi] 表示 X-Y 平面上的一个点。求最多有多少个点在同一条直线上。
恬静的小魔龙
2022/08/07
3520
☆打卡算法☆LeetCode 149. 直线上最多的点数 算法解析
第十节、Python中整数和浮点数《Python学习》
Python支持对整数和浮点数直接进行四则混合运算,运算规则和数学上的四则运算规则完全一致。
申霖
2019/12/27
7580
第十节、Python中整数和浮点数《Python学习》
【学点数据结构和算法】05-树
通过【学点数据结构和算法】系列的1-4,我们已经学习了数据结构中常用的线性结构。从物理存储方面来说,它们又分为顺序存储和链式存储结构。他们各自有自己的优缺点,顺序存储结构读快写慢,链式存储结构写快读慢。但是这些数据元素之间的关系都为一对一的关系,而我们生活中关系不止是一对一,有可能是一对多,多对多的情况… 本篇博客,我们就要学习一种新的数据结构——树,它将为我们展示一个全新的“世界”。
大数据梦想家
2021/01/27
3940
【学点数据结构和算法】05-树
【唯实践】基于Alluxio优化电商平台热点数据访问性能
在互联网电商平台上,广告是提升成交总额(Gross Merchandise Volume)和拉取新客的常见途经。在广告系统或广告运营中都需要基于人群数据分析进行定向的用户广告投放。在第三方平台进行广告投放,同样需要使用人群数据分析计算。根据计算分析方的不同,可以分为两类,第一类是基础数据全部发送给第三方广告平台,如抖音,腾讯等,由第三方在投放人群时候进行人群计算并作选择;第二类是人群计算工作在电商平台内部完成,推送给第三方的只是单个的人群包数据(设备数据)。在唯品会,我们目前采用第二类方式进行人群计算投放。我们每天需要完成数万的人群包计算,这些计算都是基于几张位于HDFS的之上的Hive 表完成,这些表每天通常都需要被访问上万次。
Spark学习技巧
2021/03/05
6080
【唯实践】基于Alluxio优化电商平台热点数据访问性能
浮点数原理与精度损失问题
计算机中小数的表示按照小数点的位置是否固定可以分为浮点数和定点数。为了方便和float32浮点数做对比,我们构造一个32位精度的定点数,其中小数点固定在23bit处:
TOMOCAT
2020/10/29
3.2K0
浮点数原理与精度损失问题
算法分析----第一节
O(n)不是算法,它是一个函数,是一个表征算法时间复杂度的一个函数。 计算机科学中,算法的时间复杂度是一个函数,它定性描述了该算法的运行时间。这是一个关于代表算法输入值的字符串的长度的函数。时间复杂度常用大O符号表述,不包括这个函数的低阶项和首项系数。 使用这种方式时,时间复杂度可被称为是渐近的,它考察当输入值大小趋近无穷时的情况。
Dream城堡
2019/03/20
3960
算法分析----第一节
ACM算法竞赛——浮点数二分(模板)
浮点数二分算法代码比整数二分算法简洁易懂,也不需要处理复杂的边界问题 bool check(double x) {/* ... */} // 检查x是否满足某种性质 double bsearch_3(double l, double r) { const double eps = 1e-6; // eps 表示精度,取决于题目对精度的要求 while (r - l > eps) { double mid = (l + r) / 2; if (ch
战士小小白
2022/05/14
2760
ACM算法竞赛——浮点数二分(模板)
【学点数据结构和算法】02-链表
上一篇博客博主为大家带来了数组的内容分享,本篇博客我们来学习另外一个重要的数据结构——链表!
大数据梦想家
2021/01/27
5480
【学点数据结构和算法】02-链表
【学点数据结构和算法】01-数组
先来解释下博主为什么会在这个时候开设一个专栏来学习【数据结构和算法】。
大数据梦想家
2021/01/27
5800
【学点数据结构和算法】01-数组
定点数和浮点数_定点数和浮点数哪个精度高
计算机中常用的数据表示格式有两种,一是定点格式,二是浮点格式。所谓定点数和浮点数,是指在计算机中一个数的小数点的位置是固定的还是浮动的:如果一个数中小数点的位置是固定的,则为定点数;如果一个数中小数点的位置是浮动的,则为浮点数。一般来说,定点格式可表示的数值的范围有限,但要求的处理硬件比较简单。而浮点格式可表示的数值的范围很大,但要求的处理硬件比较复杂。
全栈程序员站长
2022/11/03
1.1K0
小朋友学C语言(4):单精度浮点数与双精度浮点数
上节课 简单介绍了浮点数。计算机程序中的浮点数分为单精度浮点数和双精度浮点数。 单精度和双精度精确的范围不一样。 计算机里的最基本的存储单位用位(bit)来表示。bit只能用来存储0或1。 稍大一点的单位是字节(Byte,简写为B)。 再大一级的是千字节(kilo Bytes),用k来表示。 再大一级的单位是兆字节(Mega Bytes),用M来表示。一张照片的大小通常为1~3M。 再大一级的单位为G。一部高清电影的大小通常为1~2G。 再大一级的单位为T。 换算关系为: 1B = 8bit 1k =
海天一树
2018/04/17
2.8K0
小朋友学C语言(4):单精度浮点数与双精度浮点数
【学点数据结构和算法】04-散列表
前面已经陆陆续续写了几篇介绍数据结构的博客,包含数组,链表,栈和队列…本篇博客,我们再来学习一种有趣的数据结构——散列表。
大数据梦想家
2021/01/27
4600
【学点数据结构和算法】04-散列表
浮点数与十六进制互相转换
利用强制转换类型实现。 浮点数转十六进制 实现: float f = 123.45f; unsigned char *hex = (unsigned char *)&f; 打印输出: for(int i = 0; i < 4; i++) printf("0x%02X ", hex[i]); printf("\n"); 十六进制转浮点数 实现: unsigned char hex[] = { 0x66, 0xE6, 0xF6, 0x42 }; float f = *(float *)hex;
Qt君
2019/09/10
4.2K0
点击加载更多

相似问题

如何在Visual Studio C#窗体中创建滚动平铺

137

创建可滚动窗口窗体C#

14

列表视图xamarin窗体滚动中的图像消失

20

我们如何在c#窗体中弹出图片框,如bing图像搜索

310

如何在C#窗口窗体中创建选项窗体?

35
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档