Skip to content

Embed: AUTO checkbox, lanes down to the seek bar, and Load before downloading on a phone - #875

Merged
nulltask merged 3 commits into
develfrom
feature/embed-autoplay-toggle
Oct 31, 2026
Merged

nulltask merged 3 commits into
develfrom
feature/embed-autoplay-toggle

Conversation

@nulltask

Copy link
Copy Markdown
Owner

Summary

  • AUTO checkbox (155bd8d): be-music-preview-select (list header) and be-music-preview-start (under the play button) gain autoPlay and emit auto-play-change. The embed starts it from ?mode= and switches between the AUTO preview and the viewer's play without touching the URL; under the play button it loads the play again in the other mode.
  • Lanes down to the seek bar (b9bc65c): on a phone held upright the lanes stopped well above the controls; held sideways (SP or DP) the judgement line sat under the seek bar; a DP chart letterboxed on a phone held upright had the controls over its lanes. previewJudgementInset keeps clear only the controls' 54 CSS px as tall as they get on a 320 px phone plus 16 px, in both orientations, and the preview HUD puts the controls along the bottom of the screen rather than the stage.
  • Load before downloading on mobile (c6437bc): a phone or tablet (or a browser asking to save data) shows a Load button with the archive's file name and size (from a HEAD request) and downloads only once it is pressed. /__url-load-proxy answers HEAD with the upstream's Content-Length (unless compressed).
  • Docs (EN/JA), changesets for @be-music/app-play, @be-music/player-ui and @be-music/worker-play, and the bench case for the new export.

Tests

  • pnpm run check
  • vp test run packages/player-ui packages/app-play/src/embed packages/worker-play (new: embedModeOfAutoPlay, embedWaitsToDownload, readDownloadSize / describeDownload, previewJudgementInset, the proxy's HEAD size)
  • New embed E2E cases (AUTO checkbox, Load on a touch context) run in CI only.
  • Checked by hand in the dev server: the checkbox in the list header (right edge on the rows') and under the play button, DP lanes in 375×700 portrait and 700×340 landscape, and the Load button at 375×812 (HEAD only until pressed).

🤖 Generated with Claude Code

…?mode=

be-music-preview-select and be-music-preview-start gain an autoPlay property that shows an AUTO checkbox (the list's header, under the play button) and emits auto-play-change. The embed starts it from ?mode= and switches its mode on a change; under the play button it loads the play again in the other mode.
…r it

On a phone held upright the lanes stopped well above the controls, and on a phone held sideways (SP or DP) the judgement line sat under the seek bar. Keep clear only the controls' 54 CSS px as tall as they get on a 320 px phone and a 16 px gap (previewJudgementInset), in both orientations. The preview HUD puts the controls along the bottom of the screen rather than the stage, so a DP chart letterboxed on a phone held upright keeps them off its lanes.
… on a phone

A phone or tablet (or a browser asking to save data) no longer downloads the track as soon as the embed opens. It shows a Load button (be-music-preview-start's new load mode and caption) with the file name and the size a HEAD request reports; /__url-load-proxy now answers HEAD with the upstream's Content-Length.
@github-actions

Copy link
Copy Markdown
Contributor

Exports Benchmark

🔴 3 regressions · 0 improvements · 19 within noise · 888 compared

188f6456 → c6437bcb · 3 runs base / 3 runs head · a regression or improvement is a change past ±8% whose runs do not overlap · times are per call (median)

Regressions (3)

API Base Head Change Run spread (base / head)
player-ui.resolvePreviewPortrait 13.3 ns 44.7 ns 236.3% slower ±0.3% / ±4.8%
player-ui.resolvePreviewInfoBox 11.4 ns 14.9 ns 31.1% slower ±2.1% / ±0.5%
player-engine.course.stitchNonstopCourse 281 µs 366 µs 30.1% slower ±0.4% / ±16.0%

Changed packages

app-play, player-ui, worker-play: 9 cases compared, median 0.1% slower.

All 9 cases
API Base Head Change Run spread (base / head)
player-ui.defineBeMusicElements 603 ns 604 ns 0.1% slower ±3.0% / ±8.1%
player-ui.formatPlaybackTime 43.1 ns 42.9 ns 0.5% faster ±0.6% / ±0.2%
player-ui.paintPlayfieldParts 58.9 µs 59.3 µs 0.7% slower ±0.6% / ±0.3%
player-ui.previewContentBottom 6.91 ns 6.94 ns 0.4% slower ±3.0% / ±3.2%
player-ui.resolvePlayfieldParts 2.20 µs 2.18 µs 0.7% faster ±0.5% / ±1.3%
player-ui.resolvePreviewInfoBox 11.4 ns 14.9 ns 31.1% slower 🔴 ±2.1% / ±0.5%
player-ui.resolvePreviewPortrait 13.3 ns 44.7 ns 236.3% slower 🔴 ±0.3% / ±4.8%
player-ui.resolveSeekTarget 6.28 ns 6.06 ns 3.5% faster ±19.8% / ±2.6%
player-ui.setBeMusicTheme 19.3 ns 19.2 ns 0.8% faster ±1.3% / ±0.3%

New exports (1)

API Head
player-ui.previewJudgementInset 7.39 ns
Within noise (19): past the threshold, but the runs overlap
API Base Head Change Run spread (base / head)
skin-beatoraja.scene.createBeatorajaJudgeStateGraph 4.66 µs 2.29 µs 50.8% faster ±48.3% / ±34.0%
player-node-audio.audio-sink.createBrowserAudioSink 4.75 µs 2.91 µs 38.7% faster ±28.9% / ±19.6%
player-browser.setMasterVolume 325 µs 249 µs 23.4% faster ±44.2% / ±37.8%
chart-parser.resolveBMSControlFlowWithDraws 7.16 µs 5.57 µs 22.2% faster ±12.9% / ±17.7%
chart-editor.deleteNote 5.24 µs 6.94 µs 32.6% slower ±7.6% / ±20.2%
chart-editor.addNote 6.62 µs 5.52 µs 16.7% faster ±16.1% / ±18.5%
shared-utils.workerize.invokeWorkerizedFunction 752 ns 632 ns 16.0% faster ±13.3% / ±15.1%
chart-model.createSpeedTimeline 32.1 ns 39.0 ns 21.3% slower ±7.1% / ±12.7%
player-engine.course.prepareNonstopCourse 120 µs 145 µs 21.0% slower ±6.6% / ±15.4%
chart-model.getPlayModeLayouts 12.7 ns 11.0 ns 13.0% faster ±31.5% / ±13.3%
chart-writer.stringifyBMS 49.2 µs 42.8 µs 13.0% faster ±9.3% / ±8.4%
player-engine.replay.resolveRulesetResultLamp 40.7 ns 46.4 ns 14.1% slower ±6.4% / ±12.5%

…and 7 more.

I/O-bound, not judged (19)

These cases touch the filesystem, so their time follows the OS cache and the disk more than the code.

API Base Head Change Run spread (base / head)
chart-audio-renderer.renderChartFile 6.38 ms 6.61 ms 3.6% slower ±1.7% / ±35.5%
chart-audio-renderer.renderJSON 3.82 ms 3.94 ms 3.2% slower ±3.5% / ±4.2%
chart-audio-renderer.renderSingleSample 8.11 µs 8.05 µs 0.8% faster ±0.4% / ±2.3%
chart-audio-renderer.writeAudioFile 163 µs 202 µs 23.5% slower ±17.6% / ±34.4%
chart-editor.exportChart 210 µs 219 µs 4.4% slower ±2.1% / ±5.9%
chart-editor.importChart 124 µs 134 µs 8.0% slower ±3.9% / ±6.8%
chart-editor.loadJSONFile 141 µs 142 µs 0.4% slower ±4.1% / ±2.8%
chart-editor.saveJSONFile 212 µs 234 µs 10.2% slower ±15.6% / ±5.8%
chart-parser.parseChartFile 116 µs 137 µs 17.4% slower ±11.9% / ±2.3%
player-browser.readFilesIntoBytesMap 4.66 µs 4.64 µs 0.5% faster ±3.2% / ±2.2%
player-terminal.createBgaANSIRenderer 3.26 µs 3.20 µs 1.6% faster ±3.1% / ±2.4%
player-terminal.loadStageFileANSIImage 101 ns 100 ns 0.9% faster ±1.0% / ±0.5%
player-terminal.loadStageFileANSILines 163 ns 164 ns 0.6% slower ±1.2% / ±0.5%
player-terminal.loadTerminalANSIImage 1.03 ms 1.06 ms 3.0% slower ±4.4% / ±2.3%
shared-utils.createFileLogger 196 µs 195 µs 0.5% faster ±2.4% / ±1.7%
shared-utils.readFilesIntoEntryMap 2.32 µs 2.30 µs 0.7% faster ±2.5% / ±0.5%
shared-utils.resolveFirstExistingPath 90.9 µs 92.2 µs 1.4% slower ±4.4% / ±3.6%
shared-utils.workerize.workerize 10.8 ms 10.8 ms ±0.0% ±0.6% / ±0.3%
skin-beatoraja.readFilesIntoBytesMap 19.9 µs 19.7 µs 0.9% faster ±2.4% / ±5.0%
Excluded: too fast to time (74)

A timed sample lasted 1 µs or less on at least one side (usually a base commit from before calls were batched), so its time is timer noise and no change is shown.

API Base Head
chart-model.createMeasureBoundariesBeats 72.0 ns 72.0 ns
chart-model.mirrorBeatAtTempoReversal 6.15 ns 6.21 ns
chart-model.parseBmsARGB 272 ns 264 ns
chart-model.parseBMSExBMP 608 ns 608 ns
chart-model.resolveChartMainBPM 107 ns 107 ns
player-browser.applyBeatorajaStretchRect 28.7 ns 28.4 ns
player-browser.checkBrowserCompat 159 ns 160 ns
player-browser.createRandomMixEntry 13.7 ns 13.5 ns
player-browser.destinationToSpriteProps 85.6 ns 85.6 ns
player-browser.GameplayRecorder 150 ns 78.0 ns
player-browser.SceneController 248 ns 256 ns
player-browser.setBrowserWorkerCount 38.4 ns 38.4 ns

…and 62 more.

Run details
Measure Value
Median change (all compared cases) -0.03%
Mean change -0.05%
Overall verdict (median vs. threshold) unchanged
Compared / within noise / I/O-bound / unchanged 888 / 19 / 19 / 847
Benchmarked / skipped (head) 963 / 38
Time / warmup per case 50 ms / 25 ms
Node / platform v26.12.1 / linux

@nulltask
nulltask merged commit e665fc8 into devel Oct 31, 2026
9 checks passed
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.

1 participant