Lyrenne for iPad: a free YouTube Music player for iPad with synced lyrics, ad-free, sideloaded with xtool
翻译准备中
正在加载完整 README。
查看完整 README ↗A personal, sideloaded iPad port of Lyrenne, the YouTube Music desktop player. SwiftUI + AVPlayer, built with xtool.
Ported from Lyrenne 81ac0ac (2026-10-25).
Made by Andrei (Doctordefector) with love <3
Artist - Title [id].m4a (the id is
how the app finds them; deleting one there removes the download)Left out on purpose: Discord, Last.fm, hosting a Listen Together room, equalizer, crossfade.
| Path | What |
|---|---|
Sources/LyrenneCore/ | Foundation only, no UI, builds on Linux too. InnerTube.swift (search, radio, stream URLs), Browse.swift (home, artist pages, search filters, suggestions), Account.swift (signed-in calls, session refresh), Downloads.swift (fetching audio, offline files), Lyrics.swift (lrclib), Romanize.swift (romanized lyrics: the system's Japanese tokenizer and transliteration, Korean by hand), ListenTogether.swift (guest client, hand-rolled protobuf for desktop's listentogether.proto) |
Sources/Lyrenne/ | The iPad app: Player.swift (queue, AVPlayer, lock screen), Library.swift (sign-in, Keychain, library, playlists), LyricsTweaks.swift (per-song lyrics timing and edits, in UserDefaults), DownloadsView.swift, TogetherView.swift (Listen Together room), Browse.swift (home, shelves, artist page), LyrenneApp.swift (layout, search, now playing, lyrics) |
Sources/lyrenne-check/ | Live end-to-end check of the core: search, radio, lyrics, per-client stream report, download, 500-song playlist paging; with LYRENNE_COOKIE set, the library too |
Info.plist | Merged by xtool: iPad-only family, background audio |
Resources/AppIcon.png | App icon, desktop's lyre (icon-small.svg) full-bleed at 1024 px |
.github/workflows/ipa.yml | Builds the unsigned .ipa, and runs the app on an iPad simulator with screenshots |
Google's sign-in page in a web view, the same flow as upstream Android. The resulting cookie is
kept in the Keychain. Google rotates session cookies and a stored copy dies within weeks unless the
rotated ones are folded back, so every launch loads music.youtube.com with it, reads LOGGED_IN, and
merges the new cookies (desktop's AuthManager.refreshSession). An expired session says so and asks
you to sign in again; being offline keeps the login.
visitorData sent like desktop. The check before using a URL probes the file's
last byte; desktop's first-byte check passes the truncated URLs.When playback breaks: run swift run lyrenne-check and read its client ... lines, then compare
streamClients in InnerTube.swift with desktop's YouTubeClient.kt / ContentAwareFallbackStrategy.kt.
The app's error under the player also lists each client's reason.
Same server (wss://metroserverx.meowery.eu/ws) and messages as desktop's listentogether/.
The iPad only joins: it sends join_room, follows sync_playback / sync_state, and sends
buffer_ready once the host's song has loaded so the host can start everyone together.
lyrenne-check decodes a sample message and, on macOS, joins a made-up room and expects the
server's "Room not found" (Linux Foundation has no WebSockets, so that part is skipped there).
以上为 README 的开头部分。其余内容请阅读原文。 查看完整 README ↗