A SwiftUI iOS app for searching and playing YouTube videos with local subscriptions and a mini player.
- Video / channel / playlist search
- Full-screen playback screen with AVKit
- Mini player pinned above the tab bar
- Local channel subscriptions (JSON-backed, on-device)
- Subscription feed of recent uploads
- Background audio and Picture-in-Picture (within iOS limits)
- SwiftUI + AVFoundation / AVKit
- XcodeGen (
project.yml) - InnerTube-based YouTube extractor with an ANDROID_VR → ANDROID → IOS client waterfall
- Optional Piped fallback (multi-instance)
- Local
AVAssetResourceLoaderDelegateHLS proxy for on-the-fly n-param decoding
- Xcode 15+
- iOS 16+
- XcodeGen
- Generate the project:
xcodegen generate
- Open
YourPipe.xcodeproj. - Build and run the
YourPipetarget.
YourPipe/YourPipeApp.swift— app entry, environment wiringYourPipe/ContentView.swift— tab shell and mini player barYourPipe/PlaybackController.swift— AVPlayer orchestration, PiP, Now Playing, stream-refresh recoveryYourPipe/PlaybackResolver.swift— cached resolver with inflight deduplication and first-byte warmupYourPipe/YouTubePlaybackService.swift— InnerTube client waterfall, n-param JS decoder, client cooldown / backoff, optional poToken hookYourPipe/HLSProxy.swift— HLS playlist rewriter for throttling parameter decodingYourPipe/YouTubeSearchService.swift— search / channel / feed parsing via InnerTubeYourPipe/SubscriptionStore.swift— on-disk subscription persistenceYourPipe/AppSettingsStore.swift— playback-source preference
Selectable from the in-app Settings tab:
- Direct YouTube — InnerTube clients only.
- Piped proxy — community Piped instances only.
- Auto — tries Direct first, falls back to Piped on failure.
The direct path follows techniques used by NewPipe/yt-dlp to reduce rate-limit and LOGIN_REQUIRED responses:
- Sequential client waterfall with randomised jitter between attempts (no parallel bursts from a single IP).
- Per-client cooldown with exponential backoff on 403 / 429 / anti-bot
statuses, honouring
Retry-After. - Device-locale-based
hl/gl/ UTC offset (no hard-codeden/US). - Lazy
visitorDatafetch — no cold-start request on app launch. - Mid-playback 403 recovery: a fresh resolve with position-restore before any user-visible error is surfaced.
- Optional
PoTokenProviderprotocol; when a provider is installed the service appendspot=to stream URLs.
Client versions and n-param patterns should be re-synced periodically against upstream references:
- yt-dlp —
yt_dlp/extractor/youtube/_base.py(INNERTUBE_CLIENTS) - NewPipeExtractor —
YoutubeParsingHelper.java,YoutubeThrottlingParameterUtils.java
- MVP-quality codebase, actively iterated on.
- Playback strategies depend on YouTube-side changes and may require recurring fixes. Treat the extractor layer as maintenance code.