最近在使用ESP32-S3开发SD卡播放本地歌曲,使用官方组件espressif/esp_audio_simple_player,但是无法获取文件播放时长,在网上也没有找到简单、准确的偷懒方法,自己也没时间去摸索底层原理,这里使用tinymp3库提供一个简单的参考做法。
1、WAV
创建一个main_wav.c,拷贝下面代码。
/*main_wav.c*/
#define DR_WAV_IMPLEMENTATION
#define DR_WAV_NO_CONVERSION_API /* 去掉所有 drwav_read_*_s16/f32/s32 */
#define DR_WAV_NO_STDIO /* 去掉 drwav_init_file/write 等 */
#include "dr_wav.h"
#include <stdio.h>
#include <stdlib.h>
static size_t file_read(void *ud, void *buf, size_t len)
{
return fread(buf, 1, len, (FILE*)ud);
}
static drwav_bool32 file_seek(void *ud, int offset, drwav_seek_origin origin)
{
return fseek((FILE*)ud, offset, origin==drwav_seek_origin_start?SEEK_SET:SEEK_CUR)==0;
}
int main(int argc, char *argv[])
{
if(argc!=2){ fprintf(stderr,"usage: %s file.wav\n",argv[0]); return 1; }
FILE *fp = fopen(argv[1],"rb");
if(!fp){ perror("fopen"); return 1; }
drwav wav;
if(!drwav_init(&wav, file_read, file_seek, fp, NULL)){ fclose(fp); return 1; }
double dur = (double)wav.totalPCMFrameCount / wav.sampleRate;
printf("%.3f\n", dur); /* 只打印秒数 */
drwav_uninit(&wav);
fclose(fp);
return 0;
}
把库文件dr_wav.h放到同级别目录下,编译运行,即可得到wav文件总时长。

2、mp3
同wav操作。
/*main_mp3*/
#define DR_MP3_IMPLEMENTATION
#define DR_MP3_NO_SIMD /* 不要 SSE/Neon 加速(省体积) */
#define DR_MP3_ONLY_MP3 /* 只支持 MP3,去掉 Layer1/2 代码 */
#include "dr_mp3.h"
#include <stdio.h>
int main(int argc, char **argv)
{
if (argc != 2) return 1;
drmp3 mp3;
if (!drmp3_init_file(&mp3, argv[1], NULL)) /* 内部仍用 fopen */
return printf("invalid mp3\n"), 1;
drmp3_uint64 frames = drmp3_get_pcm_frame_count(&mp3);
double sec = (double)frames / mp3.sampleRate;
printf("%.3f\n", sec);
drmp3_uninit(&mp3);
return 0;
}

509

被折叠的 条评论
为什么被折叠?



