From ca36be96e036bfe1ac91bb413fce4f0c30fdbf4f Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 29 Jul 2026 13:00:40 -0400 Subject: [PATCH] docs: add cross-client media playback guide (#116005) * docs: add media playback guide * docs: complete media playback glossary --- docs/.i18n/glossary.zh-CN.json | 28 ++++++ docs/concepts/features.md | 1 + docs/docs.json | 1 + docs/docs_map.md | 17 ++++ docs/nodes/audio.md | 5 ++ docs/nodes/images.md | 5 ++ docs/nodes/media-playback.md | 153 +++++++++++++++++++++++++++++++++ docs/tools/media-overview.md | 5 ++ docs/tools/tts.md | 12 ++- 9 files changed, 225 insertions(+), 2 deletions(-) create mode 100644 docs/nodes/media-playback.md diff --git a/docs/.i18n/glossary.zh-CN.json b/docs/.i18n/glossary.zh-CN.json index 3f8693deb2de..495d930a863e 100644 --- a/docs/.i18n/glossary.zh-CN.json +++ b/docs/.i18n/glossary.zh-CN.json @@ -1447,6 +1447,34 @@ "source": "Media understanding", "target": "媒体理解" }, + { + "source": "Media playback", + "target": "媒体播放" + }, + { + "source": "Image and media support", + "target": "图像和媒体支持" + }, + { + "source": "Audio and voice notes", + "target": "音频和语音消息" + }, + { + "source": "Media overview", + "target": "媒体概览" + }, + { + "source": "Text to speech", + "target": "文本转语音" + }, + { + "source": "Linux app", + "target": "Linux 应用" + }, + { + "source": "Inline audio and video playback", + "target": "内联音频和视频播放" + }, { "source": "Models CLI reference", "target": "模型 CLI 参考" diff --git a/docs/concepts/features.md b/docs/concepts/features.md index 446a3d38743c..8456b0308507 100644 --- a/docs/concepts/features.md +++ b/docs/concepts/features.md @@ -59,6 +59,7 @@ title: "Features" **Media:** - Images, audio, video, and documents in and out +- [Inline audio and video playback](/nodes/media-playback) across the Control UI, iOS/macOS, Android, and the Linux companion - Shared image generation and video generation capability surfaces - Voice note transcription - Text-to-speech with multiple providers diff --git a/docs/docs.json b/docs/docs.json index 890577e49407..84237758df4b 100644 --- a/docs/docs.json +++ b/docs/docs.json @@ -1747,6 +1747,7 @@ "group": "Media capabilities", "pages": [ "nodes/media-understanding", + "nodes/media-playback", "nodes/images", "nodes/audio", "nodes/camera", diff --git a/docs/docs_map.md b/docs/docs_map.md index 7e5390af9122..6c124fcae6fc 100644 --- a/docs/docs_map.md +++ b/docs/docs_map.md @@ -5143,6 +5143,23 @@ Do not edit it by hand; run `pnpm docs:map:gen`. - H2: UX copy (suggested) - H2: Related +## nodes/media-playback.md + +- Route: /nodes/media-playback +- Headings: + - H2: Client support + - H2: Portable formats + - H2: Lazy playback renditions + - H2: Managed attachments and access + - H2: Metadata and limits + - H2: Troubleshooting + - H3: Duration or dimensions are missing + - H3: A recognized format downloads instead of playing + - H3: Playback stays in preparing state + - H3: Linux reports a codec error + - H3: Android shows a media row while offline + - H2: Related + ## nodes/media-understanding.md - Route: /nodes/media-understanding diff --git a/docs/nodes/audio.md b/docs/nodes/audio.md index 81312172b3aa..21a012a379fd 100644 --- a/docs/nodes/audio.md +++ b/docs/nodes/audio.md @@ -5,6 +5,10 @@ read_when: title: "Audio and voice notes" --- +This page covers inbound transcription and voice-note handling. For inline +audio and video players in OpenClaw chat clients, see +[Media playback](/nodes/media-playback). + ## What it does When audio understanding is enabled (or auto-detected), OpenClaw: @@ -198,6 +202,7 @@ On channels that support audio preflight, OpenClaw transcribes audio **before** ## Related +- [Media playback](/nodes/media-playback) - [Media understanding](/nodes/media-understanding) - [Talk mode](/nodes/talk) - [Voice wake](/nodes/voicewake) diff --git a/docs/nodes/images.md b/docs/nodes/images.md index 0b33ba5f58ae..fe77964adf6c 100644 --- a/docs/nodes/images.md +++ b/docs/nodes/images.md @@ -7,6 +7,10 @@ title: "Image and media support" The WhatsApp channel runs on Baileys Web. This page covers media handling rules for send, gateway, and agent replies. +For inline audio and video in the Control UI and native apps, including +portable formats, byte limits, and lazy transcoding, see +[Media playback](/nodes/media-playback). + ## Goals - Send media with an optional caption via `openclaw message send --media`. @@ -90,4 +94,5 @@ The 16MB audio/video and 100MB document figures above are the shared per-kind me - [Camera capture](/nodes/camera) - [Media understanding](/nodes/media-understanding) +- [Media playback](/nodes/media-playback) - [Audio and voice notes](/nodes/audio) diff --git a/docs/nodes/media-playback.md b/docs/nodes/media-playback.md new file mode 100644 index 000000000000..73dca0162bee --- /dev/null +++ b/docs/nodes/media-playback.md @@ -0,0 +1,153 @@ +--- +summary: "Inline audio and video playback across the Control UI and native apps" +read_when: + - Playing or troubleshooting audio and video attachments in chat + - Comparing media format support across OpenClaw clients + - Debugging playback metadata, transcoding, or codec availability +title: "Media playback" +--- + +OpenClaw chat clients play assistant audio and video attachments inline. The +Gateway keeps those attachments behind session-scoped access, serves seekable +byte ranges, and can prepare a portable playback rendition for recognized +formats that are not safe across every client. + +This page covers playback in OpenClaw clients. Channel delivery, inbound media +understanding, and live voice conversations use separate paths; see +[Image and media support](/nodes/images), +[Media understanding](/nodes/media-understanding), and [Talk mode](/nodes/talk). + +## Client support + +| Client | Playback path | Operator notes | +| --------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Control UI | Themed inline audio cards and native video controls | Audio cards provide play/pause, seek, elapsed and total time, download, a voice-note badge, and keyboard controls. Space toggles playback; Left/Right seek by five seconds. Starting one audio card pauses the previous one. Video upload is available from the chat attachment picker. | +| iOS and macOS | `AVAudioPlayer` for audio and `AVPlayer` for video | Inline media coordinates with Talk and Listen so two speech paths do not play over each other. For a pinned-TLS Gateway, the app performs a bounded authenticated download before video playback instead of bypassing certificate pinning. | +| Android | Media3 ExoPlayer | The app streams video through the authenticated Gateway HTTP client, requests Android audio focus, and coordinates attachment playback with Talk/TTS. Cached transcript media rows remain visible offline, but playback needs a connection to obtain a fresh media ticket. | +| Linux companion | Control UI inside the companion WebView | Codec availability comes from GStreamer. Released packages include or declare the expected codec plugins; see [Linux media codecs](/platforms/linux#media-codecs). | + +## Portable formats + +The Gateway classifies these formats as the portable native set shared by the +browser, Apple players, and Android Media3: + +| Kind | Portable native input | Recognized transcode input | Playback target | +| ----- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------ | -------------------------------------------------------- | +| Audio | MP3; AAC in M4A/MP4; PCM WAV | AAC, AIFF, AMR/AMR-WB, CAF, FLAC, Ogg/Opus/Vorbis, WebM audio, WMA | AAC in M4A (`audio/mp4`) | +| Video | H.264 MP4 with a portable profile and 4:2:0 pixel format; AAC or MP3 audio when present | AVI, FLV, Matroska/MKV, QuickTime/MOV, WebM, ASF, WMV | H.264/AAC MP4 with 4:2:0 pixel format, at most 1920×1080 | + +The Linux companion can also play formats supplied by its installed GStreamer +plugins. Browser and operating-system updates may add native formats, but the +table above is the cross-client contract OpenClaw targets. + +## Lazy playback renditions + +Both Gateway byte routes accept `?playback=1`: the managed attachment route +under `/api/chat/media/outgoing/.../full` and the Control UI assistant-media +route. Attachment metadata can report `playback: "native"` or +`playback: "transcode"` so a client can choose the rendition deliberately. + +Playback conversion is lazy: + +1. A native source passes through unchanged. +2. A recognized non-portable source starts a bounded `ffmpeg` job. The route + returns HTTP `202` with `{ "status": "preparing" }` while the rendition is + being prepared. +3. A later request receives the cached M4A or MP4 rendition. +4. If inspection or conversion is unavailable, fails, or exceeds a limit, the + route falls back to the original bytes. The client can then show its + unplayable-media fallback and keep the download action available. + +Transcoding accepts sources up to 20 minutes and never raises the normal audio +or video byte cap. Cached playback renditions are pruned by normal media-store +maintenance. + +## Managed attachments and access + +Agent-produced audio and video are stored as managed media artifacts. Images +keep their separate managed-image artifact family. Native clients resolve the +artifact through `artifacts.download`, which returns inline base64 bytes when +the artifact is byte-backed or a short-lived, ticketed URL when it is +Gateway-managed. + +The ticketed byte routes support: + +- `Range` requests with HTTP `206 Partial Content` for seeking +- `ETag` and `If-Range` for safe resume behavior +- `HEAD` requests with the same content metadata and no response body + +Do not copy a ticketed URL into durable configuration. Clients reacquire a +ticket from the authenticated Gateway when needed. + +## Metadata and limits + +Chat attachments may include `sizeBytes`, `durationMs`, `width`, and `height`. +OpenClaw also uses `ffprobe`, when available, to fill audio duration and video +duration/dimensions for media facts and the Control UI `?meta=1` availability +probe. Probing is best-effort: a missing or failed probe leaves fields absent +instead of rejecting the attachment. + +Gateway-managed assistant attachments use these per-file caps: + +| Kind | Maximum size | +| ----- | -----------: | +| Image | 12 MiB | +| Audio | 16 MiB | +| Video | 16 MiB | + +These are playback/storage caps, not the separate media-understanding limits. +For transcription and description limits, see +[Image and media support](/nodes/images#limits-and-errors). + +## Troubleshooting + +### Duration or dimensions are missing + +Check that `ffprobe` is installed on the Gateway host and visible on its +`PATH`: + +```bash +ffprobe -version +``` + +Playback of an already portable file can still work without metadata. + +### A recognized format downloads instead of playing + +Check both media tools on the Gateway host: + +```bash +ffmpeg -version +ffprobe -version +``` + +`ffprobe` classifies codecs and duration; `ffmpeg` creates the portable +rendition. If either step cannot safely handle the source, OpenClaw serves the +original file and the client keeps its fallback/download path. + +### Playback stays in preparing state + +The first rendition request is asynchronous. Wait briefly and retry. Very +large, longer than 20-minute, unprobeable, or unsupported sources remain on the +original-byte fallback instead of blocking the Gateway. + +### Linux reports a codec error + +Use the package and source-build instructions in +[Linux media codecs](/platforms/linux#media-codecs). The `.deb` depends on the +required GStreamer plugin packages; the AppImage carries the media framework +and codecs installed by the release build. + +### Android shows a media row while offline + +That is expected. Android caches the transcript metadata, not the attachment +bytes or its short-lived download capability. Reconnect, then play again so the +app can request a new ticket. + +## Related + +- [Image and media support](/nodes/images) +- [Audio and voice notes](/nodes/audio) +- [Media overview](/tools/media-overview) +- [Text to speech](/tools/tts) +- [Linux app](/platforms/linux) diff --git a/docs/tools/media-overview.md b/docs/tools/media-overview.md index edc3f11ef0f4..e4c93a8286d1 100644 --- a/docs/tools/media-overview.md +++ b/docs/tools/media-overview.md @@ -48,6 +48,10 @@ telephony, meetings, browser realtime, and native push-to-talk clients. Transcribe inbound voice messages through batch STT or Voice Call streaming STT providers. + + Play assistant audio and video inline across the Control UI and native + apps, with managed access and portable playback renditions. + ## Provider capability matrix @@ -171,6 +175,7 @@ catalogs returned by the Gateway. - [Video generation](/tools/video-generation) - [Music generation](/tools/music-generation) - [Text-to-speech](/tools/tts) +- [Media playback](/nodes/media-playback) - [Media understanding](/nodes/media-understanding) - [Audio nodes](/nodes/audio) - [Talk mode](/nodes/talk) diff --git a/docs/tools/tts.md b/docs/tools/tts.md index a15491175a83..071eaebe89bb 100644 --- a/docs/tools/tts.md +++ b/docs/tools/tts.md @@ -421,8 +421,8 @@ is required by OpenClaw's provider configuration but is not validated by the loopback server. -The Homebrew `speech` executable can write directly to OpenClaw's temporary -output path: +The Homebrew `speech` executable can write directly to OpenClaw's +per-invocation output path: ```json5 { @@ -812,6 +812,13 @@ whether voice-style TTS should ask providers for a native `voice-note` target or keep normal `audio-file` synthesis, and whether the channel transcodes non-native output before sending. +After synthesis, OpenClaw persists batch TTS output in the media store under +`tool-speech-synthesis`. The reply uses that stable media path instead of a +provider temporary file, and normal media maintenance prunes expired output. +Local CLI providers may still use `{{OutputPath}}` as scratch space before +OpenClaw imports the completed bytes. See [Media playback](/nodes/media-playback) +for inline-player formats and limits. + | Target | Format | | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | | Feishu / Matrix / Telegram / WhatsApp | Voice-note replies prefer **Opus** (`opus_48000_64` from ElevenLabs, `opus` from OpenAI). 48 kHz / 64 kbps balances clarity and size. | @@ -1112,6 +1119,7 @@ provider default. ## Related - [Media overview](/tools/media-overview) +- [Media playback](/nodes/media-playback) - [Music generation](/tools/music-generation) - [Video generation](/tools/video-generation) - [Slash commands](/tools/slash-commands)