Skip to content

Feature/music play demo - #12

Open
sedawwk wants to merge 4 commits into
masterfrom
feature/music-play-demo
Open

Feature/music play demo#12
sedawwk wants to merge 4 commits into
masterfrom
feature/music-play-demo

Conversation

@sedawwk

@sedawwk sedawwk commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

add music play demo

sedawwk added 3 commits August 7, 2026 12:13
Adds music_play_demo.c which sends a text query triggering the server's
music skill, parses the returned audio metadata, and downloads the mp3
trial clip. Registers the tai_music_play_demo target in the POSIX
CMakeLists.txt.
Adds tutorials/music-play.md covering the music play demo: build/run
instructions, SKILL response parsing, copyright notes (trial clip
duration limits, NetEase Cloud Music integration via Tuya content
server). Registers it in sidebars.ts under AI功能 after 语音/文本聊天
and lists it in quick-start.md.
Adds an Added entry under [Unreleased] for the tai_music_play_demo
example and its user guide.
@heshaoqiong-tuya
heshaoqiong-tuya force-pushed the feature/music-play-demo branch from 0d6e7ae to efd244f Compare August 10, 2026 07:36
Fixes specific to this demo, found reviewing it against the SDK
contracts. The shared-helper work that the review also turned up lands
in the following commit; this one stays self-contained.

- download_mp3() built a curl command line from the server-supplied URL
  and ran it through system(), where $(...) in a URL would have executed
  as the demo user. It now uses fork + execvp with no shell, so the URL
  is one argv element that cannot be read as a command, and only http(s)
  schemes are accepted.

- That function was never called. The file header, the tutorial and the
  changelog all promised output_music.mp3; nothing wrote it. It is wired
  up, so the documented behaviour is the actual behaviour.

- devid / secret_key / local_key from argv were memcpy'd into
  iot_client_config_t's 32-byte fields with no length check, overflowing
  the stack-local config. An over-long value is rejected up front.

- "code" was resolved against the whole document, so the common
  {"code":0,...,"data":{"code":"music"}} envelope matched the outer
  status code: the demo dropped the music response without a word while
  still reporting success. The check splits into is_music_response() and
  try_parse_music(), so "not a music response" is distinguishable from
  "a music response whose payload could not be read".

- The exit status reflects the outcome. got_music was set before knowing
  whether parsing had succeeded and never read again, so a run where the
  AI merely chatted was indistinguishable from one that found a song.

- The metadata box padded with %-31s, i.e. by bytes, so the Chinese
  titles this demo exists to show always broke the border: 开不了口 is
  12 bytes but 8 columns. Padding is by display column now, truncating
  on a character boundary. imageUrl was extracted and discarded; it is
  printed.

The tutorial follows: the run commands no longer assume a directory the
build block does not leave you in, the sample output matches what the
code prints, and the exit-code contract and the no-shell download
constraint are stated.

Builds clean under -Wall -Wextra -Wshadow.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@heshaoqiong-tuya
heshaoqiong-tuya force-pushed the feature/music-play-demo branch from efd244f to 096f2fe Compare August 10, 2026 07:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants