Unofficial Moonlight port (Sunshine/GameStream game-streaming client) for jailbroken PS4 (GoldHEN), built on the OpenOrbis toolchain.
Full port plan: PLAN.md.
Current version: 1.1.0
Playable client for jailbroken PS4 (GoldHEN / FW 9.00 validated):
- Pairing, applist, launch, and H.264 streaming against Sunshine
- Audio (Opus +
sceAudioOut) - Software video (FFmpeg) and hardware decode (
libSceVideodec2,prefer_hw) - DualShock 4 input (
scePad) - On-console UI (APPS / SETTINGS + on-screen keyboard) and INI config
- Installable
.pkg(CATEGORY=gd) - Optional performance overlay and Videodec2 / BGRA tuning knobs
- Keyboard and mouse support
- mDNS host discovery
- Native YCbCr/NV12 presentation on
sceVideoOut
Full port plan and longer backlog: PLAN.md. Validation notes: docs/CONSOLE_VALIDATE.md.
- Linux x86_64 with
clang,ld.lld,cmake,ninja,git, andcurl - OpenOrbis toolchain v0.5.4 (default:
~/ps4dev/OpenOrbis/PS4Toolchain) - Cross-built FFmpeg for PS4 (H.264 decoder only):
scripts/build_ffmpeg_ps4.sh - For
PkgTool.Core:libssl.so.1.1/libcrypto.so.1.1in~/ps4dev/hostlibs/usr/lib - PS4 with GoldHEN-compatible firmware (plan validated on 9.00)
- Host PC running Sunshine
Vendored libraries live as git submodules pinned in third_party/DEPS.
Git only stores the commit SHA for each submodule — not a full copy of upstream.
Orbis-specific fixes are not committed inside those repos; they live under
patches/ and are applied after checkout.
git clone <this-repo>
scripts/setup_deps.sh # checkout pins from third_party/DEPS + apply patches/Equivalent manual flow: git submodule update --init --recursive then
scripts/apply_patches.sh. After patches, third_party/* working trees look
dirty — that is expected; commit patch files, not submodule dirt.
To bump a dependency on purpose: edit the pin in third_party/DEPS, update the
submodule to that commit, refresh patches if needed (scripts/refresh_patches.sh),
and commit the new gitlink + DEPS (+ patches).
git clone <this-repo>
cd moonlight-ps4
scripts/setup_deps.sh # pinned third_party + Orbis patches
scripts/build_ffmpeg_ps4.sh # once (→ ~/ps4dev/ffmpeg-ps4)
# PS4 app + .pkg (sources env.sh, configures, builds, packages)
scripts/build_pkg.sh
# scripts/build_pkg.sh --clean # wipe build-ps4/ and reconfigure
# Optional: Linux development CLI (pairing / H.264 dump)
cmake -B build-host -G Ninja && cmake --build build-hostInstallable artifact: build-ps4/Moonlight-1.1.0.pkg
(also IV0000-MLNT00001_00-MOONLIGHTPS40000.pkg).
build_pkg.sh runs source scripts/env.sh itself. Manual CMake equivalent:
source scripts/env.sh
cmake -B build-ps4 -G Ninja -DCMAKE_TOOLCHAIN_FILE=cmake/openorbis.cmake
cmake --build build-ps4- Install the
.pkg(Package Installer / GoldHEN / FTP). The package usesCATEGORY=gd(required so GoldHEN injects plugins). - Optional — YCbCr presentation (
prefer_ycbcr=true, experimental):
- Copy
plugin/bin/ycbcr_unlock.prx→/data/GoldHEN/plugins/ - Add
[MLNT00001]in/data/GoldHEN/plugins.ini(see[plugin/README.md](plugin/README.md)andplugin/plugins.ini.example) - GoldHEN → Enable plugins
- After each reboot, send the kpayload once:
nc -w 3 <PS4_IP> 9090 < plugin/bin/ycbcr_kpatch_900.bin
- On first launch the app opens the SETTINGS menu if no host is set. You can
also create
/data/moonlight/moonlight.iniover FTP (seepkg/assets/misc/moonlight.ini). Optional:debug_host.txtwith your PC IP. - Start Sunshine on the PC. On first pair the app shows a PIN (also written to
/data/moonlight/pin.txt); enter it athttps://<pc>:47990/pin. - Logs on the PC:
nc -ulk 9999(or enable file log in SETTINGS →/data/moonlight/debug.log). - In the menu: X/O start app, L1/R1 switch APPS/SETTINGS, OPTIONS quit active Sunshine session, OPTIONS + Touchpad (~1 s) exit stream.
| Setting | Default |
|---|---|
| Resolution / FPS | 1920×1080 @ 60 |
| Bitrate | 20 Mbps, H.264 |
prefer_hw |
true (Videodec2) |
prefer_ycbcr |
false (BGRA path; correct colors, SSE2 multi-thread convert) |
| Title ID | MLNT00001 |
Mean decode/convert/present times are printed every second over UDP.
Validation protocol: [docs/CONSOLE_VALIDATE.md](docs/CONSOLE_VALIDATE.md).
Isolated Videodec2 spike: videodec2_spike = true in the INI.
./build-host/moonlight-cli pair 192.168.1.100
./build-host/moonlight-cli list 192.168.1.100
./build-host/moonlight-cli stream 192.168.1.100 --res 1280x720 --time 20
./build-host/moonlight-cli quit 192.168.1.100cmake/openorbis.cmake CMake toolchain for PS4
pkg/ package assets (icon0, sce modules)
scripts/ env, cross FFmpeg, .pkg packaging
src/
main.c stream.c config.c orchestration + INI config
ui/ on-console menu (APPS / SETTINGS + OSK)
gamestream/ pairing/HTTP/XML over mbedTLS
audio/audio_orbis.c Opus + sceAudioOut
video/renderer_videoout.c YCbCr/NV12 or BGRA presentation (sceVideoOut)
video/nv12_blit.c 1088→1080 copy (WB_GARLIC / Onion alias)
video/decoder_ffmpeg.c H.264 software (FFmpeg)
video/decoder_orbis.c H.264 hardware (libSceVideodec2)
gamestream/sps.c SPS fixup (num_ref_frames=1)
input/input_pad.c DualShock 4
orbis/ VideoOut / Videodec2 / net helpers
host/main_cli.c Linux development CLI
plugin/
ycbcr_unlock/ GoldHEN PRX (1.63) for YCbCr VideoOut
ycbcr_kpatch/ FW 9.00 kernel kpayload (BinLoader)
kernel_dumper_900/ kernel dump helper for RE
docs/ console validation + kernel YCbCr RE notes
third_party/
DEPS pinned tags/SHAs (lockfile for setup_deps.sh)
moonlight-common-c protocol engine (submodule + Orbis patches)
mbedtls crypto (v3.6.4)
opus audio
h264bitstream SPS rewrite
patches/ Orbis patches applied by scripts/apply_patches.sh
scripts/setup_deps.sh checkout pins + apply patches
scripts/apply_patches.sh
scripts/refresh_patches.sh regenerate patches after local dep edits