Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

audio模块释放播放器时写入不允许访问的内存地址报错重启 #30

Open
wojiaoyishang opened this issue Aug 8, 2023 · 0 comments

Comments

@wojiaoyishang
Copy link

描述BUG
audio模块释放播放器时写入不允许访问的内存地址报错重启。详情:
当调用 audio.play("local.mp3") 播放本地音乐时,会阻塞代码运行,直到音乐播放结束,通过 audio.player_deinit() 释放播放器并未捕获异常。但是,如果采用阻塞的方式播放本地文件,audio模块中提供的暂停、继续播放函数将会没有意义。
奇怪的是。当调用 audio.play("http://xxx.mp3") 播放在线音乐时,并不会阻塞代码运行,通过 audio.player_deinit() 释放播放器会造成写入不允许访问的内存地址报错重启。

复现BUG
通过一下步骤:

  1. 连接 WIFI
  2. 导入 audio 模块并播放在线音乐,并等待音乐播放到中途某一个阶段
  3. 使用 audio.player_deinit() 释放播放器便会出现报错,代码如下:
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() 造成的报错?

A: 不存在这种情况,即使使用 audio.stop() 也会报错,查看源码 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

Q: 其它想说的。

A: 代码中的函数 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

修改建议

代码停止音乐播放的逻辑是:先将引脚输出“禁用”,然后将文件播放到文件尾。这种方式对于长的音乐文件不太友好,建议直接将所有任务终止。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant