ESP32 通过蓝牙显示歌词代码示例

通过蓝牙协议播放音乐,有的时候需要显示歌词,这里就是a2dp库获取了歌词

值得注意的是要想正确获取到歌词,必须打开各种播放器的字幕(歌词)开关

本项目用了三个开源库 a2dp,tft_espi,xfont.

a2dp :蓝牙传输音频资料和字幕信息

tft_espi : tft 屏幕驱动

xfont : 显示汉字 ,详细使用请参考 GitHub - StarCompute/tftziku: 这是一个通过单片机在各种屏幕上显示中文的解决方案

注意,xfont的初始化必须先执行。

项目内的代码通过网易云音乐 播放正常获取到歌词。

 

项目整体开源到了: https://github.com/StarCompute/bluemusic

 

#include <Arduino.h>
// #include "AudioTools.h"
#include "a2dp/BluetoothA2DPSink.h"
#include "xfont.h"// #define TFT_SCLK   22
// #define TFT_MOSI  21
// #define TFT_RST     25
// #define TFT_DC      14
// #define TFT_CS   	 15XFont *_xFont;
BluetoothA2DPSink a2dp_sink;
// Then somewhere in your sketch:
void read_data_stream(const uint8_t *data, uint32_t length)
{i2s_write(I2S_NUM_0,data,length,NULL,0);
}
void rssi(esp_bt_gap_cb_param_t::read_rssi_delta_param &rssiParam)
{Serial.print("rssi value: ");Serial.println(rssiParam.rssi_delta);
}String song_singer = "";
String song_album = "";
float totalSongTime=1.0;// 显示播放的百分比,其实可以优化的更好
void avrc_rn_play_pos_callback(uint32_t play_pos) {Serial.printf("Play position is %d (%d seconds)\n", play_pos, (int)round(play_pos/1000.0));if(totalSongTime>0){float per=play_pos/totalSongTime*100;_xFont->tft.fillRect(0, 102, 400, 40, TFT_BLACK);_xFont->DrawChineseEx(0, 102, "" + String(per,2)+"%", TFT_SILVER,TFT_BLACK);}
}void avrc_metadata_callback(uint8_t data1, const uint8_t *data2)
{// Serial.printf("AVRC metadata rsp: attribute id 0x%x, %s\n", data1, data2);String strData2 = (const char *)data2;if(strData2!="0")Serial.printf("data1: %d data2: %s \n",data1,strData2);if (data1 == 2){// Serial.printf("歌名:%s", data2);if (song_singer != strData2){_xFont->tft.fillRect(0, 2, 400, 40, TFT_BLACK);_xFont->DrawChineseEx(0, 2, "" + strData2,TFT_GREEN,TFT_BLACK);song_singer = strData2;}}if (data1 == 4){// Serial.printf("歌手:%s", data2);if (song_album != strData2){_xFont->tft.fillRect(0, 46, 400, 40, TFT_BLACK);_xFont->DrawChineseEx(0, 46, "" + strData2, TFT_RED,TFT_BLACK);song_album = strData2;}}if (data1 == 1){// Serial.printf("专辑:%s", data2);_xFont->tft.fillRect(0, 71, 400, 30, TFT_BLACK);_xFont->DrawChineseEx(0, 71, "" + strData2, TFT_LIGHTGREY,TFT_BLACK);}if(data1==64)totalSongTime=strData2.toFloat();// 0x8 第几首歌// 0x10 总共多少首歌// 0x20
}void connection_state_changed(esp_a2d_connection_state_t state, void *ptr)
{Serial.println(a2dp_sink.to_str(state));
}void audio_state_changed(esp_a2d_audio_state_t state, void *ptr)
{Serial.println(a2dp_sink.to_str(state));
}void setup()
{Serial.begin(115200);_xFont = new XFont(true);_xFont->DrawChineseEx(0, 2, "欢迎使用。。", TFT_GREEN);a2dp_sink.set_avrc_metadata_attribute_mask(ESP_AVRC_MD_ATTR_TITLE | ESP_AVRC_MD_ATTR_ARTIST | ESP_AVRC_MD_ATTR_ALBUM | ESP_AVRC_MD_ATTR_TRACK_NUM | ESP_AVRC_MD_ATTR_NUM_TRACKS|ESP_AVRC_MD_ATTR_PLAYING_TIME|ESP_AVRC_MD_ATTR_GENRE);// a2dp_sink.a2dp_sink.set_avrc_metadata_callback(avrc_metadata_callback);a2dp_sink.set_on_connection_state_changed(connection_state_changed);a2dp_sink.set_on_audio_state_changed(audio_state_changed);a2dp_sink.set_avrc_rn_play_pos_callback(avrc_rn_play_pos_callback);i2s_pin_config_t my_pin_config = {.bck_io_num = 32,//输入.ws_io_num = 33,//输入.data_out_num = 23,//输出.data_in_num = I2S_PIN_NO_CHANGE};a2dp_sink.set_pin_config(my_pin_config);a2dp_sink.start("my music");}void loop()
{delay(100);
}

 由于歌词内容不确定,所以使用了开源中文字库 :

GitHub - StarCompute/tftziku: 这是一个通过单片机在各种屏幕上显示中文的解决方案

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/41733.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【】AI八股-神经网络相关

Deep-Learning-Interview-Book/docs/深度学习.md at master amusi/Deep-Learning-Interview-Book GitHub 网上相关总结&#xff1a; 小菜鸡写一写基础深度学习的问题&#xff08;复制大佬的&#xff0c;自己复习用&#xff09; - 知乎 (zhihu.com) CV面试问题准备持续更新贴 …

.net 调用海康SDK的跨平台解决方案

📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!📢本文作者:由webmote 原创📢作者格言:新的征程,我们面对的不仅仅是技术还有人心,人心不可测,海水不可量,唯有技术,才是深沉黑夜中的一座闪烁的灯塔序言 上2篇海康SDK使用以及常见的坑…

【JavaEE精炼宝库】文件操作(1)——基本知识 | 操作文件——打开实用性编程的大门

目录 一、文件的基本知识1.1 文件的基本概念&#xff1a;1.2 树型结构组织和目录&#xff1a;1.3 文件路径&#xff08;Path&#xff09;&#xff1a;1.4 二进制文件 VS 文本文件&#xff1a;1.5 其它&#xff1a; 二、Java 操作文件2.1 方法说明&#xff1a;2.2 使用演示&…

HCIA综合实验

学习新思想&#xff0c;争做新青年。今天学习的是HCIA综合实验&#xff01; 实验拓扑 实验需求 总部&#xff1a; 1、除了SW8 SW9是三层交换机&#xff0c;其他交换机均为2层交换机。 2、GW为总部的出口设备&#xff0c;使用单臂路由技术&#xff0c;VLAN10,20,100的网关都在GW…

ERROR: “armeabi-v7a“ not supported for HarmonyOS

IDE 从 devecostudio-mac-4.1.3.700 升级至 devecostudio-mac-5.0.3.403 后抛出了如下异常: ERROR: "armeabi-v7a" not supported for HarmonyOS. 解决办法 一.entry/build-profile.json5 需 entry/build-profile.json5 的 abiFilters 中移除 "armeabi-v7a&qu…

计算机网络体系结构详解:协议与分层

在学习计算机网络时&#xff0c;理解网络协议与分层体系结构是至关重要的。本文将详细介绍这些概念&#xff0c;帮助基础小白快速入门。 1. 什么是网络协议 网络协议是计算机网络中用于数据交换的规则和标准。这些规则规定了数据格式、时序以及发送和接收数据时的动作。网络协…

基于java+springboot+vue实现的流浪动物管理系统(文末源码+Lw)277

摘 要 在如今社会上&#xff0c;关于信息上面的处理&#xff0c;没有任何一个企业或者个人会忽视&#xff0c;如何让信息急速传递&#xff0c;并且归档储存查询&#xff0c;采用之前的纸张记录模式已经不符合当前使用要求了。所以&#xff0c;对流浪动物信息管理的提升&…

【React】React18 Hooks之useState

目录 useState案例1&#xff08;直接修改状态&#xff09;案例2&#xff08;函数式更新&#xff09;案例3&#xff08;受控表单绑定&#xff09;注意事项1&#xff1a;set函数不会改变正在运行的代码的状态注意事项2&#xff1a;set函数自动批量处理注意事项3&#xff1a;在下次…

[数据集][目标检测]护目镜检测数据集VOC+YOLO格式888张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;888 标注数量(xml文件个数)&#xff1a;888 标注数量(txt文件个数)&#xff1a;888 标注类别…

ORB 特征点提取

FAST关键点 选取像素p&#xff0c;假设它的亮度为Ip&#xff1b; . 设置一个阈值T&#xff08;比如Ip的20%&#xff09;&#xff1b; 以像素p为中心&#xff0c;选取半径为3的圆上的16个像素点&#xff1b; 假如选取的圆上&#xff0c;有连续的N个点的亮度大于IpT或小于…

Redis 八股文

标题 1. Redis主从同步原理&#xff1a;判断下线的条件:故障转移如何保证Sentinel高可用 1. Redis主从同步原理&#xff1a; 1、slave执行命令向master建立连接 2、master执行bgsave&#xff08;后台存储&#xff09;&#xff0c;生成rdb快照&#xff08;redis备份方式&#x…

日志自动分析-Web---360星图GoaccessALBAnolog

目录 1、Web-360星图(IIS/Apache/Nginx) 2、Web-GoAccess &#xff08;任何自定义日志格式字符串&#xff09; 源码及使用手册 安装goaccess 使用 输出 3-Web-自写脚本&#xff08;任何自定义日志格式字符串&#xff09; 4、Web-机器语言analog&#xff08;任何自定义日…

游戏AI的创造思路-技术基础-强化学习(1)

我们“强化”一下机器的“学习”&#xff0c;让机器变得更强~~~~ 目录 1. 强化学习的定义 2. 发展历史 3. 强化学习的基本概念和函数 3.1. 基本概念和函数 3.1.1. 基本概念和函数 3.1.2. Q函数 3.1.2.1. 定义与作用 3.1.2.2. 数学表示 3.1.2.3. 更新规则 3.1.2.4. 算…

AI时代算法面试:揭秘高频算法问题与解答策略

三种决策树算法的特点和区别 ID3算法&#xff1a;基本的决策树算法&#xff0c;适用于简单的分类问题C4.5算法&#xff1a;改进了ID3算法&#xff0c;适用于更复杂的分类问题&#xff0c;可以处理连续型数据和缺失值CART算法&#xff1a;更加通用的决策树算法&#xff0c;适用于…

云服务器在 Web 应用程序中作用

云服务器在Web应用程序中扮演着至关重要的角色&#xff0c;它不仅是现代Web应用程序的基石&#xff0c;还是推动业务发展和提升用户体验的关键技术之一。下面将详细探讨云服务器在Web应用程序中的重要作用及其优势。 首先&#xff0c;云服务器为Web应用程序提供了高度可扩展的…

【postgresql】索引

见的索引类型&#xff1a; B-tree 索引&#xff1a;这是最常用的索引类型&#xff0c;适用于大多数查询。B-tree索引可以高效地处理范围查询。 Hash 索引&#xff1a;适用于等值查询&#xff0c;但不支持范围查询。 GiST 索引&#xff1a;通用搜索树&#xff08;GiST&#xf…

怀念旧的Windows声音?以下是如何在Windows 11中恢复它们

如果你渴望旧的Windows声音,希望能在Windows 11上再次听到,那你就很幸运了。我们将向你展示如何下载必要的声音包并创建复古的声音方案。 如何获取旧Windows声音的声音包 你需要做的第一件事是下载一个包含旧Windows版本声音的声音包。此外,请确保它包含的每个声音都是WAV…

在 Vue 项目中使用 FullCalendar

1、先安装依赖包&#xff0c;根据自己的需求安装&#xff0c;建议使用cnpm安装&#xff0c;不然会很慢有时候会出现安装不上的情况。 npm i fullcalendar/vue --save npm i fullcalendar/core --save // 在月视图或日视图中操作事件 npm i fullcalendar/daygrid --save // 在…

记录discuz修改用户的主题出售价格

大家好&#xff0c;我是网创有方的站长&#xff0c;今天遇到了需要修改discuz的主题出售价格。特此记录下 方法很简单&#xff1a; 进入用于组-》选择论坛-》批量修改

【shell编程小项目】

目录 一、项目拓扑二、要求三、shell编程 一、项目拓扑 二、要求 环境准备&#xff1a; 准备两个虚拟机&#xff0c;按照环境配置好对应的 IP 地址和对应的主机名和 SSH 密钥登录在 workstation.exam.com 节点实现如下需求&#xff1a; 1、编写 Shell 脚本&#xff0c;要求代码…