You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 5dcf8b2
Browse filesBrowse the repository at this point in the historyBrowse files
feat(media): one sound at a time across route videos, radio and audio tracks
Playing a route video pauses the header radio and the audio tracks, and
playing either of those pauses the video (site.mediaExclusivePlayback,
default true). A route video with video.muted plays only the picture and
stays out of the rule.
- shared/lib/media-playback: page-wide playback arbiter (moved from
features/audio-player, which re-exports it)
- features/video-playback: per-source controllers (YouTube IFrame Player
API, Vimeo postMessage protocol, native media, generic iframe focus),
embed playback params and useVideoPlayback
- content containers: shared header text, card title/description, frame
props and container style; md-container renders one branch
- route-builders: shared text and frame defaults (output unchanged)
- docs: README "Media playback", functionalities pages (en/pt/es),
frontend README; e2e/media-playback.spec.ts
- Languages: \`site.languages\` (enable/disable each one); UI strings: \`gitpagedocs/langs/<lang>.json\`
183
183
184
+
## Media playback (one sound at a time)
185
+
186
+
\`site.mediaExclusivePlayback\` (default \`true\`): playing a route video pauses the radio and the audio tracks, and playing the radio or an audio track pauses the video. It works with YouTube and Vimeo (through their player APIs), native files (\`mp4\`, \`webm\`, …) and any other embed.
187
+
188
+
To show a video without sound while the radio or an audio track explains it, set \`"muted": true\` in that route's \`video\` object: the video plays only the picture and stays out of the rule. \`"mediaExclusivePlayback": false\` turns the rule off for the whole site.
- Idiomas: \`site.languages\` (activa/desactiva cada uno); textos de la UI: \`gitpagedocs/langs/<lang>.json\`
176
176
177
+
## Reproduccion de medios (un sonido a la vez)
178
+
179
+
\`site.mediaExclusivePlayback\` (por defecto \`true\`): reproducir un video de ruta pausa la radio y las pistas de audio, y reproducir la radio o una pista de audio pausa el video. Funciona con YouTube y Vimeo (mediante las APIs de sus reproductores), archivos nativos (\`mp4\`, \`webm\`, …) y cualquier otro embed.
180
+
181
+
Para mostrar un video sin sonido mientras la radio o una pista de audio lo explica, usa \`"muted": true\` en el objeto \`video\` de la ruta: el video reproduce solo la imagen y queda fuera de la regla. \`"mediaExclusivePlayback": false\` desactiva la regla en todo el sitio.
182
+
177
183
## Variables de entorno
178
184
179
185
- \`GITPAGEDOCS_REPOSITORY_SEARCH\` – busqueda de repositorio (local)
- Idiomas: \`site.languages\` (liga/desliga cada um); textos da UI: \`gitpagedocs/langs/<lang>.json\`
176
176
177
+
## Reproducao de midia (um som por vez)
178
+
179
+
\`site.mediaExclusivePlayback\` (padrao \`true\`): dar play num video de rota pausa o radio e as trilhas de audio, e dar play no radio ou numa trilha de audio pausa o video. Funciona com YouTube e Vimeo (pelas APIs dos players), arquivos nativos (\`mp4\`, \`webm\`, …) e qualquer outro embed.
180
+
181
+
Para mostrar um video sem som enquanto o radio ou uma trilha de audio o explica, use \`"muted": true\` no objeto \`video\` da rota: o video roda so a imagem e fica fora da regra. \`"mediaExclusivePlayback": false\` desliga a regra no site inteiro.
182
+
177
183
## Variaveis de ambiente
178
184
179
185
- \`GITPAGEDOCS_REPOSITORY_SEARCH\` – busca de repositorio (local)
FSD import direction is enforced by the root `eslint.config.mjs` (`app → page-slices → widgets → features → entities → shared`).
@@ -71,6 +71,21 @@ When `site.docsAccess.enabled` is set in `gitpagedocs/config.json` (via the `git
71
71
-`GuideHero` enters with Motion variants: rows focus in with a stagger, and the title splits into grapheme glyphs (`model/hero-motion.ts`) that rise in while a visually hidden copy keeps the heading readable as one name. Each row drifts at its own `HERO_PARALLAX.depthPx` as the hero scrolls away.
72
72
-`GuideStory` (`ui/story/`) is a scroll-driven tour placed before the full guide. The section is one viewport tall per chapter and a sticky stage plays one chapter per slice of the page's own scroll (wheel, touch, keyboard and scrollbar keep working). Each chapter's numeral, headline and details move at different depths; the keyframes come from `chapterTimeline` in `model/story.ts` and run through function-form `useTransform` with `interpolate`, because the range form hands opacity to the native scroll timeline, which left the first chapter half visible. A rail jumps to any chapter, a skip link goes straight to the full guide, and with reduced motion the tour still crossfades while CSS pins every layer in place.
73
73
74
+
## Media playback
75
+
76
+
`shared/lib/media-playback` holds the page-wide playback arbiter: every player registers a `pause`
77
+
and calls `claim` before it starts, which pauses all the others. The radio and the audio tracks
78
+
(`features/audio-player`) and the route videos (`features/video-playback`) use it, so with
79
+
`site.mediaExclusivePlayback` (default `true`) only one of them sounds at a time.
80
+
81
+
`features/video-playback` picks a controller per source (`resolveVideoProvider`): the official YouTube
82
+
IFrame Player API attached to the existing iframe (`enablejsapi=1&origin=…`; it falls back to the
83
+
generic rule if the script cannot load), the Vimeo player `postMessage` protocol, the native media
84
+
`play` event, or, for any other embed, focus moving into the iframe (paused by reloading it).
85
+
`useVideoPlayback` wires the controller to the arbiter and rebuilds it when the source changes; the
86
+
page origin comes from `usePageOrigin`, empty in the static render so the exported markup stays
87
+
stable. A route video with `video.muted: true` starts without sound and stays out of the rule.
88
+
74
89
## Environment
75
90
76
91
`.env` (frontend-local; copy from `.env.example`):
@@ -95,6 +110,7 @@ PORT=3100 pnpm run test:e2e # use an alternate port if 3000 is taken
95
110
-`e2e/ai-console.spec.ts` and `e2e/ai-chat-drawer.spec.ts` verify the password gate, encrypted persistence (no plaintext key in `localStorage`), and reload behavior.
96
111
-`e2e/docs.spec.ts` checks the docs home renders with no horizontal overflow.
97
112
-`e2e/audio-playback.spec.ts` covers the audio route's centered fullscreen view and the mutual exclusion between the route player and the header radio.
113
+
-`e2e/media-playback.spec.ts` plays the YouTube route video over the header radio and back (needs network access to youtube.com).
98
114
-`e2e/introduction-guide.spec.ts` checks the guide's backdrop, reveal and layout across light, dark and white-primary themes.
0 commit comments