Skip to content

fix(macos): playback, crossfade decipher, packaging, adblocker, dev icon#4390

Open
perlytiara wants to merge 3 commits into
pear-devs:masterfrom
perlytiara:fix/macos-arm-playback-crossfade-packaging
Open

fix(macos): playback, crossfade decipher, packaging, adblocker, dev icon#4390
perlytiara wants to merge 3 commits into
pear-devs:masterfrom
perlytiara:fix/macos-arm-playback-crossfade-packaging

Conversation

@perlytiara

@perlytiara perlytiara commented Mar 28, 2026

Copy link
Copy Markdown

Summary

This PR bundles fixes and improvements developed and verified on Apple Silicon (macOS, darwin 25.3.0): silent playback after Web Audio suspend, crossfade/downloader crashes after a youtubei.js player update, Ghostery-based ad/tracking blocking (no broad first-party allowlists that bypass ads), Trusted Types compatibility in the renderer, correct window icon in dev, and arm64 DMG packaging.

Environment (author)

  • OS: macOS (darwin 25.3.0)
  • Device / arch: Apple Silicon (ARM64)
  • Build verified (latest on branch): pnpm typecheck, pnpm build, pnpm dist:mac:arm64 — DMG: pack/YouTube Music-3.11.0-arm64.dmg (not committed; local artifact only)

Changes

Playback (macOS / Web Audio)

  • Renderer: resume AudioContext on visibility, focus, play, user input, and IPC peard:resume-audio-context.
  • Renderer follow-up: on timeupdate while the video is playing, retry resume() if the context is still suspended (avoids “silent audio, picture still moving”). Also pageshow when returning from bfcache.
  • Main: send that IPC on window focus / show; set backgroundThrottling: false on the BrowserWindow so timers/media scheduling stay steadier in the background.

Trusted Types (YouTube Music)

  • New src/trusted-types-function-shim.ts, imported first from renderer.ts: registers a small Trusted Types policy and proxies Function / new Function so the function body is passed through createScript, satisfying Chromium when YT Music enforces Trusted Types (fixes console errors like “TrustedScript assignment” / Function constructor blocked).

Crossfade / audio-url (exportedVars.nFunction is not a function)

  • Bump youtubei.js to 17.0.1.
  • Downloader Platform.shim.eval: execute the script YouTube.js emits via new Function(data.output)(), matching v17 output (no separate nFunction wiring).
  • Crossfade: wrap getStreamURL in try/catch; if there is no URL, restore <video> volume when it was left at 0 after a failed transition.

Adblocker + session hooks

  • New plugin src/plugins/adblocker/: Ghostery @ghostery/adblocker-electron, engine cache at userData/adblocker-engine.bin.
  • Ensure removeContentSecurityPolicy() runs before initHook / loadAllMainPlugins so webRequest wrapping stays compatible with blocking (per comment in index.ts).
  • No merged @@ allowlist for music.youtube.com / pagead / broad youtubei: earlier attempts whitelisted ad and ad-adjacent endpoints (e.g. www.youtube.com/pagead, all of youtubei), which allowed ads again. The engine stays prebuilt ads + tracking only, plus optional additionalBlockLists in plugin settings for power users.

Dev experience

  • Window icon: resolve BrowserWindow icon to an absolute path (try app.getAppPath(), cwd, then repo-relative from bundled main) so electron-vite preview shows the real app icon instead of the default Electron icon.
  • Login item: wrap setLoginItemSettings in try/catch; in dev, log a short warning when the OS denies login-item changes.

macOS packaging

  • Add committed assets/generated/icons/mac/icon.icns and point electron-builder at it so arm64 DMG builds work without relying on Xcode 26 actool .icon issues.

Misc

  • Strict TypeScript fixes: websocket route typing, auth-proxy Buffer, skip-silences analyzer callback.

Notes

  • Code signing: local dist:mac:arm64 was built with signing identity unset (expected for local builds); release pipelines should still use your usual signing/notarization setup.
  • DMG is a local build output under pack/; it is not part of the git diff.
  • Push is from fork perlytiara/pear-desktoppear-devs/pear-desktop (no direct push permission on upstream).

Prepared with assistance from Cursor.

user added 3 commits March 28, 2026 08:32
- Resume Web Audio (renderer + main IPC) and disable background throttling to reduce silent playback on macOS ARM after suspend/background.

- Bump youtubei.js to 17.x and align downloader Platform.shim.eval with v17 script output (fixes crossfade audio-url TypeError: nFunction is not a function).

- Call removeContentSecurityPolicy before initHook/loadAllMainPlugins so session webRequest wrapping stays compatible with adblocker blocking.

- Add adblocker plugin (Ghostery) with cached engine under userData.

- Resolve BrowserWindow icon to an absolute path so dev/preview shows the app icon, not the default Electron icon.

- Wrap setLoginItemSettings in try/catch for dev environments where login items are not permitted.

- macOS packaging: committed icon.icns and electron-builder target path for arm64 DMG builds without Xcode 26 actool issues.

- Misc strict TS fixes (websocket cast, auth-proxy Buffer, skip-silences analyzer).

Tested on: macOS (darwin 25.3.0), Apple Silicon (ARM64), pnpm dist:mac:arm64.

Made-with: Cursor
…owlist

- Install pear-dynamic-script policy and proxy Function so new Function(string) works under YT Music Trusted Types (stops console blocks / broken dynamic code).

- Resume AudioContext on timeupdate while playing and on pageshow after bfcache to reduce silent-audio with video still advancing.

- Adblocker: merge @@ allow rules for first-party music.youtube.com youtubei/stats/ptracking/generate_204 and play.google.com log (and pagead on YTM) so ERR_BLOCKED_BY_CLIENT does not hit player-critical calls.

- Crossfade: try/catch getStreamURL; restore video volume if URL missing so we do not stay muted after a failed transition.

Verified: pnpm typecheck, pnpm build, pnpm dist:mac:arm64 (Apple Silicon).
Made-with: Cursor
Remove merged @@ rules (pagead, broad youtubei, etc.). Ghostery prebuilt ads+tracking only, plus optional additionalBlockLists.

Made-with: Cursor
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