I used to stream my PC to my phone with Artemis clients, and the same things kept bugging me. I had to pick one bitrate up front and hope it held: too high and it stuttered the moment someone used the Wi-Fi, too low and everything turned to mush. When it did stutter, the overlay showed numbers but never said whether the network, the phone's decoder or my PC was to blame. A 50 fps game juddered on a 120 Hz screen. My phone got hot and throttled halfway through a session with some of its settings, and nothing in the app reacted. Fast phones were treated like any other phone, so the decoder in a recent Snapdragon never got pushed. And the extras I liked worked with one host and quietly did nothing on another.
So I built Nightjar, with one goal: get the best stream your phone or android handheld, your network and your host can actually deliver, measure instead of guess, and tell you plainly when something is holding it back. It's a free, open-source (GPL-3.0) Android client for Sunshine, Apollo, Vibepollo, Rubylight and any other Moonlight-compatible host.
Demo (69 s): https://ramazankara.github.io/nightjar/#demo Download (APK) and source: https://github.com/RamazanKara/nightjar
1. Automatic bitrate and quality You don't pick a bitrate and hope. Nightjar watches packet loss, jitter and how much headroom your phone's decoder has left, and moves the bitrate anywhere up to 2000 Mbps where the host allows it. It drops fast when the link gets worse and climbs back slowly once it's healthy, so it doesn't bounce. Automatic quality goes a step further and changes resolution and frame rate mid-stream toward the goal you pick: smooth motion, sharp detail or battery life. Both back off before your phone gets hot enough to throttle. On any host you can still set the bitrate yourself, also up to 2000 Mbps.
2. Android 16 adaptive refresh (ARR) On phones with Android 16's adaptive refresh, the screen follows the game's actual frame rate instead of a fixed 60 or 120 Hz. A game running at 50 or 72 fps is shown at that cadence, without the judder of frames landing between refreshes. Hosts that support VRR (Rubylight, Vibepollo) are asked to pace frames to the game too, and also told how long each frame waits for your screen so it can time them. Other phones fall back to their maximum refresh rate.
3. Decoding tuned for your phone's chip Nightjar asks the hardware decoder which low-latency settings it really supports and turns those on, across Qualcomm, Samsung Exynos and Google Tensor, MediaTek, Kirin and NVIDIA. On Snapdragon 8 Gen 2 and newer, frames are released through a faster fence instead of waiting on the default one. Once per phone it benchmarks each codec on a short game-like clip, so Automatic picks the one that decodes fastest on your device, not just the one it supports. At very high bitrates the decoder gets input buffers big enough for the largest frames, so the stream doesn't fall over at 1 Gbps. The overlay shows which settings the decoder accepted and its decode time, so you can see the effect yourself.
4. Upscaling on the phone Stream at 720p to a 1080p or 1440p screen and let the phone's GPU rebuild the detail with AMD FSR or Qualcomm's Snapdragon GSR. Fewer pixels go over Wi-Fi and through the decoder, so you get a lower bitrate, less decode time and less heat for a picture that still looks sharp. Sharpening is adjustable, and if the GPU gets overloaded it switches back to plain output instead of dropping frames.
5. PyroWave, decoded on the GPU (Only with PyroWave enabled Hosts). PyroWave is a wavelet codec built for the lowest decode time at high bitrates on a fast LAN. Nightjar decodes it in Vulkan, including full 4:4:4 colour for sharp desktop text. Decoding and display run on separate threads, so a new frame never waits behind one the screen hasn't shown yet. A lost packet only affects its own part of the picture instead of smearing the frame until the next keyframe. Upscaling runs in the same pass, and on Snapdragon phones you can load a newer Adreno driver for extra speed, with an automatic fallback to the system driver. Nightjar also tells the host your wired link speed and can calibrate a loss-free frame pace, and it warns you when the bitrate is below what PyroWave needs. Needs a 64-bit phone with Android 10+ and Vulkan 1.3.
6. Host telemetry, and why it stuttered (only on supported hosts). The overlay can show your PC's CPU load and GPU usage, temperature and power next to your phone's numbers, so when frames drop you can see whether the PC was maxed out. The default overlay is one line: FPS, round trip, loss and a dot that turns amber or red. A "why did my stream stutter?" view points at the network, the decoder, the host, the display or heat.
Also in there:
- Controllers and voice. A USB DualSense gets adaptive triggers, rumble, lightbar and Edge paddles on any host, plus waveform haptics and its own speaker and mic (only on supported hosts). Your android's mic can go to the PC for voice chat. Xbox USB controllers, Switch Controllers work through a built-in driver. Integrated Keyboard with combined trackpad fully customizable and includes shortcut function like task manager.
- Configure your Virtual Display Pick per PC whether the stream gets its own virtual display at your phone's resolution. You can also choose what happens to your monitors: the virtual display alone, extended beside them, made primary, or the physical display. Remote Monitor watches a PC without taking over its input, and Input-only controls it with no video. Clipboard sync, host commands and one-time-PIN pairing.
- Touch and on-screen controls. A natural trackpad with acceleration and glide, a Local cursor drawn on the phone, or touch off for controller play. Per-game on-screen controls with keys, buttons, sticks, triggers and a D-pad, in an editor with grid snapping, and you can import your Artemis layouts.
- Stream it your way. Fit, Fill, Stretch or 1:1 scaling, portrait streams and rotate-with-device. Named profiles that switch by network, per-game settings and a mobile data bitrate cap. Quick resume from the PC list, and an opt-in setting that rides out network drops of up to 60 seconds instead of ending the stream.
- More controllers. A controller test page, an opt-in USB driver for the Switch Pro Controller, and rumble off.
- play away from home. A built-in Tailscale guide that tests the connection and shows whether it runs direct or through a relay.
- Tools for tinkerers. An input-to-screen latency test, a decoder benchmark that runs without a PC, frame timings as CSV, and device results you can share to a public table of how phones perform. The stream doctor also spots stutters that repeat on a steady beat and shows your Wi-Fi band, signal and link speed.
- 15 languages.
- No switches that do nothing. Nightjar reads what your host supports and only shows options that work there. If something needs a host setting or update, it says which one.
- Updates itself. It checks GitHub for new releases and installs them after verifying the checksum, so a sideloaded install doesn't go stale.
- Launcher Support. supports ES-DE, Daijisho and many other launchers! Configure it once on your launchers and never see it again.
- wide range of compatibility. TV Aware Interface Android TV integration and Remote Control navigation, Handhelds, TV Boxes, Fire TV Sticks, Phones.. you name it. Made for all Androids.
- Lightweight 30 MB Disk usage and nearly no RAM when idling. On max GPU Clocks on and Pyrowave it will sweat your GPU though.
No ads, no analytics, no accounts.
About the Host-only parts: I don't want the best features to depend on which host you run. I'm reaching out to the other host projects about supporting automatic bitrate, host telemetry, the mic and PyroWave-specific optimizations, and about one shared way for hosts to report what they support, so any client can use these extras with any host. Until then, Nightjar works with whatever your host offers today.
“Great, another Android client.” I get it. But this isn’t a reskin with a new icon. The six things at the top don’t exist in the other clients, and I’m not trying to lock anyone in: where a host can do more, I’d rather it become a shared standard every client can use. If your current client already does everything you want, keep using it. If you’ve hit the same walls I did, give it ten minutes.
It's an early release, so expect some rough edges. If something breaks, Settings → App → Report a problem creates a log you can attach to an issue, and I read every one. I'd especially like to hear how ARR, upscaling and the decoder tuning work on your phone. If there's a feature you're missing, tell me here or open an issue, and pull requests are welcome.
Input latency demonstration and Stats example are in the comments!