기록

[GPT가 알려주는] Vendor Dependent | Bluetooth Music Player (AVRCP, MediaSession) 본문

잡동사니/GPT가 알려주는

[GPT가 알려주는] Vendor Dependent | Bluetooth Music Player (AVRCP, MediaSession)

heylo 2025. 9. 11. 17:32

좋은 질문이에요 👍

네, **Bluetooth Music Player의 벤더(제조사)**에 따라 셔플/반복 모드 같은 상태가 다르게 동작하거나, 심지어는 데이터가 오는 형식 자체가 달라집니다. 이유를 정리해드릴게요:


1. 표준은 AVRCP

  • 블루투스 음악 제어는 AVRCP (Audio/Video Remote Control Profile) 표준을 따릅니다.
  • 여기서 정의된 건 플레이/일시정지, 다음/이전 트랙, 메타데이터(제목/가수) 같은 필수 기능이에요.
  • 셔플(Shuffle) / 반복(Repeat)은 Player Application Settings라는 확장 필드로 들어가지만, **선택 구현(Optional)**입니다. 즉, 벤더가 안 넣으면 아예 안 와요.

2. 벤더별 차이

  • 아이폰 (iOS)
    • MediaSession과 AVRCP를 꽤 충실히 연동해줍니다.
    • 그래서 iPhone에서 셔플/반복을 바꾸면 AVRCP 이벤트가 컨트롤러(차량/헤드유닛)에 전달돼요.
  • 안드로이드 폰 (삼성, LG, Pixel 등)
    • 공통적으로 AVRCP는 지원하지만, 셔플/반복 모드를 AVRCP에 싱크해주지 않는 경우가 많습니다.
    • 즉, 안드로이드 기기 내부의 MediaSession은 바뀌지만, AVRCP Controller로는 "Settings Changed" 같은 로그만 오고 실제 값은 안 채워지는 경우가 흔해요.
    • 제조사별 커스텀도 심합니다. 예) 삼성 뮤직 앱은 metadata 필드를 다 주지만, 구글 뮤직(YouTube Music)은 간소화해서 보냅니다.

3. 데이터 오는 형식 차이

  • AVRCP에서 오는 패킷은 TLV(Tag-Length-Value) 형식이에요.
    • 예: RepeatMode = 0x01 (Single), 0x02 (All)
    • ShuffleMode = 0x01 (Group), 0x02 (All)
  • 그런데 벤더마다 이걸 채우는 방식이 다름:
    • 어떤 기기는 값을 무조건 0 (OFF)만 던짐 → 컨트롤러 입장에선 항상 해제 상태로 보임.
    • 어떤 기기는 값은 보내지만, UI에서 버튼을 눌러도 반영 안 됨.
    • 어떤 기기는 아예 이 필드를 빼버림.

4. 결론

  • 아이폰 → AVRCP + MediaSession 동기화 잘 됨 → 셔플/반복 정보 교환 O
  • 안드로이드 폰 → 벤더/앱마다 다르고 AVRCP 확장 값 무시하는 경우 많음 → 셔플/반복 동기화 X
  • 따라서 지금처럼 "UI는 잘 갱신되는데 실제로 블루투스 소스와 안 맞는" 현상은 안드로이드 쪽에서 AVRCP Application Settings를 무시하기 때문에 발생하는 게 맞습니다.

👉 질문:
당신이 원하는 건 내 앱에서 버튼 누르면 소스(안드로이드/아이폰)의 모드가 실제로 바뀌는 것인가요,
아니면 소스에서 바꾼 걸 내 앱에서 정확히 읽어오는 것인가요?

둘 중 어디를 우선 맞추고 싶으세요?