Repository navigation
feat(player): add media session controls and honor playback defaults - #411
Merged
Merged
Conversation
Deploying podnotes with
|
| Latest commit: |
2076d8e
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://d99f26b2.podnotes.pages.dev |
| Branch Preview URL: | https://feat-media-session.podnotes.pages.dev |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PodNotes publishes the episode title, podcast, artwork, and playback position to the main window's Media Session. Play, pause, configured backward and forward skips, seek-to, fixed 30-second next-track, and previous-track timestamp capture use the player. Empty selection and plugin unload clear the session. Popouts keep the main window's single registration.
The player remembers one volume across episodes and restarts, including changes through
api.volume. The Settings Default Volume slider now changes playing audio immediately. Default Playback Rate applies when a different episode loads. Reloading the shown episode preserves its live speed, including restored first play, error retry, source replacement, and replay after the episode ends. A live speed change never overwrites the saved default.Fixes #350. Android's portion is closed as unsupported by Obsidian's WebView, with sources below.
Verification
origin/master:npm run lint,npm run format:check,npm run typecheck,npm run build,npm run test, andnpm run docs:build. 1,712 tests across 98 files; 18 docs pages and 112 legacy fragments pass.npm run test:e2epasses all 72 tests across 11 files in real Obsidian 1.13.7 on Linux. The first run had a checkpoint timeout and a mismatch between the reused vault's 7/11-second skip settings and the test's expected 15/15. The final fresh-vault run passes all 72 with recorded command exit 0. The report retains the earlier fixture failures and terminal-wrapper exit 143.npm run sizepasses at 284,862 raw bytes and 90,640 gzip bytes, 807 gzip bytes above the brief's 89,833-byte baseline, including upstream fix: make podcast name lookups exact and safe #413.Android
Obsidian's Android WebView does not support Media Session. Android 14 emulator, Obsidian mobile 1.14.4 (versionCode 389), Android System WebView 113.0.5672.136. Inside Obsidian, both
navigator.mediaSessionandMediaMetadataare undefined in a secure context.npm run --silent mobile:verifypassed before the V-411 volume and speed correction. The Android player passed in-app play/pause and configured skips on that build. The Media Session adapter is unchanged by the correction; Android was not rerun for it.This is a platform restriction. MDN browser-compat-data records
webview_android.version_added: false; Navigator and MediaMetadata data agree. Chrome Platform Status lists Chrome Android 57 and desktop 73 with no WebView milestone. Chromium source explicitly setskDisableMediaSessionAPI, explaining that WebView has no metadata/control UI; issue 40611412 tracks WebView support. No supported newer WebView was found, so an APK update cannot remove this intentional restriction and was not attempted. No native bridge is included.A separate plain
<audio>played the local 60-second, 8 kHz mono WAV while locked. Android recorded Obsidian as an audio client but nomd.obsidianmedia session or notification. Playback probes and Android service dumps are the primary evidence; the screenshots show no card on the actual lock screen or notification shade. The shade screenshot has no simultaneous playback reading.iOS: expected, not verified
This Linux host has no iOS simulator. MDN Navigator compatibility data records Safari/iOS 15 support for
navigator.mediaSessionand mirrors it towebview_ios. WebKit enables MediaSession by default and builds it on Cocoa except watchOS. WKWebView API availability is expected on iOS 15+, but Obsidian's background playback, lock-screen controls and headset behavior remain unverified.Release impact
No schema, API signature, or migration change. Saved volume and its documented API persistence remain compatible. Settings import applies volume immediately; imported default speed applies when a different episode loads. Remappable media actions and headset-capture feedback remain follow-ups. Physical media keys and headsets remain unverified; Linux native controls were verified through MPRIS. The OS does not route controls before the first playback after startup, as on master.
Docs at release
No docs files change in this PR. Apply these updates when the feature is released:
mobile.md. Document all seven actions. State that Android Obsidian has no Media Session controls or previous-track capture because its WebView disables the API. Label iOS lock-screen and headset behavior expected, not verified.api.md. Retain the existing statement that setting volume updates saved Default Volume. Explain that live speed lasts until a different episode loads and never overwrites Default Playback Rate.settings.md, Playback table. Default Volume changes live audio and remains the one remembered volume. Default Playback Rate applies at startup and when a different episode loads; same-episode reloads preserve live speed.sync.md. Keep volume as a saved preference. Explain that current speed remains unsaved, while the saved default applies to different episodes.import_export.md, Import your settings. Imported volume applies immediately. Imported default speed applies on the next different episode, leaving the shown episode's speed unchanged.Note
Add Media Session controls and honor playback volume/speed defaults
bindMediaSessionin mediaSession.ts. It registers OS/lock-screen controls for play, pause, seeking, skipping, and timestamp capture, and reports episode metadata, playback state, and position. Unsupported or throwing browser calls are isolated and do not reach player state subscribers.PlayerController.setVolumeinstead of writing settings directly (PodNotesSettingsTab.ts).Macroscope summarized 2076d8e.