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,一经查实,立即删除!

相关文章

基于python实现的监听服务接口是否正常,发送异常消息到钉钉群

获取钉钉机器人 创建钉钉群组(要求至少三个成员)进入群组 设置>机器人>添加机器人选择自定义机器人 按照要求填写完获取到 Webhook的链接 实现代码 from time import sleep import requests import json from datetime import datetime import logging# 配置日志记录的…

数据结构第11节: B树

B树是一种自平衡的树数据结构&#xff0c;它能够保持数据排序&#xff0c;并且在插入、删除和查找操作中具有对数时间复杂度。B树广泛应用于文件系统、数据库和索引中&#xff0c;因为它们可以有效地处理大量数据。 B树的特点&#xff1a; 所有叶子节点都位于同一层。每个节点…

【】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使用以及常见的坑…

PCL 点云PFH特征描述子

点云PFH特征描述子 一、概述1.1 概念1.2 算法原理一、代码实现二、结果示例一、概述 1.1 概念 点特征直方图PFH(Point Feature Histograms)描述子:用于表示点云中每个点的局部几何形状信息,它是一种直方图描述子,包括了点云的法线方向和曲率信息,PFH描述子可以帮助区分不同…

深入Django(八)

掌握Django的管理后台 引言 在前七天的教程中&#xff0c;我们介绍了Django的基础架构、模型、视图、模板、URL路由、表单系统以及数据库迁移。今天&#xff0c;我们将深入了解Django的管理后台&#xff0c;这是一个功能强大的内置管理界面&#xff0c;用于创建、更新、查看和…

【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 使用演示&…

QT面试笔记总计

一 Qt 保证多线程安全? 使互斥锁保证多线程安全性。QMutex类、。使用读写锁保证多线程安全性&#xff0c;QReadWriteLock。使用信号和槽机制保证多线程安全性。使用显示切换保证多线程安全性。QTread类。 Qt 中的事件与信号的区别? 事件与信号的实现机制不同&#xff1b;事…

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. 什么是网络协议 网络协议是计算机网络中用于数据交换的规则和标准。这些规则规定了数据格式、时序以及发送和接收数据时的动作。网络协…

Unity3D瓦片地图辅助定位工具

介绍 该工具用于TileMap的瓦片辅助定位&#xff0c;通过键盘或鼠标按瓦片尺寸0到1的比例作为单次移动值移动定位点游戏对象。当采用定位点游戏对象映射瓦片时&#xff0c;可使用该工具来移动定位点游戏对象&#xff0c;在新版本Unity3D的TileMap编辑器中可使用GameObject Brush…

基于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;在下次…

实现基于Spring Security的权限管理系统

实现基于Spring Security的权限管理系统 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在现代Web应用中&#xff0c;权限管理系统是至关重要的组成部分。通过…

[数据集][目标检测]护目镜检测数据集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…

FreeRTOS中vTaskDelay 和 xTaskDelayUntil 的区别?

vTaskDelay 和 xTaskDelayUntil 是 FreeRTOS 提供的两种不同任务延迟函数&#xff0c;各自有其适用的场景和优缺点。vTaskDelay 适用于简单的延迟操作&#xff0c;而 xTaskDelayUntil 提供了精确的周期控制能力。在设计 FreeRTOS 应用程序时&#xff0c;根据任务的时间要求选择…

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

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