|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +## Project Summary |
| 4 | + |
| 5 | +ArtPlayer is a monorepo for a modern HTML5 video player and its ecosystem packages. |
| 6 | + |
| 7 | +- Homepage: `https://artplayer.org` |
| 8 | +- Local dev site: `http://localhost:8082` |
| 9 | +- API docs: `https://artplayer.org/document` |
| 10 | +- Packaging model: workspace monorepo with per-package versioning and per-package build output |
| 11 | + |
| 12 | +The repository contains: |
| 13 | + |
| 14 | +- `packages/artplayer`: the core player |
| 15 | +- `packages/artplayer-plugin-*`: UI and playback plugins |
| 16 | +- `packages/artplayer-proxy-*`: proxy renderers and playback adapters |
| 17 | +- `packages/artplayer-tool-*`: helper tools |
| 18 | +- `packages/artplayer-vitepress`: docs site package |
| 19 | +- `docs/`: local demo site, examples, compiled assets, generated docs |
| 20 | +- `scripts/`: custom build/dev/doc tooling |
| 21 | + |
| 22 | +## Working Style For This Repo |
| 23 | + |
| 24 | +- Verify the real implementation before editing docs or examples. |
| 25 | +- Prefer changing the source package first, then regenerate build artifacts only when needed. |
| 26 | +- Keep package APIs small and consistent with existing ArtPlayer plugin conventions. |
| 27 | +- Preserve the existing visual and API style of sibling packages instead of inventing a new pattern. |
| 28 | +- When touching demo examples, make sure the example still works in `http://localhost:8082`. |
| 29 | +- Do not hand-edit `dist/`, `docs/compiled/`, or `docs/uncompiled/` unless a build step generated them. |
| 30 | + |
| 31 | +## Primary Commands |
| 32 | + |
| 33 | +Use the repo scripts rather than ad hoc bundler commands. |
| 34 | + |
| 35 | +### Development |
| 36 | + |
| 37 | +```bash |
| 38 | +npm run dev |
| 39 | +``` |
| 40 | + |
| 41 | +Starts the local dev site on port `8082` and interactively selects a package to watch. The selected package is built into: |
| 42 | + |
| 43 | +- `docs/uncompiled/<package>/` |
| 44 | + |
| 45 | +### Production Build |
| 46 | + |
| 47 | +```bash |
| 48 | +npm run build |
| 49 | +``` |
| 50 | + |
| 51 | +Interactive build for one package. Outputs: |
| 52 | + |
| 53 | +- `packages/<name>/dist/*.js|*.legacy.js|*.mjs` |
| 54 | +- copied artifacts into `docs/compiled/` |
| 55 | + |
| 56 | +Build all packages: |
| 57 | + |
| 58 | +```bash |
| 59 | +npm run build all |
| 60 | +``` |
| 61 | + |
| 62 | +### Other Project Scripts |
| 63 | + |
| 64 | +```bash |
| 65 | +npm run build:i18n |
| 66 | +npm run build:ts |
| 67 | +npm run build:docs |
| 68 | +npm run build:llm |
| 69 | +npm run build:test |
| 70 | +npm run lint |
| 71 | +npm run build:all |
| 72 | +``` |
| 73 | + |
| 74 | +Notes: |
| 75 | + |
| 76 | +- `npm run lint` targets package source/types plus scripts and TypeScript demo assets. |
| 77 | +- `npm run build:all` is expensive; use it when a change truly spans builds/docs/types/lint together. |
| 78 | + |
| 79 | +## Useful Local URLs |
| 80 | + |
| 81 | +- Root demo index: `http://localhost:8082` |
| 82 | +- Demo by package/example: |
| 83 | + - `http://localhost:8082/?libs=./uncompiled/<package>/index.js&example=<example>` |
| 84 | +- Docs: `http://localhost:8082/document/` |
| 85 | + |
| 86 | +For proxy/plugin work, prefer validating on the local demo page rather than reasoning only from source. |
| 87 | + |
| 88 | +## Repository Layout |
| 89 | + |
| 90 | +### Core package |
| 91 | + |
| 92 | +- `packages/artplayer/src/index.js`: player entry |
| 93 | +- `packages/artplayer/src/player/`: playback mixins and player-facing behavior |
| 94 | +- `packages/artplayer/src/control/`: bottom controls |
| 95 | +- `packages/artplayer/src/setting/`: settings panel |
| 96 | +- `packages/artplayer/src/contextmenu/`: context menu items |
| 97 | +- `packages/artplayer/src/plugins/`: built-in plugins |
| 98 | +- `packages/artplayer/src/utils/`: shared helpers, component base classes, DOM utilities |
| 99 | +- `packages/artplayer/types/`: public TS declarations |
| 100 | + |
| 101 | +### Ecosystem packages |
| 102 | + |
| 103 | +Most ecosystem packages follow this pattern: |
| 104 | + |
| 105 | +```text |
| 106 | +packages/<package>/ |
| 107 | + src/index.js |
| 108 | + src/*.less # optional |
| 109 | + types/*.d.ts # optional but preferred for public APIs |
| 110 | + README.md |
| 111 | + package.json |
| 112 | + dist/* |
| 113 | +``` |
| 114 | + |
| 115 | +### Demo and docs assets |
| 116 | + |
| 117 | +- `docs/assets/example/*.js`: runnable browser examples |
| 118 | +- `docs/assets/ts/*.js`: TypeScript demo assets targeted by lint/docs flows |
| 119 | +- `docs/uncompiled/`: dev output |
| 120 | +- `docs/compiled/`: production-copied output |
| 121 | +- `docs/document/`: generated docs content |
| 122 | + |
| 123 | +## Architecture Notes |
| 124 | + |
| 125 | +### Core player |
| 126 | + |
| 127 | +ArtPlayer composes many subsystems during construction. Common integration points: |
| 128 | + |
| 129 | +- `art.template` |
| 130 | +- `art.events` |
| 131 | +- `art.controls` |
| 132 | +- `art.setting` |
| 133 | +- `art.contextmenu` |
| 134 | +- `art.layers` |
| 135 | +- `art.plugins` |
| 136 | +- `art.player` |
| 137 | + |
| 138 | +When extending behavior, prefer integrating with these existing systems rather than bypassing them. |
| 139 | + |
| 140 | +### Control and setting components |
| 141 | + |
| 142 | +Controls and setting entries are managed through component registries. |
| 143 | + |
| 144 | +Relevant implementation: |
| 145 | + |
| 146 | +- `packages/artplayer/src/control/index.js` |
| 147 | +- `packages/artplayer/src/setting/index.js` |
| 148 | +- `packages/artplayer/src/utils/component.js` |
| 149 | + |
| 150 | +Important behavior: |
| 151 | + |
| 152 | +- `art.controls.update(...)` and `art.setting.update(...)` replace existing entries by `name` |
| 153 | +- `art.controls.remove(name)` and `art.setting.remove(name)` are the correct cleanup APIs |
| 154 | +- selector-style controls rely on `default` flags to determine highlighted items |
| 155 | + |
| 156 | +If a plugin conditionally shows UI, it must also clean that UI up when the condition no longer holds. |
| 157 | + |
| 158 | +### Plugin shape |
| 159 | + |
| 160 | +Standard plugin/export shape: |
| 161 | + |
| 162 | +```js |
| 163 | +export default function somePlugin(option = {}) { |
| 164 | + return (art) => { |
| 165 | + return { |
| 166 | + name: 'somePlugin', |
| 167 | + } |
| 168 | + } |
| 169 | +} |
| 170 | +``` |
| 171 | + |
| 172 | +Naming conventions: |
| 173 | + |
| 174 | +- package: `artplayer-plugin-<name>` |
| 175 | +- global: `artplayerPlugin<Name>` |
| 176 | +- exported function name should match the global naming convention |
| 177 | + |
| 178 | +### Proxy packages |
| 179 | + |
| 180 | +Proxy packages usually return a non-video element or video-like shim and emulate media element behavior for ArtPlayer. |
| 181 | + |
| 182 | +Examples: |
| 183 | + |
| 184 | +- `packages/artplayer-proxy-canvas` |
| 185 | +- `packages/artplayer-proxy-mediabunny` |
| 186 | + |
| 187 | +When editing proxy packages: |
| 188 | + |
| 189 | +- keep the HTMLMediaElement-like surface coherent |
| 190 | +- keep event ordering stable |
| 191 | +- treat `loadedmetadata`, `loadeddata`, `canplay`, `seeked`, `waiting`, and `pause/play` semantics carefully |
| 192 | +- ensure UI state is updated and cleaned up when source topology changes |
| 193 | + |
| 194 | +### HLS / adaptive playback controls |
| 195 | + |
| 196 | +The reference implementation for adaptive selector UI is: |
| 197 | + |
| 198 | +- `packages/artplayer-plugin-hls-control/src/index.js` |
| 199 | + |
| 200 | +If adding HLS-like quality/audio selection elsewhere: |
| 201 | + |
| 202 | +- follow the selector format used there |
| 203 | +- derive highlighted items from actual current tracks, not only from mode flags |
| 204 | +- avoid stale selectors when changing to streams without the same topology |
| 205 | + |
| 206 | +## Build and Artifact Rules |
| 207 | + |
| 208 | +- Always edit `src/` and `types/` first. |
| 209 | +- Rebuild package artifacts after source changes that should ship. |
| 210 | +- Do not treat `dist/` as source of truth. |
| 211 | +- If a change affects demo behavior, also verify the matching file in `docs/assets/example/`. |
| 212 | + |
| 213 | +For package-specific builds, the normal flow is: |
| 214 | + |
| 215 | +1. `npm run dev` and pick the package for fast local iteration |
| 216 | +2. validate in `http://localhost:8082` |
| 217 | +3. `npm run build` and pick the package when ready to update shippable artifacts |
| 218 | + |
| 219 | +## Documentation Expectations |
| 220 | + |
| 221 | +If a public package API changes, check whether these also need updates: |
| 222 | + |
| 223 | +- the package `README.md` |
| 224 | +- `docs/assets/example/<name>.js` |
| 225 | +- `types/<name>.d.ts` |
| 226 | +- any generated compiled outputs if you built the package |
| 227 | + |
| 228 | +Keep examples realistic and runnable. Prefer local demo URLs or stable public sample streams. |
| 229 | + |
| 230 | +## Code Quality Expectations |
| 231 | + |
| 232 | +- Follow existing plain JavaScript style in the repo. |
| 233 | +- Use ASCII unless a file already requires otherwise. |
| 234 | +- Match the minimal-comment style of neighboring files. |
| 235 | +- Avoid unnecessary abstraction; this codebase generally prefers direct implementation. |
| 236 | +- Respect current browser targets: |
| 237 | + - modern build: `es2020` |
| 238 | + - legacy build: `es2015` |
| 239 | + |
| 240 | +## Validation Checklist |
| 241 | + |
| 242 | +For most package changes, validate as many of these as apply: |
| 243 | + |
| 244 | +- source file lint passes |
| 245 | +- local demo page loads |
| 246 | +- expected events fire once and in the correct order |
| 247 | +- controls/settings render correctly |
| 248 | +- cleanup works after restart, source switch, or destroy |
| 249 | +- package build succeeds |
| 250 | + |
| 251 | +For playback/proxy changes specifically: |
| 252 | + |
| 253 | +- test initial load |
| 254 | +- test play/pause |
| 255 | +- test seek |
| 256 | +- test switching source or track topology |
| 257 | +- test whether UI reflects the actual selected track/quality |
| 258 | + |
| 259 | +## Notes Specific To `artplayer-proxy-mediabunny` |
| 260 | + |
| 261 | +This package now depends on modern `mediabunny` and supports HLS through `mediabunny` input handling. |
| 262 | + |
| 263 | +Files to understand first: |
| 264 | + |
| 265 | +- `packages/artplayer-proxy-mediabunny/src/index.js` |
| 266 | +- `packages/artplayer-proxy-mediabunny/src/VideoShim.js` |
| 267 | +- `packages/artplayer-proxy-mediabunny/src/MediaBunnyEngine.js` |
| 268 | +- `packages/artplayer-proxy-mediabunny/src/input.js` |
| 269 | +- `packages/artplayer-proxy-mediabunny/src/m3u8.js` |
| 270 | + |
| 271 | +Key expectations: |
| 272 | + |
| 273 | +- HLS source detection should happen in `input.js` |
| 274 | +- track selection should use actual pairable audio/video relationships |
| 275 | +- selector UI should mirror the behavior of `artplayer-plugin-hls-control` |
| 276 | +- selector cleanup is required when a later source no longer supports the same controls |
| 277 | +- avoid duplicate readiness events during load and track switches |
| 278 | + |
| 279 | +## When Unsure |
| 280 | + |
| 281 | +Start with the nearest sibling implementation instead of inventing a new pattern: |
| 282 | + |
| 283 | +- control/setting UI: `artplayer-plugin-hls-control`, `artplayer-plugin-dash-control` |
| 284 | +- proxy behavior: `artplayer-proxy-canvas`, `artplayer-proxy-mediabunny` |
| 285 | +- component lifecycle: `packages/artplayer/src/utils/component.js` |
| 286 | + |
| 287 | +If a change spans source, examples, and packaging, make all three consistent in the same pass. |
0 commit comments