espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.67k stars 7.29k forks source link

Implementing cover_art on a canvas through esp_avrc_api.h (IDFGH-9643) #10988

Closed leonardokucarz closed 1 month ago

leonardokucarz commented 1 year ago

Is your feature request related to a problem?

Good morning everything is fine? My name is Leonardo Kucarz, I'm developing a Bluetooth receiver with ESP32 to listen to music. Together with the ESP32 I have a screen on which I have managed to bring information such as the name of the song and the artist, I have also managed to place some buttons to control the music but my main objective is to be able to show the album image on the screen and I know that it exists the possibility from the commands:

esp_avrc_api.h ESP_AVRC_FEAT_FLAG_COVER_ART_GET_IMAGE_PROP = 0x0080, ESP_AVRC_FEAT_FLAG_COVER_ART_GET_IMAGE = 0x0100, ESP_AVRC_FEAT_FLAG_COVER_ART_GET_LINKED_THUMBNAIL = 0x0200,

I don't have much experience and I can't find any example on the internet to help me, I've been looking for days and I realized that there are several people who also want to do this application but don't know how to start. I'll post the main code that I made but if you need all the files I can send them, I'll put a picture of how my project is so far, I would be extremely grateful if you could help me.

Code:

// LGFX
#define LGFX_AUTODETECT     // Autodetcção de Placa
#define LGFX_USE_V1         // Usa a nova versão da biblioteca
#include <LovyanGFX.hpp>    // Livraria principal

// LVGL
#include <C:\Users\Leonardo\Documents\Arduino\libraries\lvgl-8.3.3\lvgl.h>
#include "ui.h"
#include "ui_events.c"

//BLUETOOTH
#include "BluetoothA2DPSink.h"
BluetoothA2DPSink a2dp_sink;

static LGFX lcd;            // declara a variavel do display

char lcd_buf[40];           // Tamanho da variavel nome da Musica
char lcd_buf1[40];          // Tamanho da variavel nome do Artista
char lcd_image[100];
bool flagstate = false;

/*Change to your screen resolution*/
static const uint32_t screenWidth = 480;
static const uint32_t screenHeight = 320;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[screenWidth * 10];

void ProximaMusica(lv_event_t * e)
{
    lv_event_code_t event = lv_event_get_code(e);
  lv_obj_t *obj = lv_event_get_target(e);
  if (event == LV_EVENT_CLICKED) {
    a2dp_sink.next();
  }
}

void MusicaAnterior(lv_event_t * e)
{
    lv_event_code_t event = lv_event_get_code(e);
  lv_obj_t *obj = lv_event_get_target(e);
  if (event == LV_EVENT_CLICKED) {
    a2dp_sink.previous();
  }
}

void PlayPause(lv_event_t * e)
{
    lv_event_code_t event = lv_event_get_code(e);
  lv_obj_t *obj = lv_event_get_target(e);
  if (event == LV_EVENT_CLICKED) {
    a2dp_sink.play();
  }
}

void setup(void)
{
  initDisplay();
  lv_init();
  lv_disp_draw_buf_init(&draw_buf, buf, NULL, screenWidth * 10);

  //INICIA O DISPLAY LV
  static lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv);

  //MUDA A RESOLUÇÃO DO DISPLAY
  disp_drv.hor_res = screenWidth;
  disp_drv.ver_res = screenHeight;
  disp_drv.flush_cb = my_disp_flush;
  disp_drv.draw_buf = &draw_buf;
  lv_disp_drv_register(&disp_drv);

  //Initialize the (dummy) input device driver
  static lv_indev_drv_t indev_drv;
  lv_indev_drv_init(&indev_drv);
  indev_drv.type = LV_INDEV_TYPE_POINTER;
  indev_drv.read_cb = my_touchpad_read;
  lv_indev_drv_register(&indev_drv);

  ui_init();

  i2s_pin_config_t my_pin_config = {
    .bck_io_num = 26,
    .ws_io_num = 25,
    .data_out_num = 2,    
    .data_in_num = I2S_PIN_NO_CHANGE
  };

  a2dp_sink.set_pin_config(my_pin_config);
  a2dp_sink.set_bits_per_sample(16);  
  a2dp_sink.set_avrc_metadata_callback(avrc_metadata_callback);
  a2dp_sink.start("LK_W-Series"); 

}

void loop()
{ 
  lv_timer_handler();
  delay(1); // do nothing
}

//INICIA O DISPLAY
void initDisplay() {
  lcd.init();
  lcd.setRotation(1);
  lcd.setBrightness(255);
  lcd.fillScreen(TFT_BLACK);
}

//CHAMA AS INFORMAÇÕES
void avrc_metadata_callback(uint8_t id, const uint8_t *text) {

  flagstate = true;  // set flag within metadata function
  if (id == 0x1)
    snprintf(lcd_buf, 40, "%s                                ", text);
    lv_label_set_text(ui_Nome_Musica, lcd_buf);
     //lv_label_set_text(ui_SpeedLabel, "0");
  if (id == 0x2)
    snprintf(lcd_buf1, 40, "%s                                ", text);
    lv_label_set_text(ui_Nome_da_banda, lcd_buf1);

}

//CONFIG Display flushing
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  uint32_t w = (area->x2 - area->x1 + 1);
  uint32_t h = (area->y2 - area->y1 + 1);

  lcd.startWrite();
  lcd.setAddrWindow(area->x1, area->y1, w, h);
  lcd.writePixels((lgfx::rgb565_t *)&color_p->full, w * h);
  lcd.endWrite();

  lv_disp_flush_ready(disp);
}

//CONFIG Read the touchpad
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) {

  uint16_t x, y;
  if (lcd.getTouch(&x, &y)) {
    data->state = LV_INDEV_STATE_PR;
    data->point.x = x;
    data->point.y = y;

  } else {
    data->state = LV_INDEV_STATE_REL;
  }
}

WhatsApp Image 2023-03-14 at 21 55 04

Describe the solution you'd like.

No response

Describe alternatives you've considered.

No response

Additional context.

No response

wmy-espressif commented 1 year ago

Hi @leonardokucarz , thanks for your request on the AVRCP cover art feature. Functionality of "Cover Art" to transmit images associated to media items is provided through the protocol defined in the Bluetooth Basic Imaging Profile (BIP) over OBEX protocol. Currently neither OBEX nor BIP is implemented on the Bluedroid host in esp-idf.

I am afraid that we don't have the resources for the OBEX and BIP implementation for now and in the near future(possibly within the year 2023). But we will enlist them in our development plan.

esp-lrh commented 1 month ago

Hi, @leonardokucarz I am pleased to inform you that the AVRCP cover art feature is now supported as of commit cda2846558d10cd8a8190e69a2facfb4e57bec54 in the esp-idf master branch. This feature will be included in the upcoming 5.4 release. For usage instructions, you can refer to examples/bluetooth/bluedroid/classic_bt/a2dp_sink.

Thanks again for your request on the AVRCP cover art feature, as the feature is supported now, I am going to close this issue. If you have any questions, please feel free to reopen it and ask.