Getting song metadata with AVRCP commands (classic bluetooth)

Sinisa_PUF
Posts: 6
Joined: Thu Apr 20, 2017 3:15 pm
Location: Croatia
Contact:

Getting song metadata with AVRCP commands (classic bluetooth)

Postby Sinisa_PUF » Fri Jul 28, 2017 5:42 pm

Hi.

I'm trying to get song metadata (title, album, artist, etc..) from the android phone connected to ESP32 via bluetooth.
Phone supports this feature, I tested it on raspberry pi.

I've compiled a2dp example code and got the phone to connect and stream music.

Then I used provided esp_avrc_ct_send_passthrough_cmd() function to send media button presses and that
is also working fine. I can see that media player on the phone responds to those commands.

esp-idf doesn't yet supports fetching metadata from target devices so I dug around to see how esp_avrc_ct_send_passthrough_cmd()
actually transfers passthrough commands. It has some hoops but ultimately it led me to BTA_AvRemoteCmd() in bt_av_api.c.

To confirm that this is the right function I constructed a new passthrough command and sent it with BTA_AvRemoteCmd().
Media player responded properly.

The same file (btw_av_api.c) contains BTA_AvMetaCmd() with the following comment: "Send a Metadata/Advanced Control command"

I had a bit of trouble constructing a proper message for the function since the documentation is very scarce but
I managed to find this volume setting code (line 1238) for android and ported it over. It doesn't work unfortunately.
I'm using a proper handle (btc_rc_vb.rc_handle). For transaction label I used 0x0, which should be ok since I don't have
consequtive messages.

Then I reconfigured it for metadata request (AVRC_PDU_GET_ITEM_ATTRIBUTES) but I still had no success.

There is also BTA_AvVendorCmd for sending vendor specific commands, which to my understanding can be used to
achieve the same effect since metadata is just a subset of vendor specific commands. It too doesn't't work.

I'm using Wireshark to capture packets on the smartphone side and I see AVRCP passthrough commands (play, pause, etc) but
no vendor specific commands (metadata) are ever received, not even a improperly formatted ones.

Am I missing something in the process? Feature mask from target (phone) says it supports vendor commands.

Sinisa_PUF
Posts: 6
Joined: Thu Apr 20, 2017 3:15 pm
Location: Croatia
Contact:

Re: Getting song metadata with AVRCP commands (classic bluetooth)

Postby Sinisa_PUF » Sun Sep 17, 2017 8:03 pm

Further investigation into this yielded no results unfortunately.
I'd certainly appreciate a nudge in the right direction.

Sinisa_PUF
Posts: 6
Joined: Thu Apr 20, 2017 3:15 pm
Location: Croatia
Contact:

Re: Getting song metadata with AVRCP commands (classic bluetooth)

Postby Sinisa_PUF » Sat Sep 30, 2017 2:25 pm

Some progress, finally. But still no cigar.

In this issue on github Karl Wang said:
I think the issue that you cannot get it working is that the feature bit "BTA_AV_FEAT_METADATA" is not set in the argument of function BTA_AvEnable, called in btc_avk.c.
which is correct. After uncommenting a line of code I was able to use BTA_AvMetaCmd() and I could see that it was executed.
But phone rejects the request because after a correct AVRCP header there are no parameters even though I set them.

Here is my code for sending metadata request:

Code: Select all

static bt_status_t btc_avrc_ct_send_metadata_cmd()
{
  UINT32 attr_list[] = {
          AVRC_MEDIA_ATTR_ID_TITLE,
          AVRC_MEDIA_ATTR_ID_ARTIST,
          AVRC_MEDIA_ATTR_ID_ALBUM,
          AVRC_MEDIA_ATTR_ID_TRACK_NUM,
          AVRC_MEDIA_ATTR_ID_NUM_TRACKS,
          AVRC_MEDIA_ATTR_ID_GENRE,
          AVRC_MEDIA_ATTR_ID_PLAYING_TIME
          };
          
  return get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list);
  
}


static bt_status_t get_element_attribute_cmd (uint8_t num_attribute, uint32_t *p_attr_ids)
{
    tAVRC_STS status = BT_STATUS_UNSUPPORTED;
    int count  = 0;

    tAVRC_COMMAND avrc_cmd = {0};
    BT_HDR *p_msg = NULL;
    bt_status_t tran_status;

    avrc_cmd.get_elem_attrs.opcode = AVRC_OP_VENDOR;
    avrc_cmd.get_elem_attrs.status = AVRC_STS_NO_ERROR;
    avrc_cmd.get_elem_attrs.num_attr = num_attribute;
    avrc_cmd.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;

    for (count = 0; count < num_attribute; count++)
    {
        avrc_cmd.get_elem_attrs.attrs[count] = p_attr_ids[count];
    }

    status = AVRC_BldCommand(&avrc_cmd, &p_msg);
    if (status == AVRC_STS_NO_ERROR)
    {
        BTA_AvMetaCmd(btc_rc_vb.rc_handle, 0, AVRC_CMD_STATUS, p_msg);
        status = BT_STATUS_SUCCESS;
    }

    //if (p_msg != NULL) osi_freebuf(p_msg);

    return status;
}
I attached screenshots from Wireshark showing incomplete request, rejected response and
a proper message from a RN52 bluetooth module.
Attachments
Screen Shot 2017-09-30 at 16.03.10.png
Proper request from a RN52 bluetooth module
Screen Shot 2017-09-30 at 16.03.10.png (46.71 KiB) Viewed 17699 times
Screen Shot 2017-09-30 at 15.56.20.png
Rejected response from smartphone
Screen Shot 2017-09-30 at 15.56.20.png (48.07 KiB) Viewed 17699 times
Screen Shot 2017-09-30 at 15.51.42.png
Incomplete metadata request
Screen Shot 2017-09-30 at 15.51.42.png (46.22 KiB) Viewed 17699 times
Last edited by Sinisa_PUF on Tue Oct 10, 2017 3:22 am, edited 1 time in total.

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: Getting song metadata with AVRCP commands (classic bluetooth)

Postby WiFive » Sat Sep 30, 2017 4:54 pm

AVRC_BldCommand does not know how to build AVRC_PDU_GET_ELEMENT_ATTR

https://github.com/espressif/esp-idf/bl ... _ct.c#L212

Somebody did it here (backport I think) https://github.com/denisigo/fireprime_e ... 43d7c55b18

Sinisa_PUF
Posts: 6
Joined: Thu Apr 20, 2017 3:15 pm
Location: Croatia
Contact:

Re: Getting song metadata with AVRCP commands (classic bluetooth)

Postby Sinisa_PUF » Sat Sep 30, 2017 10:48 pm

Thank you :D
That's exactly what it was.

Just need to port/implement response handler and I'm set.
Attachments
Screen Shot 2017-10-01 at 00.43.16.png
Screen Shot 2017-10-01 at 00.43.16.png (41.77 KiB) Viewed 17678 times

Sinisa_PUF
Posts: 6
Joined: Thu Apr 20, 2017 3:15 pm
Location: Croatia
Contact:

Re: Getting song metadata with AVRCP commands (classic bluetooth)

Postby Sinisa_PUF » Tue Oct 03, 2017 3:16 am

I've got it.
Thanks again WiFive.

Here's my commit.
There is still a few things I need to touch up but when i'm done I'll make a pull request.
Attachments
Screen Shot 2017-10-03 at 05.08.33.png
Screen Shot 2017-10-03 at 05.08.33.png (54.76 KiB) Viewed 17636 times

tr1p1ea
Posts: 1
Joined: Wed Sep 18, 2019 11:00 pm

Re: Getting song metadata with AVRCP commands (classic bluetooth)

Postby tr1p1ea » Wed Sep 18, 2019 11:04 pm

Sorry for the massive bump - I was wondering if anyone had any code examples for ESP32 BT Audio playback + AVRCP track information?

Himbeer
Posts: 1
Joined: Sun Dec 08, 2019 1:19 pm

Re: Getting song metadata with AVRCP commands (classic bluetooth)

Postby Himbeer » Sun Dec 08, 2019 1:21 pm

tr1p1ea wrote:
Wed Sep 18, 2019 11:04 pm
Sorry for the massive bump - I was wondering if anyone had any code examples for ESP32 BT Audio playback + AVRCP track information?
This might help: https://github.com/espressif/esp-adf/issues/227

Who is online

Users browsing this forum: Baidu [Spider], Bing [Bot] and 128 guests