cocos creater 鸿蒙 音频卡死 播放失败 不回调

2023-11-03

cocos creater音频播放失败 || 不回调 || 卡死 || 鸿蒙

问题背景

  1. 开发过程中 未发现问题

  2. 线上 部分鸿蒙用户反馈: 页面卡死没反应 || 页面不能继续下一步

  3. so: 问题有可能是 音频没播出来, 或者回调没回来, 或者 获取音频的时长错误

测试现场1

  1. 经过测试的重复复现问题 得到一个现场数据 如下

    2022-08-09 17:10:54.792 21491-21981/com.zuoyebang.bangbangshizi V/AudioEngineImpl: play2d, _audioPlayers.size=0
    2022-08-09 17:10:54.792 21491-21981/com.zuoyebang.bangbangshizi V/AudioPlayerProvider: (@assets/assets/bundle_common/native/5b/5b1f43ed-ff53-42f2-ae62-b8770d2533ad.mp3) file size: 979728
    2022-08-09 17:10:54.792 21491-21981/com.zuoyebang.bangbangshizi V/UrlAudioPlayer: Current UrlAudioPlayer instance count: 1
    2022-08-09 17:10:54.792 21491-21981/com.zuoyebang.bangbangshizi V/UrlAudioPlayer: UrlAudioPlayer::prepare: @assets/assets/bundle_common/native/5b/5b1f43ed-ff53-42f2-ae62-b8770d2533ad.mp3, SL_DATALOCATOR_ANDROIDFD, 147, 190559016, 979728
    2022-08-09 17:10:54.792 21491-21981/com.zuoyebang.bangbangshizi I/AudioSystem: getDeviceConnectionState , Connecting to the Bluetooth device
    2022-08-09 17:10:54.792 21491-21981/com.zuoyebang.bangbangshizi I/IAudioPolicyService: getDeviceConnectionState, BpAudioPolicy: Bluetooth device
    2022-08-09 17:10:54.796 21491-21981/com.zuoyebang.bangbangshizi V/AudioEngineImpl: play2d, _audioPlayers.size=1
    2022-08-09 17:10:54.796 21491-21981/com.zuoyebang.bangbangshizi V/AudioPlayerProvider: (@assets/assets/bundle_common/native/be/be1894f3-7064-4479-94fe-cfaabe1a07c6.mp3) file size: 202477
    2022-08-09 17:10:54.796 21491-21981/com.zuoyebang.bangbangshizi V/UrlAudioPlayer: Current UrlAudioPlayer instance count: 2
    2022-08-09 17:10:54.796 21491-21981/com.zuoyebang.bangbangshizi V/UrlAudioPlayer: UrlAudioPlayer::prepare: @assets/assets/bundle_common/native/be/be1894f3-7064-4479-94fe-cfaabe1a07c6.mp3, SL_DATALOCATOR_ANDROIDFD, 151, 387146732, 202477
    2022-08-09 17:10:54.796 21491-21981/com.zuoyebang.bangbangshizi I/AudioSystem: getDeviceConnectionState , Connecting to the Bluetooth device
    2022-08-09 17:10:54.796 21491-21981/com.zuoyebang.bangbangshizi I/IAudioPolicyService: getDeviceConnectionState, BpAudioPolicy: Bluetooth device
    2022-08-09 17:10:54.880 21491-28436/com.zuoyebang.bangbangshizi E/libOpenSLES: Error after prepare: 1
    2022-08-09 17:10:54.885 21491-28433/com.zuoyebang.bangbangshizi E/libOpenSLES: Error after prepare: 1
    2022-08-09 17:11:01.042 21491-22407/com.zuoyebang.bangbangshizi E/NLog: start or restart send timer, sendInterval=30.
    
  2. 上边的数据可以看到: E/libOpenSLES: Error after prepare: 1

  3. 查找相关资料 : https://www.twblogs.net/a/5c83723dbd9eee35fc13cb3e/?lang=zh-cn

  4. 查阅资料可知:

    (1) E/libOpenSLES(25131): Too many objects
    (2) E/libOpenSLES: Error after prepare: 1
    
    第一个, 是SLPlayItf对象没有及时销毁,不同的平台SLPlayItf同时支持的数量不同,大约是2-10左右,所以音频播放完成之后,需要及时销毁。否则,出现(1)的错误,就会播放不出来声音,到一定程度就会导致崩溃。
    
    第二个, 是因为播放文件的格式OpenSLES不支持,或是文件有问题,无法正确播放。并且出现这种问题后,会让SLPlayItf的回调函数无法正确执行,最终导致SLPlayItf越来越多,从而出现(1)的情况和结局。
    
    那么,解决(1)的问题,就是在音频播放完成后及时销毁,我们可以使用回调来实现,但是(2)的问题又会导致回调不正确。
    
  5. 所以, 现在分析错误原因: 是因为调用关系, 或者别的位置原因 导致音频播放失败

测试现场1 解决方案
  1. 由于 代码中频繁的调用 cc.audioEngine.stopAll

  2. 这个错误 是 io 还挺快的鸿蒙机器上发现的

  3. 怀疑 stopAll 和 play 调用时间不确定。 stop 还未完成 直接调play 导致播放失败

  4. 顺着这个思路 尝试解决的方案 就是

    1. 切换场景 和 切换页面 调用 stopAll 之后 等待 0.1s 在初始化场景
    2. 0.1s 用户感知上 未见明显延迟
    

测试现场2

  1. 测试现场2 是 比较老的 鸿蒙pad 上发现的

    08-08 15:29:06.345   588   806 I APM_AudioPolicyManager: getNewOutputDevice() selected device 2 connectdeDevices(10002)
    08-08 15:29:06.346   588   806 D APM::AudioOutputDescriptor: stop, profile name: primary out,  curActiveCount: 0
    08-08 15:29:06.346 13482 14264 E libOpenSLES: frameworks/wilhelm/src/android/AudioPlayer_to_android.cpp:889: pthread_mutex_lock_timeout_np returned 110
    08-08 15:29:06.346   817   894 I dubaid  : [AudioHandler.cpp] stopSession# Failed to find audio session: 3753
    08-08 15:29:06.354  9599  9893 W ContentSensor_AudioInfoCapture: No need notify, resultList is empty
    08-08 15:29:06.354  9599  9893 W ContentSensor_AudioInfoCapture: insert info list is empty
    08-08 15:29:06.354  9599  9893 W ContentSensor_AudioInfoCapture: insert info list is empty
    08-08 15:29:06.372  2494  3160 D nStackXCoAP: ParseServiceDiscover:[416] :new device join
    08-08 15:29:06.372  2494  3160 E nStackXDFinder: DatabaseAllocRecord:[136] :DB max limit exceeded maxcnt:20, usecnt:20
    08-08 15:29:06.372  2494  3160 E nStackXDFinder: CreateNewDevice:[227] :Failed to allocate device info
    08-08 15:29:06.376 13482 14264 E libOpenSLES: frameworks/wilhelm/src/android/AudioPlayer_to_android.cpp:889: pthread_mutex_lock_timeout_np returned 110
    08-08 15:29:06.382  9599  9893 W ContentSensor_AudioInfoCapture: No need notify, resultList is empty
    08-08 15:29:06.382  9599  9893 W ContentSensor_AudioInfoCapture: insert info list is empty
    08-08 15:29:06.382  9599  9893 W ContentSensor_AudioInfoCapture: insert info list is empty
    08-08 15:29:06.384  9599  9893 W ContentSensor_AudioInfoCapture: No need notify, resultList is empty
    08-08 15:29:06.384  9599  9893 W ContentSensor_AudioInfoCapture: insert info list is empty
    08-08 15:29:06.384  9599  9893 W ContentSensor_AudioInfoCapture: insert info list is empty
    08-08 15:29:06.385  1589  1598 I system_server: Background concurrent copying GC freed 826201(24MB) AllocSpace objects, 3(60KB) LOS objects, 40% free, 34MB/58MB, paused 839us total 209.358ms
    08-08 15:29:06.386 13482 14263 D         : TrackPlayerBase::~TrackPlayerBase()
    08-08 15:29:06.386 13482 14263 D         : PlayerBase::~PlayerBase()
    08-08 15:29:06.387 13482 14263 D         : TrackPlayerBase::~TrackPlayerBase()
    08-08 15:29:06.387 13482 14263 D         : PlayerBase::~PlayerBase()
    08-08 15:29:06.399  9599  9893 W ContentSensor_AudioInfoCapture: No need notify, resultList is empty
    08-08 15:29:06.399  9599  9893 W ContentSensor_AudioInfoCapture: insert info list is empty
    08-08 15:29:06.399  9599  9893 W ContentSensor_AudioInfoCapture: insert info list is empty
    08-08 15:29:06.416 13482 14264 E libOpenSLES: frameworks/wilhelm/src/android/AudioPlayer_to_android.cpp:889: pthread_mutex_lock_timeout_np returned 110
    08-08 15:29:06.433  1589  1815 I HwFingersSnapshooter: handleMotionEvent first finger(0) touch down at (106.9443,115.90342)
    08-08 15:29:06.467 13482 14264 E libOpenSLES: frameworks/wilhelm/src/android/AudioPlayer_to_android.cpp:889: pthread_mutex_lock_timeout_np returned 110
    
  2. 表现为: 页面不能点击 动画不播放 , 连接V8 调试模式 连接失败

  3. 怀疑 V8 引擎崩溃 或者卡死

  4. 但是 查看上述 log 发现

    libOpenSLES: frameworks/wilhelm/src/android/AudioPlayer_to_android.cpp:889: pthread_mutex_lock_timeout_np returned 110
    
  5. 所以 最后怀疑: 音频线程死锁,把主线程 卡死

  6. 查找资料: https://developer.aliyun.com/article/580467

  7. 查找资料:https://forum.cocos.org/t/topic/115287 论坛中有人提到:卡死的问题我也遇到过,是短时间内停止、播放音效导致的,上层做下管理,避免这种情况的出现。

  8. 结合 复现机器, io 很慢,

  9. 所以 分析原因: 有可能是 因为io慢, 音频加载的时间变长, 刚播放 就调用 stop ,导致音频线程锁死

测试现场2 解决方案
  1. 由于 代码中频繁的调用 cc.audioEngine.stopAll

  2. 这个错误 是 io 非常慢的鸿蒙机器 发现的

  3. 音频加载的时间变长, 刚播放 就调用 stop ,导致音频线程锁死

  4. 顺着这个思路 尝试解决的方案 就是

    1. 调用 cc.audioEngine.play 之后 0.1s 之内 不允许stopAll
    2. 调用play之前 记录一下 当前时间戳
    3. 调用 stopAll之前 判断 是否 超过记录时间戳的 0.1s  如果不够的话 等待到0.1s 再stop
    记录的代码如下
    
        public static initFuncForAudioEngine(){
            let playFunc = cc.audioEngine.play
            cc.audioEngine.play = (clip: cc.AudioClip, loop: boolean, volume: number):number=>{
                AudioUtils._lastTimeSound = new Date().getTime()
                return playFunc.call(cc.audioEngine, clip, loop, volume)
            }
    
            let playEffectFunc = cc.audioEngine.playEffect
            cc.audioEngine.playEffect = (clip: cc.AudioClip, loop: boolean):number=>{
                AudioUtils._lastTimeSound = new Date().getTime()
                return playEffectFunc.call(cc.audioEngine, clip, loop)
            }
    
            let playMusicFunc = cc.audioEngine.playMusic
            cc.audioEngine.playMusic = (clip: cc.AudioClip, loop: boolean):number=>{
                AudioUtils._lastTimeMusic = new Date().getTime()
                return playMusicFunc.call(cc.audioEngine, clip, loop)
            }
        }
    
    

From 2023-04-11

随着 chatgpt的爆火 把错误日志丢给chatgpt试试

12-30 15:06:03.013   725  2075 I AF::TrackHandle: OpPlayAudio: track:184 usage:1 not muted
12-30 15:06:03.013   725  2075 E AudioFlinger: createTrack_l() initCheck failed -12; no control block?
12-30 15:06:03.015   997 20097 E IAudioFlinger: createTrack returned error -12
12-30 15:06:03.015   997 20097 E AudioTrack: createTrack_l(0): AudioFlinger could not create track, status: -12 output 0
12-30 15:06:03.015   997 20097 E AudioSink: Unable to create audio track
12-30 15:06:03.015   997 20097 D AudioTrack: gather(): no metrics gathered, track status=-12
12-30 15:06:03.015   997 20097 W NuPlayerRenderer: openAudioSink: non offloaded open failed status: -19
12-30 15:06:03.015   997 20097 W NuPlayerRenderer: onDrainAudioQueue(): audio sink is not ready
12-30 15:06:03.015   997 20098 E NuPlayerDecoder: Renderer reported 0xffffffed when changing audio output format
12-30 15:06:03.015   997 20095 E NuPlayer: received error(0xffffffed) from audio decoder, flushing(0), now shutting down
12-30 15:06:03.015   997 20099 I MediaCodec: kWhatFlush processing is complete
12-30 15:06:03.015  3204 20093 E libOpenSLES: Error after prepare: 1
12-30 15:06:03.015   997 20099 I CCodecBufferChannel: [c2.android.mp3.decoder#492] flush
12-30 15:06:03.015   997 20099 D CCodecBuffers: [c2.android.mp3.decoder#492:1D-Output.Impl[N]] Client returned a buffer it does not own according to our record: 0
12-30 15:06:03.016   997 20099 D CCodecBuffers: [c2.android.mp3.decoder#492:1D-Output.Impl[N]] Client returned a buffer it does not own according to our record: 1
12-30 15:06:03.016   997 20099 D CCodecBuffers: [c2.android.mp3.decoder#492:1D-Output.Impl[N]] Client returned a buffer it does not own according to our record: 2
12-30 15:06:03.016   997 20099 I MediaCodec: Start Processing kWhatFlushCompleted
12-30 15:06:03.017   997 20101 D BufferPoolAccessor: buffer invalidation added bp:125 1
12-30 15:06:03.018  2506  3226 I DeviceStateService: event is too short, not process app: com.zuoyebang.bangbangshizi mediacodec action.

得到的回答是

上述log显示的是Android设备在进行音频播放时出现的一系列错误信息。它们的含义如下:

I AF::TrackHandle: OpPlayAudio: track:184 usage:1 not muted 表示一个音频轨道正在被播放,且未被静音;
E AudioFlinger: createTrack_l() initCheck failed -12; no control block? 表示音频播放引擎(AudioFlinger)创建音频轨道失败,错误码为-12,没有找到控制块;
E IAudioFlinger: createTrack returned error -12 表示音频播放引擎创建音频轨道失败,错误码为-12;
E AudioTrack: createTrack_l(0): AudioFlinger could not create track, status: -12 output 0 表示创建音频轨道的操作失败,输出错误码为-12;
E AudioSink: Unable to create audio track 表示音频播放引擎无法创建音频轨道;
D AudioTrack: gather(): no metrics gathered, track status=-12 表示音频轨道创建失败导致采集不到度量数据;
W NuPlayerRenderer: openAudioSink: non offloaded open failed status: -19 表示音频播放器(NuPlayerRenderer)的开放音频输出(AudioSink)失败,错误码为-19;
W NuPlayerRenderer: onDrainAudioQueue(): audio sink is not ready 表示音频播放器无法正常采集音频数据,因为音频输出并未准备就绪;
E NuPlayerDecoder: Renderer reported 0xffffffed when changing audio output format 表示更改音频输出格式时音频解码器(NuPlayerDecoder)报告了错误;
E NuPlayer: received error(0xffffffed) from audio decoder, flushing(0), now shutting down 表示音频解码器收到了错误报告,并且准备关闭应用;
I MediaCodec: kWhatFlush processing is complete 表示音频解码器已经完成清除缓存的操作;
E libOpenSLES: Error after prepare: 1 表示OpenSLES库准备出现错误;
I CCodecBufferChannel: [c2.android.mp3.decoder#492] flush 表示解码器缓存通道将要被清空;
D CCodecBuffers: [c2.android.mp3.decoder#492:1D-Output.Impl[N]] Client returned a buffer it does not own according to our record: 0/1/2 表示解码器缓存通道收到了客户端返回不属于自己的缓存对象或偏移量的错误信息;
I MediaCodec: Start Processing kWhatFlushCompleted 表示解码器完成清除缓存的操作;
D BufferPoolAccessor: buffer invalidation added bp:125 1 表示缓冲池出现问题。
综上所述,这些错误可能是由设备的音频硬件或驱动程序发生问题、应用程序本身出现功能问题或权限不足、音频文件格式不正确等原因引起的。解决方法包括检查设备硬件,重新安装、更新应用程序,确保网络连接,等等。

这个分析就很明显了。结合我们自己的代码 准备先把audio的双声道 先压成单声道 试试 后续有进展 接着同步

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

cocos creater 鸿蒙 音频卡死 播放失败 不回调 的相关文章

  • 智慧城市篇

    智慧城市篇 数字孪生智慧排水管网管理平台https mp weixin qq com s ZDgmKqHRztYk2ehBDbi3AA 2022年3月1日 住房和城乡建设部印发了 十四五 住房和城乡建设科技发展规划 提出关于实现城市基础设施
  • Mybatis中的resultType和resultMap

    一 概述 MyBatis中在查询进行select映射的时候 返回类型可以用resultType 也可以用resultMap resultType是直接表示返回类型的 而resultMap则是对外部ResultMap的引用 但是resultT
  • android组件悬浮,Andorid 任意界面悬浮窗,实现悬浮窗如此简单

    特性 1 支持拖动 提供自动贴边等动画 2 内部自动进行权限申请操作 3 可自由指定要显示悬浮窗的界面 4 应用退到后台时 悬浮窗会自动隐藏 5 位置不可变的悬浮窗无需权限申请 6 位置及宽高可设置百分比值 轻松适配各分辨率 7 链式调用
  • [Python / PyTorch] debug backward()

    问题描述 在自定义Loss的中 其backward 函数不支持在PyCharm中进行断点调试 因此需要以其他方式进行断点调试 解决方案 参考 Is there a way to debug the backward method of Fu
  • SQLI-Labs(3)8-14关【布尔盲注和时间盲注】

    目录 第八关 第九关 第十关 第十一关 第十二关 第十三关 第十四关 第八关 我们用测试语句来测试是否为注入点 从上图中得知存在注入点 那么接下来就是爆列 一共有三列 接下来用union select 和报错注入都试一下发现没有回显点 那么

随机推荐

  • thinkPHP使用PHPExcel实现导入导出

    目录 一 使用composer安装PHPExcel 二 使用PHPExcel 1 导入Excel文件 2 导出数据 3 导出方法使用demo 效果图 一 使用composer安装PHPExcel 安装命令 composer require
  • 常见的PLC通讯协议有哪些?

    PLC 可编程逻辑控制器 通讯方式有多种 以下是一些常见的通讯方式 串口通信 使用串行接口 如RS232 RS485等 进行通信 常用于与外部设备进行简单的数据传输 以太网通信 通过以太网接口进行通信 可以实现较高的数据传输速率和远程连接
  • 键值数据库PebblesDB读后感

    键值数据库PebblesDB读后感 在LevelDB RocksDB这种分层思路上 PebblesDB提出了一种减少写放大的思路 下面学习并总结 所述以论文为基础 也有个人 观点 客观论述请看原文 虽然LSM的写放大最近被研究很多 但是就写
  • 关于log4j

    log4j 在强调可重用组件开发的今天 除了自己从头到尾开发一个可重用的日志操作类外 Apache为我们提供了一个强有力的日志操作包 Log4j 官方站点 http logging apache org log4j Log4j是Apache
  • linux拒绝更改密码,【Linux】解决SSH服务拒绝密码

    xShell连接Linux服务器提示密码错误 1 检查虚拟机SSH服务是否开启 service sshd status 如果没有开启 请执行service sshd start启动该服务 或者通过service sshd restart重启
  • web3.0 nft 是什么? nft的意义是什么?

    英国一名12岁的男孩本雅明 他在暑假期间画了一系列的画作 并在网上以数字藏品的形式进行出售 不到9小时就全部售完 赚取的虚拟货币价值相当于250万人民币 这些画算不上很高端的艺术佳作 而是由密密麻麻的像素组成各种形状各异的鲸鱼 每条鲸鱼都有
  • Vulhub漏洞靶场搭建和使用

    今天继续给大家介绍渗透测试相关知识 本文主要内容是Vulhub漏洞靶场搭建和使用 免责声明 本文所介绍的内容仅做学习交流使用 严禁利用文中技术进行非法行为 否则造成一切严重后果自负 再次强调 严禁对未授权设备进行渗透测试 一 Vulhub漏
  • 视频播放器测试点

    视频播放器测试点 在负责XX项目组的测试中 接触了好多的关于播放器的测试 基于这些 再结合我测试过程中遇到的问题整理的测试点分别从以下几个方面进行 功能测试 视频资源可以正常获取 不管是服务器返回还是后台添加等 视频的封面图 页面UI等正常
  • 【转载】关于在keil5的time environment没有StdPeriph Drivers(标准库)但是又想使用库函数的解决办法

    关于在keil5的time environment没有StdPeriph Drivers 标准库 但是又想使用库函数的解决办法 本人刚刚接触keil5 遇到了一些问题 希望我的方法能帮到大家 作者本人使用的是芯片是stm32f407VET6
  • SpringBoot配置动态定时任务

    1 配置ScheduledTask 主要是实现SchedulingConfigurer 动态传入cron package com hzl boot config import lombok Data import org springfra
  • Spring Cloud OAuth2(一) 搭建授权服务

    本文内容主要为spring cloud 授权服务的搭建 采用jwt认证 GitHub 地址 https github com fp2952 spring cloud base tree master auth center auth cen
  • [USACO13DEC]Optimal Milking G【线段树维护最大独立集】

    题目链接 P3097 USACO13DEC Optimal Milking G 很明显的是这道题有4e4个点 直接跑最大独立集的话 那么测评机承受不起啊 所以 这里要维护一个区间dp的形式 每个区间有左右两个端点 我们现在要合并两个区间的话
  • HTTP缓存

    HTTP缓存 什么是HTTP缓存 http缓存指的是 当客户端向服务器请求资源时 会先抵达浏览器缓存 如果浏览器有 要请求资源 的副本 就可以直接从浏览器缓存中提取而不是从原始服务器中提取这个资源 常见的http缓存只能缓存get请求响应的
  • Java中的作用域

    目录 Java作用域 Java中变量类型主要有3种 成员变量 静态变量和局部变量 成员变量或方法也有4种作用域 静态修饰符的特点 静态使用的注意事项 静态的优缺点 当成员变量被静态修饰后 和非静态成员变量的区别 方法作用域 块作用域 基本使
  • 单词搜索--回溯算法

    LeetCode 单词搜索 给定一个二维网格 board 和一个字典中的单词列表 words 找出所有同时在二维网格和字典中出现的单词 单词必须按照字母顺序 通过相邻的单元格内的字母构成 其中 相邻 单元格是那些水平相邻或垂直相邻的单元格
  • UIView的setNeedsLayout, layoutIfNeeded 和 layoutSubviews 方法之间的关系解释

    layoutSubviews总结 ios layout机制相关方法 CGSize sizeThatFits CGSize size void sizeToFit void layoutSubviews void layoutIfNeeded
  • 《软件工程教程》(第2版) 主编:吴迪 马宏茹 丁万宁 第十二章课后习题参考答案

    第十二章 软件项目管理 课后习题参考答案 一 简答题 1 项目管理的定义是什么 简述软件项目管理的过程 答 项目管理的定义 项目管理是以项目为对象 通过使用知识 技能 工具和方法来组织 计划 实施并监控项目 使之满足项目目标需求的过程 一般
  • ipad扩展为Windows的第二屏幕【免费无线版】

    本文参考 Ipad扩展为Windows的第二屏幕 有时候想用ipad作为Windows电脑的第二屏幕 那么我们可以通过spacedesk软件进行无线扩展 1 在电脑和ipad上分别下载spacedesk软件 电脑端 ipad 打开ipad
  • npm ERR! tar.unpack untar error

    今天在使用nam install命令安装第三方node模块时 老是出现这样的问题 npm ERR tar unpack untar error tmp npm 5884 e9fda1ac registry npmjs org npm npm
  • cocos creater 鸿蒙 音频卡死 播放失败 不回调

    cocos creater音频播放失败 不回调 卡死 鸿蒙 问题背景 开发过程中 未发现问题 线上 部分鸿蒙用户反馈 页面卡死没反应 页面不能继续下一步 so 问题有可能是 音频没播出来 或者回调没回来 或者 获取音频的时长错误 测试现场1