Open wojiaoyishang opened 1 year ago
描述BUG audio模块释放播放器时写入不允许访问的内存地址报错重启。详情: 当调用 audio.play("local.mp3") 播放本地音乐时,会阻塞代码运行,直到音乐播放结束,通过 audio.player_deinit() 释放播放器并未捕获异常。但是,如果采用阻塞的方式播放本地文件,audio模块中提供的暂停、继续播放函数将会没有意义。、 奇怪的是。当调用 audio.play("http://xxx.mp3") 播放在线音乐时,并不会阻塞代码运行,通过 audio.player_deinit() 释放播放器会造成写入不允许访问的内存地址报错重启。
audio.play("local.mp3")
audio.player_deinit()
audio.play("http://xxx.mp3")
复现BUG 通过一下步骤:
import time import audio from mpython import * wifi().connectWiFi("ssid", "password", timeout=10) audio.player_init() audio.play('http://wiki.labplus.cn/images/4/4e/Music_test.mp3') # 播放在线音乐,不阻塞代码 time.sleep(3) # 等待音乐播放起来 audio.player_deinit() # 是否音乐
同时,在播放在线文件的时候也会出现堆栈溢出的情况,如调用下面的音频文件:
audio.player_init() audio.play('https://gitee.com/wojiaoyishang/TaoLiSystem-doc/releases/download/v114514/ctr1.mp3') audio.stop() audio.player_deinit()
附加说明
Q: 有没有可能是没有使用 audio.stop() 再 audio.player_deinit() 造成的报错?
audio.stop()
A: 不存在这种情况,即使使用 audio.stop() 也会报错,查看源码 mpython/port/drivers/codec/audio_player.c ,发现如下:
mpython/port/drivers/codec/audio_player.c
void player_deinit(void) { EventBits_t uxBits; if(player_instance){ if((player_instance->player_status == RUNNING) || (player_instance->player_status == PAUSED)) { player_stop(); // 即使处于播放状态仍然会先停止 } // something...... }
Q: 错误的原因是什么?
A: 原因是试图将一段数据试图写入一段不允许访问的内存中去,而写入内存的操作由 HTTP请求 完成,所以猜测是在释放 player 之后,并未停止 HTTP请求 。也就是没有停止代码中的 http_client_task 。
HTTP请求
http_client_task
Q: 其它想说的。
A: 代码中的函数 player_play 有一段如下:
player_play
local_play(player_instance); // xTaskCreate(local_play_task, "local_play_task", 8192, player_instance, ESP_TASK_PRIO_MIN + 1, NULL ); // ESP_LOGE(TAG, "4. Create local file read task, RAM left: %d", esp_get_free_heap_size());
xTaskCreate 函数执行被注释了,转而执行 local_play 函数,估计是当时官方发现发现本地播放的问题进行的临时补救。O(∩_∩)O
xTaskCreate
local_play
修改建议
代码停止音乐播放的逻辑是:先将引脚输出“禁用”,然后将文件播放到文件尾。这种方式对于长的音乐文件不太友好,建议直接将所有任务终止。
描述BUG audio模块释放播放器时写入不允许访问的内存地址报错重启。详情: 当调用
audio.play("local.mp3")
播放本地音乐时,会阻塞代码运行,直到音乐播放结束,通过audio.player_deinit()
释放播放器并未捕获异常。但是,如果采用阻塞的方式播放本地文件,audio模块中提供的暂停、继续播放函数将会没有意义。、 奇怪的是。当调用audio.play("http://xxx.mp3")
播放在线音乐时,并不会阻塞代码运行,通过audio.player_deinit()
释放播放器会造成写入不允许访问的内存地址报错重启。复现BUG 通过一下步骤:
audio.player_deinit()
释放播放器便会出现报错,代码如下:同时,在播放在线文件的时候也会出现堆栈溢出的情况,如调用下面的音频文件:
附加说明
Q: 有没有可能是没有使用
audio.stop()
再audio.player_deinit()
造成的报错?A: 不存在这种情况,即使使用
audio.stop()
也会报错,查看源码mpython/port/drivers/codec/audio_player.c
,发现如下:Q: 错误的原因是什么?
A: 原因是试图将一段数据试图写入一段不允许访问的内存中去,而写入内存的操作由
HTTP请求
完成,所以猜测是在释放 player 之后,并未停止HTTP请求
。也就是没有停止代码中的http_client_task
。Q: 其它想说的。
A: 代码中的函数
player_play
有一段如下:xTaskCreate
函数执行被注释了,转而执行local_play
函数,估计是当时官方发现发现本地播放的问题进行的临时补救。O(∩_∩)O修改建议
代码停止音乐播放的逻辑是:先将引脚输出“禁用”,然后将文件播放到文件尾。这种方式对于长的音乐文件不太友好,建议直接将所有任务终止。