Commit Graph
5 Commits
Author SHA1 Message Date
DrSmoothl 7c0519f75f lint 2026-10-12 15:43:34 +08:00
DrSmoothl 622c90d418 fix(protocol): transcode QQ AI voice recordings
Normalize the observed AI SILK container marker at the shared audio transcode boundary before invoking the bundled decoder. Preserve caller-owned bytes and leave ordinary SILK, AMR, and unrelated inputs unchanged.

Add unit and packaged-addon regression coverage for MP3 conversion, payload preservation, and input immutability.

Fixes #268
2026-07-21 23:29:28 +08:00
DrSmoothl 5fe6b31eb6 refactor(ci): generalize native smoke tests
Replace the feature-specific MP3 verification command with a workspace-wide native test entry point.

Keep native regression cases in package-owned test suites so future checks can expand without adding workflow steps.
2026-07-17 18:27:30 +08:00
DrSmoothl b3838d204f fix(protocol): produce valid MP3 records
Use the dedicated audio conversion path for record output so mono QQ voice records produce valid MP3 data.

Add release-target smoke coverage and preserve conversion and cleanup failures for diagnostics.

Fixes #239
2026-07-17 18:17:48 +08:00
DrSmoothl 90456def2e feat(onebot): get_record out_format — server-side voice transcode (#165)
#165: get_record gains an optional `out_format` (mp3/amr/wma/m4a/spx/ogg/
wav/flac, mirroring NapCat). When set, the QQ voice (SILK/AMR) is
transcoded server-side and the result is attached as `data.base64`; the
original info (file/url/file_size) is preserved. Absent ⇒ behaviour
unchanged. This spares ASR consumers from shipping a SILK decoder.

- protocol: convertAudioBytes(bytes, format, deps?) drives the bundled
  SILK-capable ffmpeg addon's convertFile through temp files (always
  cleaned up), with a format allowlist and an output-size cap. Pure/
  injectable, unit-tested with a fake addon (6 cases).
- core: ExtrasApi.convertRecord(source, format) = loadBinarySource (64 MiB
  cap) → convertAudioBytes.
- onebot: get_record wires out_format; transcode failure (incl. an addon
  lacking SILK decode) degrades to ACTION_FAILED, never crashes.

Adversarially reviewed: no path traversal (format allowlisted), no SSRF
(source is the cached CDN url, not user input), cleanup covers every path,
graceful degradation confirmed. Catalog regenerated. Real-machine e2e
(does the shipped .node actually decode SILK?) is Phase 2.
2026-06-30 19:25:40 +08:00