可显示SD卡中mp3文件的播放器

本程序不能在ESP32芯片上很好地运行,经过仔细地排查,问题在于ESP32的运行内存太小( SRAM 有 520KB,但是系统启动后可用内存约为 300KB),导致处理音频文件时,定义的全局变量musicList被覆盖(向屏幕打印显示乱码了)

显示歌曲列表,可切换和暂停

复制代码
#include <M5Stack.h>
#include "FS.h"
#include "AudioFileSourceSD.h"
#include "AudioFileSourceID3.h"
#include "AudioGeneratorMP3.h"
#include "AudioOutputI2S.h"
AudioGeneratorMP3 *mp3;
AudioFileSourceSD *file;
AudioOutputI2S *out;
AudioFileSourceID3 *id3;

bool myplay = false;
int i=0;
int current_i = -1;
char* musicList[4];

void listFile(fs::FS &fs, const char * dirname){
    File root = fs.open(dirname);
    if(!root){
        M5.Lcd.print("Failed to open directory");
        return;
    }
    if(!root.isDirectory()){
        M5.Lcd.print("Not a directory");
        return;
    }
    File file = root.openNextFile();
    while(file){
        if(!file.isDirectory()){
           musicList[i] = (char*)file.name();
           i++;
           //M5.Lcd.println(file.name());
        } 
        file = root.openNextFile();
    }
}
void setup(){
  M5.begin();
  M5.Lcd.setTextSize(2);
  listFile(SD,"/");
  M5.Lcd.setTextWrap(false,false);
  for(i=0;i<3;i++){
   M5.Lcd.setCursor(0,15*i);
   M5.Lcd.print(musicList[i]);
  }
  M5.Lcd.fillRect(300,4,10,10,RED);
  i = 0;
  M5.Lcd.setCursor(0,220);
}
void loop(){
  M5.update();
  if (myplay&&mp3&&mp3->isRunning()) {
    if (!mp3->loop()) mp3->stop();
  }
  if(M5.BtnB.wasPressed()){//切换至下一曲
    M5.Lcd.fillRect(300,4+15*i,10,10,BLACK);
    i = (++i)%3;
    if(i == current_i){
      if(myplay){
        M5.Lcd.fillRect(300,4+15*i,10,10,GREEN);
      }else{
        M5.Lcd.fillRect(300,4+15*i,10,10,YELLOW);
      }
    }else{
      M5.Lcd.fillRect(300,4+15*i,10,10,RED);
    }
  }
  if(M5.BtnC.wasPressed()){
     if(current_i == i){
      if(myplay){
        myplay = myplay^true;//暂停播放
        out->flush();
        M5.Lcd.fillRect(300,4+15*(i),10,10,YELLOW);
      }else{
        if(mp3&&mp3->isRunning()){//恢复播放
          myplay = myplay^true;
          M5.Lcd.fillRect(300,4+15*(i%3),10,10,GREEN);
        }
      }
     }
     else{
      M5.Lcd.drawNumber(i,0,200);
      myplay = true;
      if(mp3&&mp3->isRunning()){
        mp3->stop();
      }
      M5.Lcd.drawString(musicList[i],0,220,1);
      file = new AudioFileSourceSD(musicList[i]);
      id3 = new AudioFileSourceID3(file);
      out = new AudioOutputI2S(0, 1); // Output to builtInDAC
      out->SetOutputModeMono(true);
      mp3 = new AudioGeneratorMP3();
      mp3->begin(id3, out);
      M5.Lcd.fillRect(300,4+15*i,10,10,GREEN);
      current_i = i;
     }
  }
}
复制代码

1.仅仅播放了一首歌,第二首歌的相关对象还没new出来,musicList已经被覆盖了

2.或许可以把flash memory扩展成内存;或者少定义变量,存储一些中间文件到json中

3.尽快实现通信,远程控制

4.还可以修改Audio库文件的函数,使缓冲分配的内存少一点,但是现阶段只是学习,没有必要花过多时间改,了解到这一深度已经足够了。

 

posted @   许培风  阅读(400)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示