mirror of
https://github.com/fstat13/PSCapture.git
synced 2026-10-17 12:00:39 +02:00
docs: redesign the guide site, fix inaccurate docs
- new modern layout for index.html / index.it.html with shared style.css + main.js: app-window mock, pipeline diagram, searchable troubleshooting, copy buttons on build commands, live star count - stream port is 5599 (not 9xxx); real log line is "ERRORE caricamento dll"; button label is STOP - troubleshooting covers more real log lines (UAC refused, pldmgr missing, elfldr unreachable, stream dropped) - links to .md guides point to GitHub, download goes to /releases (v0.1 is a pre-release, /latest would miss it)
This commit is contained in:
1 parent
07fe4968da
commit
876f8ef82b
7 files changed
+1304
-627
No files matched your search
@@ -83,7 +83,7 @@ payload/ PS5 side: display-engine reader + NV12 streamer (pscapture.elf)
|
||||
pc/ PSCapture.exe — GUI + installer + payload deployer + feeder
|
||||
pc/ps5cam.c the virtual capture-card driver (DirectShow source filter)
|
||||
pc/shm.h shared-memory contract between feeder and driver
|
||||
docs/ guides: HTML, fool-proof step-by-step, build, installer, RE, log
|
||||
docs/ guides: HTML, step-by-step, build, installer, RE, log
|
||||
```
|
||||
|
||||
## 🔧 Build
|
||||
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
# PSCapture — la guida a prova di scemo
|
||||
# PSCapture — la guida passo-passo completa
|
||||
|
||||
Da zero alla tua PS5 dentro Discord. Ogni passo dice esattamente cosa devi
|
||||
vedere sullo schermo. Se qualcosa non torna, salta alla tabella dei problemi
|
||||
@@ -47,7 +47,7 @@ per Windows sono dentro di lui.
|
||||
| `driver gia' installato` | la camera è già registrata — ok |
|
||||
| `driver estratto dall'eseguibile (… byte)` + `driver registrato - la webcam 'PS5 Capture' e' pronta` | primo avvio: driver installato |
|
||||
| `payload dall'eseguibile (… byte)` + `payload avviato - la PS5 deve mostrare la notifica PSCapture` | il payload sta girando sulla console |
|
||||
| `porta stream: 9xxx` poi `collegato a 192.168.0.36:9xxx` | stream connesso |
|
||||
| `porta stream: 5599` poi `collegato a 192.168.0.36:5599` | stream connesso |
|
||||
| la pillola diventa **verde**: `STREAMING - scegli 'PS5 Capture' in Discord` | sei live |
|
||||
|
||||
5. Sulla PS5 compare la notifica di sistema: **PSCapture is streaming on:PORT**.
|
||||
@@ -74,7 +74,7 @@ Qui va alla piena risoluzione **1920x1080**.
|
||||
payload è già sulla console (autoloader) lo stream parte subito; se la
|
||||
console è spenta la pillola dice *"IN ATTESA DELLA PS5"* e si connette nel
|
||||
momento in cui la console è pronta.
|
||||
- Premi **Stop** (o chiudi l'app) per fermare lo stream. La camera si congela
|
||||
- Premi **STOP** (o chiudi l'app) per fermare lo stream. La camera si congela
|
||||
sull'ultimo frame; gli altri programmi continuano a vedere il dispositivo.
|
||||
- **Deploy payload** rimanda il payload a mano (utile dopo un riavvio della
|
||||
console senza autoloader). **Install driver** riregistra la camera a mano
|
||||
@@ -98,7 +98,7 @@ Entrambe si applicano in diretta (circa un secondo) e sono salvate in
|
||||
| Il log ripete `PS5 non raggiungibile (...), riprovo` | come sopra | come sopra |
|
||||
| La camera `PS5 Capture` non appare in Discord/OBS | driver mai registrato (install fallito) | premi **Install driver**; leggi la riga di log che segue — ora riporta l'errore *vero* |
|
||||
| Log: `ERRORE: driver non scrivibile in C:\Program Files\PSCapture (serve admin?)` | app non elevata | chiudi e riavvia `PSCapture.exe` accettando il prompt UAC |
|
||||
| Log: `ERRORE caricando la dll (err=126)` | l'antivirus ha messo in quarantena la dll estratta | controlla la quarantena dell'antivirus per `pscapture.dll`, sbloccala, premi di nuovo **Install driver** |
|
||||
| Log: `ERRORE caricamento dll (err=126)` | l'antivirus ha messo in quarantena la dll estratta | controlla la quarantena dell'antivirus per `pscapture.dll`, sbloccala, premi di nuovo **Install driver** |
|
||||
| La camera appare ma l'immagine è nera | stream non partito | controlla la pillola; premi **Deploy payload** e/o **START STREAMING** |
|
||||
| I colori sembrano sbagliati (pelle rossastra, cielo arancione) | qualcuno ha toccato `gain` | rimetti `gain` a `1.0` → Apply |
|
||||
| Immagine decentrata / barra nera | allineamento | regola `shift px` con numeri pari finché non è centrata |
|
||||
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
# PSCapture — the fool-proof guide
|
||||
# PSCapture — the complete step-by-step guide
|
||||
|
||||
🇮🇹 Versione italiana: [GUIDE.it.md](GUIDE.it.md)
|
||||
|
||||
@@ -46,7 +46,7 @@ the Windows capture-card driver are inside it.
|
||||
| `driver gia' installato` | camera already registered — fine |
|
||||
| `driver estratto dall'eseguibile (… byte)` + `driver registrato - la webcam 'PS5 Capture' e' pronta` | first run: driver installed |
|
||||
| `payload dall'eseguibile (… byte)` + `payload avviato - la PS5 deve mostrare la notifica PSCapture` | the payload is now running on the console |
|
||||
| `porta stream: 9xxx` then `collegato a 192.168.0.36:9xxx` | stream connected |
|
||||
| `porta stream: 5599` then `collegato a 192.168.0.36:5599` | stream connected |
|
||||
| status pill turns **green**: `STREAMING - scegli 'PS5 Capture' in Discord` | you're live |
|
||||
|
||||
5. The PS5 shows a system notification: **PSCapture is streaming on:PORT**.
|
||||
@@ -72,7 +72,7 @@ This runs at the full **1920x1080**.
|
||||
itself: if the payload is already on the console (autoloader) the stream
|
||||
starts by itself; if the console is off the pill says
|
||||
*"IN ATTESA DELLA PS5"* and connects the moment the console is ready.
|
||||
- Press **Stop** (or close the app) to stop streaming. The camera goes black /
|
||||
- Press **STOP** (or close the app) to stop streaming. The camera goes black /
|
||||
freezes on the last frame; consumers keep the device listed.
|
||||
- **Deploy payload** re-sends the payload by hand (useful after a console
|
||||
reboot without autoloader). **Install driver** re-registers the camera by
|
||||
@@ -96,7 +96,7 @@ exe, so they survive restarts.
|
||||
| Log repeats `PS5 non raggiungibile (...)`, riprova | same as above | same |
|
||||
| No `PS5 Capture` camera appears in Discord/OBS | driver never registered (install failed) | press **Install driver**; read the log line after it — it now reports the *real* error |
|
||||
| Log: `ERRORE: driver non scrivibile in C:\Program Files\PSCapture (serve admin?)` | app not elevated | close it, restart `PSCapture.exe` and accept the UAC prompt |
|
||||
| Log: `ERRORE caricando la dll (err=126)` | antivirus quarantined the extracted dll | check the antivirus quarantine for `pscapture.dll`, allow it, press **Install driver** again |
|
||||
| Log: `ERRORE caricamento dll (err=126)` | antivirus quarantined the extracted dll | check the antivirus quarantine for `pscapture.dll`, allow it, press **Install driver** again |
|
||||
| Camera listed but the image is black | stream not running | check the pill; press **Deploy payload** and/or **START STREAMING** |
|
||||
| Colors look wrong (skin reddish, sky orange) | `gain` was changed | set `gain` back to `1.0` → Apply |
|
||||
| Image has a black bar / is off-center | alignment | tune `shift px` (even values) until centered |
|
||||
|
||||
+395
-305
@@ -1,274 +1,350 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="en" class="no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>PSCapture by fstat13 — PS5 screen as a capture card on PC</title>
|
||||
<style>
|
||||
:root{
|
||||
--bg:#0d1015; --card:#151a22; --card2:#1b222d; --line:#242c38;
|
||||
--fg:#e8edf4; --dim:#96a0b0; --accent:#0070d1; --accent2:#35a3ff;
|
||||
--rec:#e22236; --ok:#1fbf6b;
|
||||
}
|
||||
*{box-sizing:border-box}
|
||||
body{margin:0;background:var(--bg);color:var(--fg);
|
||||
font:16px/1.65 "Segoe UI",system-ui,-apple-system,Roboto,sans-serif;}
|
||||
a{color:var(--accent2);text-decoration:none}
|
||||
a:hover{text-decoration:underline}
|
||||
.wrap{max-width:880px;margin:0 auto;padding:0 20px}
|
||||
header{background:
|
||||
radial-gradient(900px 320px at 20% -40%, rgba(0,112,209,.35), transparent 60%),
|
||||
radial-gradient(700px 300px at 90% -30%, rgba(226,34,54,.22), transparent 60%),
|
||||
var(--bg);
|
||||
border-bottom:1px solid var(--line);padding:56px 0 40px}
|
||||
.brand{display:flex;align-items:center;gap:18px}
|
||||
.brand img{width:84px;height:84px;border-radius:20px;box-shadow:0 8px 30px rgba(0,0,0,.5)}
|
||||
h1{font-size:44px;margin:0;letter-spacing:.5px}
|
||||
.tag{color:var(--dim);font-size:18px;margin-top:6px}
|
||||
.badges{margin-top:22px;display:flex;gap:10px;flex-wrap:wrap}
|
||||
.badge{border:1px solid var(--line);background:var(--card);
|
||||
padding:5px 12px;border-radius:999px;font-size:13px;color:var(--dim)}
|
||||
.badge b{color:var(--fg)}
|
||||
h2{margin:52px 0 14px;font-size:26px}
|
||||
h3{margin:26px 0 10px;font-size:19px}
|
||||
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px}
|
||||
.card{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:18px 20px}
|
||||
.card h3{margin:0 0 8px;font-size:17px}
|
||||
.card p{margin:0;color:var(--dim);font-size:14.5px}
|
||||
.flow{display:flex;gap:10px;align-items:stretch;flex-wrap:wrap;margin-top:16px}
|
||||
.box{flex:1;min-width:180px;background:var(--card2);border:1px solid var(--line);
|
||||
border-radius:12px;padding:14px 16px}
|
||||
.box b{display:block;margin-bottom:6px}
|
||||
.box div{color:var(--dim);font-size:13.5px}
|
||||
.arrow{align-self:center;color:var(--accent2);font-size:22px;padding:0 2px}
|
||||
ol.steps{counter-reset:s;list-style:none;padding:0;margin:18px 0 0}
|
||||
ol.steps li{counter-increment:s;position:relative;padding:0 0 18px 54px}
|
||||
ol.steps li::before{content:counter(s);position:absolute;left:0;top:0;
|
||||
width:34px;height:34px;border-radius:10px;background:var(--accent);
|
||||
color:#fff;font-weight:600;display:flex;align-items:center;justify-content:center}
|
||||
ol.steps b{color:var(--fg)}
|
||||
ol.steps span{color:var(--dim)}
|
||||
ul.plain{color:var(--dim);padding-left:22px}
|
||||
ul.plain b{color:var(--fg)}
|
||||
table{width:100%;border-collapse:collapse;margin-top:14px;font-size:14.5px}
|
||||
th,td{text-align:left;padding:10px 12px;border-bottom:1px solid var(--line);
|
||||
vertical-align:top}
|
||||
th{color:var(--dim);font-weight:500}
|
||||
td code,th code{white-space:nowrap}
|
||||
code,kbd{background:#0a0d12;border:1px solid var(--line);border-radius:6px;
|
||||
padding:1px 7px;font:13.5px/1.5 Consolas,monospace;color:#cfe3ff}
|
||||
pre{background:#0a0d12;border:1px solid var(--line);border-radius:12px;
|
||||
padding:14px 16px;overflow-x:auto;font:13.5px/1.6 Consolas,monospace;
|
||||
color:#cfe3ff}
|
||||
pre .c{color:#5f7186}
|
||||
details{background:var(--card);border:1px solid var(--line);border-radius:12px;
|
||||
padding:14px 18px;margin:10px 0}
|
||||
summary{cursor:pointer;font-weight:600}
|
||||
details p{color:var(--dim);margin:10px 0 0}
|
||||
.note{background:linear-gradient(0deg,rgba(0,112,209,.08),rgba(0,112,209,.08)),
|
||||
var(--card);border:1px solid #23405f;border-radius:12px;padding:14px 18px;color:#cfe3ff}
|
||||
.warn{background:linear-gradient(0deg,rgba(226,34,54,.07),rgba(226,34,54,.07)),
|
||||
var(--card);border:1px solid #5f2330;border-radius:12px;padding:14px 18px;color:#f3cdd3}
|
||||
footer{color:var(--dim);border-top:1px solid var(--line);margin-top:70px;
|
||||
padding:26px 0 40px;font-size:13.5px}
|
||||
.dot{display:inline-block;width:9px;height:9px;border-radius:50%;
|
||||
background:var(--rec);margin-right:8px;vertical-align:1px}
|
||||
.ok{color:var(--ok);font-weight:600}
|
||||
.toc{display:flex;gap:8px;flex-wrap:wrap;margin-top:18px}
|
||||
.toc a{border:1px solid var(--line);background:var(--card);border-radius:999px;
|
||||
padding:4px 12px;font-size:13px}
|
||||
.lang{position:absolute;top:18px;right:22px;font-size:13.5px}
|
||||
</style>
|
||||
<title>PSCapture — your PS5 screen as a capture card on PC</title>
|
||||
<meta name="description" content="PSCapture turns a jailbroken PS5 into a capture card for your PC: the console screen streams over your LAN and shows up in Discord, OBS and ffmpeg as a camera called “PS5 Capture”.">
|
||||
<meta name="theme-color" content="#07090d">
|
||||
<link rel="icon" type="image/png" href="pscapture.png">
|
||||
<link rel="alternate" hreflang="en" href="https://fstat13.github.io/PSCapture/">
|
||||
<link rel="alternate" hreflang="it" href="https://fstat13.github.io/PSCapture/index.it.html">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="PSCapture — your PS5 screen, live on your PC">
|
||||
<meta property="og:description" content="The PS5 screen shows up in Discord, OBS and ffmpeg as the camera “PS5 Capture”. No capture card, no Remote Play, no cloud.">
|
||||
<meta property="og:image" content="https://fstat13.github.io/PSCapture/pscapture.png">
|
||||
<meta property="og:url" content="https://fstat13.github.io/PSCapture/">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header style="position:relative">
|
||||
<div class="lang">🇮🇹 <a href="index.it.html">Italiano</a></div>
|
||||
<svg width="0" height="0" style="position:absolute" aria-hidden="true">
|
||||
<symbol id="i-download" viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></symbol>
|
||||
<symbol id="i-star" viewBox="0 0 24 24"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></symbol>
|
||||
<symbol id="i-check" viewBox="0 0 24 24"><polyline points="20 6 9 17 4 12"/></symbol>
|
||||
<symbol id="i-video" viewBox="0 0 24 24"><path d="m22 8-6 4 6 4V8Z"/><rect x="2" y="6" width="14" height="12" rx="2"/></symbol>
|
||||
<symbol id="i-zap" viewBox="0 0 24 24"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></symbol>
|
||||
<symbol id="i-file" viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></symbol>
|
||||
<symbol id="i-refresh" viewBox="0 0 24 24"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></symbol>
|
||||
<symbol id="i-sliders" viewBox="0 0 24 24"><line x1="4" y1="21" x2="4" y2="14"/><line x1="4" y1="10" x2="4" y2="3"/><line x1="12" y1="21" x2="12" y2="12"/><line x1="12" y1="8" x2="12" y2="3"/><line x1="20" y1="21" x2="20" y2="16"/><line x1="20" y1="12" x2="20" y2="3"/><line x1="1" y1="14" x2="7" y2="14"/><line x1="9" y1="8" x2="15" y2="8"/><line x1="17" y1="16" x2="23" y2="16"/></symbol>
|
||||
<symbol id="i-lock" viewBox="0 0 24 24"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></symbol>
|
||||
<symbol id="i-console" viewBox="0 0 24 24"><rect x="2" y="6" width="20" height="12" rx="3"/><line x1="6" y1="12" x2="10" y2="12"/><line x1="8" y1="10" x2="8" y2="14"/><circle cx="16" cy="11" r=".6"/><circle cx="18" cy="13" r=".6"/></symbol>
|
||||
<symbol id="i-monitor" viewBox="0 0 24 24"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></symbol>
|
||||
<symbol id="i-info" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></symbol>
|
||||
<symbol id="i-alert" viewBox="0 0 24 24"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></symbol>
|
||||
<symbol id="i-search" viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></symbol>
|
||||
</svg>
|
||||
|
||||
<nav class="nav">
|
||||
<div class="wrap">
|
||||
<div class="brand">
|
||||
<img src="pscapture.png" alt="PSCapture">
|
||||
<div>
|
||||
<h1>PSCapture</h1>
|
||||
<div class="tag">The PlayStation 5 screen, live on your PC — as a real capture card.</div>
|
||||
<a class="logo" href="#top"><img src="pscapture.png" alt="">PSCapture</a>
|
||||
<div class="nav-links">
|
||||
<a href="#how">How it works</a>
|
||||
<a href="#start">Setup</a>
|
||||
<a href="#trouble">Troubleshooting</a>
|
||||
<a href="#build">Build</a>
|
||||
<a href="#faq">FAQ</a>
|
||||
</div>
|
||||
<div class="nav-right">
|
||||
<a class="lang" href="index.it.html" hreflang="it">Italiano</a>
|
||||
<a class="btn btn-ghost btn-sm" href="https://github.com/fstat13/PSCapture"><svg class="i"><use href="#i-star"/></svg>Star <span class="stars" data-stars hidden></span></a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<header class="hero" id="top">
|
||||
<div class="wrap hero-grid">
|
||||
<div>
|
||||
<span class="eyebrow"><span class="tagv">v0.1</span>Tested on PS5 firmware 13.60</span>
|
||||
<h1>Your PS5 screen,<br><span class="grad">live on your PC.</span></h1>
|
||||
<p class="lead">PSCapture turns a jailbroken PlayStation 5 into a capture card.
|
||||
The console streams its own screen over your LAN, and Windows sees it as a
|
||||
camera called <b>PS5 Capture</b>, ready for Discord, OBS and ffmpeg.</p>
|
||||
<div class="cta">
|
||||
<a class="btn btn-primary" href="https://github.com/fstat13/PSCapture/releases"><svg class="i"><use href="#i-download"/></svg>Download for Windows</a>
|
||||
<a class="btn btn-ghost" href="https://github.com/fstat13/PSCapture"><svg class="i"><use href="#i-star"/></svg>Star on GitHub <span class="stars" data-stars hidden></span></a>
|
||||
</div>
|
||||
<div class="hero-meta">
|
||||
<span><svg class="i"><use href="#i-check"/></svg>No capture card</span>
|
||||
<span><svg class="i"><use href="#i-check"/></svg>No Remote Play</span>
|
||||
<span><svg class="i"><use href="#i-check"/></svg>No cloud</span>
|
||||
<span><svg class="i"><use href="#i-check"/></svg>One .exe</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="badges">
|
||||
<span class="badge"><b>PS5</b> jailbroken</span>
|
||||
<span class="badge"><b>Windows</b> 10 / 11</span>
|
||||
<span class="badge"><span class="dot"></span><b>No</b> capture card</span>
|
||||
<span class="badge"><b>No</b> Remote Play</span>
|
||||
<span class="badge">1080p · ~30 fps</span>
|
||||
|
||||
<div class="app" role="img" aria-label="The PSCapture window: the log shows the driver check, the payload being sent and the stream connecting; the status pill reads STREAMING.">
|
||||
<div class="app-bar">
|
||||
<img src="pscapture.png" alt="">
|
||||
<span class="t">PSCapture by fstat13 - PS5 screen to PC</span>
|
||||
<span class="w"><span>–</span><span>□</span><span>✕</span></span>
|
||||
</div>
|
||||
<div class="app-body">
|
||||
<div class="app-head">
|
||||
<div class="app-title">PSCapture<small>PS5 screen to PC</small></div>
|
||||
<span class="pill live"><i></i> STREAMING 29.8 fps</span>
|
||||
</div>
|
||||
<div class="app-row">
|
||||
<span class="app-lbl">PS5 IP</span><span class="app-in">192.168.0.36</span>
|
||||
<span class="app-btn">Deploy payload</span><span class="app-btn">Install driver</span>
|
||||
</div>
|
||||
<div class="app-row">
|
||||
<span class="app-btn big">START STREAMING</span><span class="app-btn stop">STOP</span>
|
||||
<span class="app-knobs app-row" style="margin:0">
|
||||
<span class="app-lbl">gain</span><span class="app-in">1.0</span>
|
||||
<span class="app-lbl">shift px</span><span class="app-in">0</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="app-log" aria-hidden="true">
|
||||
<div>PSCapture pronto: premo Start e faccio tutto da solo.</div>
|
||||
<div>--- AVVIO AUTOMATICO ---</div>
|
||||
<div>driver gia' installato</div>
|
||||
<div>payload dall'eseguibile (175480 byte)</div>
|
||||
<div>payload 175480 byte, invio a 192.168.0.36</div>
|
||||
<div>autoloader aggiornato (pldmgr)</div>
|
||||
<div class="hl">payload avviato - la PS5 deve mostrare la notifica PSCapture</div>
|
||||
<div>porta stream: 5599</div>
|
||||
<div class="ok">collegato a 192.168.0.36:5599</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="toc">
|
||||
<a href="#start">Quick start</a>
|
||||
<a href="#daily">Daily use</a>
|
||||
<a href="#trouble">Troubleshooting</a>
|
||||
<a href="#build">Build from source</a>
|
||||
<a href="#faq">FAQ</a>
|
||||
</div>
|
||||
|
||||
<div class="wrap">
|
||||
<div class="stats">
|
||||
<div class="stat"><div class="n">1920×1080</div><div class="l">full HD in OBS</div></div>
|
||||
<div class="stat"><div class="n">~30 fps</div><div class="l">over a plain LAN</div></div>
|
||||
<div class="stat"><div class="n">0</div><div class="l">re-encodes on the console</div></div>
|
||||
<div class="stat"><div class="n">1 file</div><div class="l">driver and payload inside</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
<main class="wrap">
|
||||
|
||||
<h2>What it is</h2>
|
||||
<div class="cards">
|
||||
<div class="card">
|
||||
<h3>🎥 Virtual capture card</h3>
|
||||
<p>PSCapture registers a DirectShow device named <b>PS5 Capture</b>.
|
||||
Discord, OBS and ffmpeg see it like an Elgato — pick it and go live.</p>
|
||||
<section id="why" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">Why PSCapture</div>
|
||||
<h2>A capture card, without the capture card.</h2>
|
||||
<p class="sub">Everything runs on hardware you already own: the console, your network and your PC.</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>⚡ Straight from the GPU</h3>
|
||||
<p>The console payload reads the display engine's scan-out buffer directly
|
||||
and streams NV12 frames over your LAN. No re-encode delay, no cloud.</p>
|
||||
<div class="grid g3">
|
||||
<div class="card"><div class="ico"><svg class="i"><use href="#i-video"/></svg></div>
|
||||
<h3>A real camera device</h3>
|
||||
<p>A DirectShow source filter named <b>PS5 Capture</b>. Any app that can open a webcam can open your console.</p></div>
|
||||
<div class="card"><div class="ico v"><svg class="i"><use href="#i-zap"/></svg></div>
|
||||
<h3>Straight from the display engine</h3>
|
||||
<p>The payload reads the console's scan-out buffer and sends raw NV12 frames. Nothing is re-encoded, so nothing waits for an encoder.</p></div>
|
||||
<div class="card"><div class="ico g"><svg class="i"><use href="#i-file"/></svg></div>
|
||||
<h3>One file, one window</h3>
|
||||
<p><b>PSCapture.exe</b> installs the driver, sends the payload, registers it in the autoloader and connects, all on its own.</p></div>
|
||||
<div class="card"><div class="ico a"><svg class="i"><use href="#i-refresh"/></svg></div>
|
||||
<h3>Recovers by itself</h3>
|
||||
<p>Console still off? It retries every 2 seconds. Stream dropped? It reconnects. You don't have to babysit it.</p></div>
|
||||
<div class="card"><div class="ico"><svg class="i"><use href="#i-sliders"/></svg></div>
|
||||
<h3>Live tuning</h3>
|
||||
<p>Colour <code>gain</code> and horizontal <code>shift</code> apply in about a second and are saved in <code>pscapture.ini</code>.</p></div>
|
||||
<div class="card"><div class="ico v"><svg class="i"><use href="#i-lock"/></svg></div>
|
||||
<h3>Stays on your network</h3>
|
||||
<p>No accounts, no cloud relay, no Remote Play. Frames go from the console to your PC and nowhere else.</p></div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>🖱️ One executable</h3>
|
||||
<p><b>PSCapture.exe</b> carries the console payload inside itself:
|
||||
install the driver, push the payload, start streaming — one window,
|
||||
one click.</p>
|
||||
</section>
|
||||
|
||||
<section id="how" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">How it works</div>
|
||||
<h2>Three small pieces, one camera.</h2>
|
||||
<p class="sub">A payload on the console, a feeder and a driver on the PC. The apps you already use just see a webcam.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pipe">
|
||||
<div class="node"><div class="where">PS5</div><h3>Payload</h3>
|
||||
<p>Reads the display engine's scan-out ring, builds NV12 frames and serves them on TCP <code>5599</code>. Pops the toast <i>“PSCapture is streaming on:5599”</i>.</p></div>
|
||||
<div class="link"><span>TCP · NV12<br>your LAN</span><div class="line"></div></div>
|
||||
<div class="node"><div class="where">PC · PSCapture.exe</div><h3>Feeder</h3>
|
||||
<p>Receives the frames and publishes them into a shared-memory ring.</p></div>
|
||||
<div class="link"><span>shared<br>memory</span><div class="line"></div></div>
|
||||
<div class="node"><div class="where">PC · pscapture.dll</div><h3>Driver</h3>
|
||||
<p>A DirectShow source filter that exposes the ring as the camera <b>PS5 Capture</b>.</p></div>
|
||||
<div class="link"><span>DirectShow</span><div class="line"></div></div>
|
||||
<div class="node end"><div class="where">Your apps</div><h3>Any camera app</h3>
|
||||
<p>Pick <b>PS5 Capture</b> like any webcam.</p>
|
||||
<div class="chips"><span class="chip">Discord</span><span class="chip">OBS</span><span class="chip">ffmpeg</span></div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h2>How it works</h2>
|
||||
<div class="flow">
|
||||
<div class="box"><b>PS5 · payload</b>
|
||||
<div>reads the DCE scan-out ring, builds NV12 frames, serves them on a TCP
|
||||
port, pops a toast: <i>“PSCapture is streaming on:PORT”</i>.</div></div>
|
||||
<div class="arrow">→</div>
|
||||
<div class="box"><b>PC · feeder</b>
|
||||
<div>receives frames and publishes them into a shared-memory ring.</div></div>
|
||||
<div class="arrow">→</div>
|
||||
<div class="box"><b>PC · driver</b>
|
||||
<div>DirectShow filter exposes the ring as a camera every app can use.</div></div>
|
||||
</div>
|
||||
<section id="requirements" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">Before you start</div>
|
||||
<h2>What you need.</h2>
|
||||
</div>
|
||||
<div class="grid g2">
|
||||
<div class="req">
|
||||
<div class="req-h"><div class="ico"><svg class="i"><use href="#i-console"/></svg></div><h3>On the PS5</h3></div>
|
||||
<ul>
|
||||
<li><svg class="i"><use href="#i-check"/></svg><span>A jailbroken console<small>Built and tuned on firmware <b>13.60</b>. See the FAQ for other versions.</small></span></li>
|
||||
<li><svg class="i"><use href="#i-check"/></svg><span>Payload loader on TCP <code>9021</code><small><code>elfldr</code>-style, as in every current jailbreak setup.</small></span></li>
|
||||
<li><svg class="i"><use href="#i-check"/></svg><span>Anonymous FTP on TCP <code>2121</code><small>The app reads and writes a few files on the console.</small></span></li>
|
||||
<li class="opt"><svg class="i"><use href="#i-check"/></svg><span><code>pldmgr</code> autoloader <span class="tagopt">optional</span><small>Starts the payload on every boot, so you never deploy by hand.</small></span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="req">
|
||||
<div class="req-h"><div class="ico v"><svg class="i"><use href="#i-monitor"/></svg></div><h3>On the PC</h3></div>
|
||||
<ul>
|
||||
<li><svg class="i"><use href="#i-check"/></svg><span>Windows 10 or 11, 64-bit<small>The camera is a DirectShow device, so the PC side is Windows-only.</small></span></li>
|
||||
<li><svg class="i"><use href="#i-check"/></svg><span>Same network as the console<small>Wired recommended. Gigabit is plenty for 1080p at 30 fps.</small></span></li>
|
||||
<li><svg class="i"><use href="#i-check"/></svg><span>Admin rights, once<small>To register the camera for every program on the machine.</small></span></li>
|
||||
<li><svg class="i"><use href="#i-check"/></svg><span><b>PSCapture.exe</b> from <a href="https://github.com/fstat13/PSCapture/releases">Releases</a><small>One single file: the payload and the driver are inside it.</small></span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h2 id="start">Quick start — step by step</h2>
|
||||
<section id="start" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">Setup</div>
|
||||
<h2>From zero to live in five steps.</h2>
|
||||
<p class="sub">After step 2 you mostly watch: the app does the rest and tells you what it's doing.</p>
|
||||
</div>
|
||||
<ol class="steps">
|
||||
<li><h3>Jailbreak the console</h3>
|
||||
<p>Run your usual jailbreak so the payload loader (<code>9021</code>) and FTP (<code>2121</code>) are up.</p></li>
|
||||
<li><h3>Double-click <code>PSCapture.exe</code></h3>
|
||||
<p>Windows asks <i>“Do you want to allow this app to make changes to your device?”</i>. Click <b>Yes</b>. The app elevates itself, no right-click needed.</p></li>
|
||||
<li><h3>Check the IP</h3>
|
||||
<p>The default is <code>192.168.0.36</code>. If your PS5 has a different address, type it in <b>PS5 IP</b> and press <b>Apply</b>. It's remembered. You can find it on the console under <i>Settings → Network → Connection Status → View Connection Status</i>.</p></li>
|
||||
<li><h3>Hands off</h3>
|
||||
<p>On the first run the app installs the driver, then sends the payload and connects. The console shows <i>“PSCapture is streaming on:5599”</i> and the status pill turns <b style="color:var(--green)">green: STREAMING</b>.</p></li>
|
||||
<li><h3>Pick <b>PS5 Capture</b> in your app</h3>
|
||||
<p>Discord, OBS or ffmpeg. See <a href="#use">where to find it</a> below.</p></li>
|
||||
</ol>
|
||||
|
||||
<div class="note" style="margin-bottom:20px">
|
||||
<b>What you need first.</b> A jailbroken PS5 with the standard setup:
|
||||
a payload loader on TCP <code>9021</code> (<code>elfldr</code>-style),
|
||||
anonymous FTP on TCP <code>2121</code>, and optionally the
|
||||
<code>pldmgr</code> autoloader so the payload starts on every boot.
|
||||
PC and console on the same LAN. Download <b>PSCapture.exe</b> from the
|
||||
Releases page — <b>it's one single file</b>: the console payload and the
|
||||
Windows driver are inside it.
|
||||
</div>
|
||||
<h3 style="margin:30px 0 6px">Reading the log</h3>
|
||||
<p style="color:var(--dim)">The app's log is in Italian. Here's what each line means, in the order you'll see them.</p>
|
||||
<div class="term" style="margin-top:14px">
|
||||
<div class="term-bar"><i></i><i></i><i></i><b>pscapture-app.log</b></div>
|
||||
<div class="term-row"><code>driver gia' installato</code><span class="m">The camera is already registered. Nothing to do.</span></div>
|
||||
<div class="term-row"><code>driver non installato: lo installo ora (primo avvio)<br>driver estratto dall'eseguibile (… byte)<br>driver registrato - la webcam 'PS5 Capture' e' pronta</code><span class="m">First run: the driver is unpacked from the exe and registered.</span></div>
|
||||
<div class="term-row"><code>payload dall'eseguibile (… byte)<br>payload … byte, invio a 192.168.0.36</code><span class="m">The payload is on its way to the console.</span></div>
|
||||
<div class="term-row"><code>autoloader aggiornato (pldmgr)</code><span class="m">The payload was copied to the autoloader, so it'll start on every boot.</span></div>
|
||||
<div class="term-row"><code>payload avviato - la PS5 deve mostrare la notifica PSCapture</code><span class="m">The payload is running. Look for the toast on the TV.</span></div>
|
||||
<div class="term-row ok"><code>porta stream: 5599<br>collegato a 192.168.0.36:5599</code><span class="m">Connected. The pill reads <b>STREAMING</b> with the live fps.</span></div>
|
||||
</div>
|
||||
|
||||
<ol class="steps">
|
||||
<li><b>Jailbreak the console</b><br>
|
||||
<span>Any kernel-capable jailbreak that gives you the payload loader
|
||||
(:9021), anonymous FTP (:2121) and — optionally — the
|
||||
<code>pldmgr</code> autoloader.</span></li>
|
||||
<li><b>Double-click <code>PSCapture.exe</code></b><br>
|
||||
<span>Windows asks <i>“Do you want to allow this app to make changes?”</i>
|
||||
→ <b>Yes</b>. The app elevates itself; admin is needed once, to register
|
||||
the virtual camera for every program on the machine.</span></li>
|
||||
<li><b>Check the IP</b><br>
|
||||
<span>If your PS5 is not at <code>192.168.0.36</code>, type its address
|
||||
in the <b>PS5 IP</b> field and press <b>Apply</b>.</span></li>
|
||||
<li><b>Watch it work — press nothing</b><br>
|
||||
<span>The app does everything alone, and narrates it in the dark log pane
|
||||
(see the table below). On the console you will also see the system
|
||||
notification <i>“PSCapture is streaming on:PORT”</i>.</span></li>
|
||||
<li><b>Use it in any app</b><br>
|
||||
<span>Discord (call): <i>Settings → Voice & Video → Camera</i> →
|
||||
<b>PS5 Capture</b> (720p — Discord asks every camera for 720p, capture
|
||||
cards included). OBS: add a <i>Video Capture Device</i> → full
|
||||
<b>1920x1080</b>. ffmpeg:
|
||||
<code>-f dshow -i video="PS5 Capture"</code>.</span></li>
|
||||
</ol>
|
||||
<div class="callout warn" style="margin-top:18px">
|
||||
<svg class="i"><use href="#i-alert"/></svg>
|
||||
<p><b>Pill stuck on “IN ATTESA DELLA PS5”</b> (“waiting for the PS5”)? The console is off, not jailbroken yet, or the IP is wrong. You don't need to restart anything: the app retries every 2 seconds and connects the moment ports <code>9021</code> and <code>2121</code> answer.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h3>What you should see in the app log</h3>
|
||||
<table>
|
||||
<tr><th>Line</th><th>Meaning</th></tr>
|
||||
<tr><td><code>driver gia' installato</code></td>
|
||||
<td>camera already registered — nothing to do</td></tr>
|
||||
<tr><td><code>driver estratto dall'eseguibile (… byte)</code><br>
|
||||
<code>driver registrato - la webcam 'PS5 Capture' e' pronta</code></td>
|
||||
<td>first run: the driver was unpacked from the exe and registered</td></tr>
|
||||
<tr><td><code>payload dall'eseguibile (… byte)</code></td>
|
||||
<td>the console payload is on its way to the PS5</td></tr>
|
||||
<tr><td><code>payload avviato - la PS5 deve mostrare la notifica PSCapture</code></td>
|
||||
<td>the payload is running on the console</td></tr>
|
||||
<tr><td><code>porta stream: 9xxx</code> → <code>collegato a …:9xxx</code></td>
|
||||
<td>stream connected — the pill turns <span class="ok">green: STREAMING</span></td></tr>
|
||||
</table>
|
||||
<section id="use" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">Use it</div>
|
||||
<h2>Works wherever a webcam works.</h2>
|
||||
</div>
|
||||
<div class="grid g3">
|
||||
<div class="card target"><h3>Discord</h3>
|
||||
<div class="path"><i>Settings → Voice & Video → Camera</i> → <b>PS5 Capture</b></div>
|
||||
<p style="margin-top:10px">Discord asks every camera for 720p, capture cards included. For 1080p60 use screen-share (Nitro).</p>
|
||||
<div class="res">in calls <b>1280×720</b></div></div>
|
||||
<div class="card target"><h3>OBS Studio</h3>
|
||||
<div class="path"><i>Sources → + → Video Capture Device</i> → <b>PS5 Capture</b></div>
|
||||
<p style="margin-top:10px">Full resolution, ready for recording or streaming.</p>
|
||||
<div class="res">native <b>1920×1080</b></div></div>
|
||||
<div class="card target"><h3>ffmpeg</h3>
|
||||
<div class="path"><code>ffmpeg -f dshow -i video="PS5 Capture" capture.mkv</code></div>
|
||||
<p style="margin-top:10px">Scripted captures and quick tests.</p>
|
||||
<div class="res">native <b>1920×1080</b></div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="warn" style="margin-top:18px">
|
||||
<b>Pill stuck on “IN ATTESA DELLA PS5 — accesa e col jailbreak avviato?”</b><br>
|
||||
The console is off, not jailbroken yet, or the IP is wrong. The app keeps
|
||||
retrying every 2 seconds: the moment the console is ready it connects by
|
||||
itself. Ports to check on the console: <code>9021</code> and
|
||||
<code>2121</code> must be open.
|
||||
</div>
|
||||
<section id="daily" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">Daily use</div>
|
||||
<h2>Open it and play.</h2>
|
||||
</div>
|
||||
<div class="grid g3">
|
||||
<div class="card knob"><span class="k">every day</span>
|
||||
<p>Open <b>PSCapture.exe</b> and accept the UAC prompt. With the autoloader the stream starts by itself.</p>
|
||||
<ul>
|
||||
<li><b>Deploy payload</b>: re-sends the payload by hand, after a reboot without autoloader.</li>
|
||||
<li><b>Install driver</b>: re-registers the camera if the log shows a driver error.</li>
|
||||
<li><b>STOP</b> or closing the app: the camera freezes on the last frame and stays listed.</li>
|
||||
</ul></div>
|
||||
<div class="card knob"><span class="k">gain</span>
|
||||
<p>Colour (chroma) strength.</p>
|
||||
<ul><li><code>1.0</code> is raw and correct.</li><li>Only touch it if colours look off.</li></ul></div>
|
||||
<div class="card knob"><span class="k">shift px</span>
|
||||
<p>Moves the picture left or right.</p>
|
||||
<ul><li><b>Even numbers only</b>: an odd value swaps the colours.</li><li>The console's title text makes a good reference.</li></ul></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h2 id="daily">Daily use & tuning</h2>
|
||||
<ul class="plain">
|
||||
<li>Open <b>PSCapture.exe</b> (UAC → Yes). If the payload is already on the
|
||||
console (autoloader), the stream starts by itself; otherwise press
|
||||
<b>Deploy payload</b> once.</li>
|
||||
<li><b>Stop</b> / closing the app stops the stream — the camera freezes on
|
||||
the last frame and consumers keep the device listed.</li>
|
||||
<li><b>gain</b> — chroma strength. <b>Leave it at 1.0</b> (raw) unless
|
||||
colors look off.</li>
|
||||
<li><b>shift px</b> — horizontal alignment. <b>Even numbers only</b> (an
|
||||
odd value inverts the colors). Applies live, saved in
|
||||
<code>pscapture.ini</code> next to the exe.</li>
|
||||
</ul>
|
||||
<section id="trouble" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">Troubleshooting</div>
|
||||
<h2>Symptom → fix.</h2>
|
||||
<p class="sub">Type what you see, or paste a line from the log.</p>
|
||||
</div>
|
||||
<div class="search"><svg class="i"><use href="#i-search"/></svg>
|
||||
<input id="q" type="search" placeholder="e.g. black, 720p, err=126, ATTESA…" autocomplete="off" aria-label="Filter problems"></div>
|
||||
<div class="issues">
|
||||
<div class="issue"><div class="sym">Pill stays on <code>AVVIO…</code> or <code>IN ATTESA DELLA PS5</code></div>
|
||||
<div class="fix"><span class="cause">console off, not jailbroken, or wrong IP</span>Turn the console on, run the jailbreak (ports 9021 and 2121 must be up), check the <b>PS5 IP</b> field. The app keeps retrying.</div></div>
|
||||
<div class="issue"><div class="sym">Log repeats <code>PS5 non raggiungibile (…), riprovo</code></div>
|
||||
<div class="fix"><span class="cause">console not reachable</span>Same as above. It connects by itself as soon as the console answers.</div></div>
|
||||
<div class="issue"><div class="sym">Log: <code>elfldr :9021 non raggiungibile</code></div>
|
||||
<div class="fix"><span class="cause">payload loader not running</span>Run the jailbreak again, then press <b>Deploy payload</b>.</div></div>
|
||||
<div class="issue"><div class="sym">No <b>PS5 Capture</b> camera in Discord or OBS</div>
|
||||
<div class="fix"><span class="cause">driver not registered</span>Press <b>Install driver</b> and read the next log line: it reports the real error.</div></div>
|
||||
<div class="issue"><div class="sym">Log: <code>ERRORE: driver non scrivibile in C:\Program Files\PSCapture (serve admin?)</code></div>
|
||||
<div class="fix"><span class="cause">app not elevated</span>Close it, start <code>PSCapture.exe</code> again and answer <b>Yes</b> to the UAC prompt.</div></div>
|
||||
<div class="issue"><div class="sym">Log: <code>elevazione rifiutata: continuo senza privilegi</code></div>
|
||||
<div class="fix"><span class="cause">UAC prompt answered “No”</span>Streaming can still work, but the driver can't be installed. Restart the app and click <b>Yes</b>.</div></div>
|
||||
<div class="issue"><div class="sym">Log: <code>ERRORE caricamento dll (err=126)</code></div>
|
||||
<div class="fix"><span class="cause">antivirus quarantined the driver</span>Restore and allow <code>pscapture.dll</code> in your antivirus, then press <b>Install driver</b> again.</div></div>
|
||||
<div class="issue"><div class="sym">Log: <code>autoloader: copia FALLITA (pldmgr c'e'?)</code></div>
|
||||
<div class="fix"><span class="cause"><code>pldmgr</code> not installed</span>Harmless: streaming works now. Without the autoloader, press <b>Deploy payload</b> after every console reboot.</div></div>
|
||||
<div class="issue"><div class="sym">Camera is listed but the image is black</div>
|
||||
<div class="fix"><span class="cause">stream not running</span>Check the pill. Press <b>Deploy payload</b> and/or <b>START STREAMING</b>.</div></div>
|
||||
<div class="issue"><div class="sym">Log: <code>stream caduto, riconnetto</code></div>
|
||||
<div class="fix"><span class="cause">network hiccup or console went to rest mode</span>The app reconnects by itself. If it happens often, use a cable instead of Wi-Fi.</div></div>
|
||||
<div class="issue"><div class="sym">Colours look wrong (reddish skin, orange sky)</div>
|
||||
<div class="fix"><span class="cause"><code>gain</code> was changed</span>Set <code>gain</code> back to <code>1.0</code> and press <b>Apply</b>.</div></div>
|
||||
<div class="issue"><div class="sym">Colours inverted, black bar, picture off-centre</div>
|
||||
<div class="fix"><span class="cause">alignment</span>Tune <code>shift px</code> using <b>even</b> values only. An odd value swaps the colours.</div></div>
|
||||
<div class="issue"><div class="sym">Discord shows only 720p</div>
|
||||
<div class="fix"><span class="cause">Discord's limit, not PSCapture's</span>Discord caps every camera at 720p in calls. Use OBS for 1080p, or Discord screen-share (1080p60 with Nitro).</div></div>
|
||||
<div class="issue"><div class="sym">OBS sees the camera, Discord doesn't</div>
|
||||
<div class="fix"><span class="cause">Discord was open during the driver install</span>Quit Discord completely (tray icon too) and reopen it.</div></div>
|
||||
<div class="issue"><div class="sym">Anything else</div>
|
||||
<div class="fix"><span class="cause">read the logs</span><code>pscapture-app.log</code> (next to the exe, or in <code>%TEMP%</code>) and the console log <code>/data/pscapture.log</code> over FTP. Then <a href="https://github.com/fstat13/PSCapture/issues">open an issue</a> with both.</div></div>
|
||||
<div class="noresult" hidden>No match. <a href="https://github.com/fstat13/PSCapture/issues">Open an issue</a> with your <code>pscapture-app.log</code>.</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h2 id="trouble">Troubleshooting — symptom → fix</h2>
|
||||
<table>
|
||||
<tr><th>Symptom</th><th>Cause → fix</th></tr>
|
||||
<tr><td>Pill stays <code>AVVIO…</code> / <code>IN ATTESA DELLA PS5</code></td>
|
||||
<td>Console off or not jailbroken, or wrong IP → turn it on, run the
|
||||
jailbreak, check the IP field</td></tr>
|
||||
<tr><td>Log repeats <code>PS5 non raggiungibile</code></td>
|
||||
<td>Same as above — the app retries by itself</td></tr>
|
||||
<tr><td>No <b>PS5 Capture</b> camera in Discord/OBS</td>
|
||||
<td>Driver never registered → press <b>Install driver</b>; the log now
|
||||
reports the real error</td></tr>
|
||||
<tr><td><code>ERRORE: driver non scrivibile in C:\Program Files\PSCapture (serve admin?)</code></td>
|
||||
<td>App not elevated → restart PSCapture.exe and accept the UAC prompt</td></tr>
|
||||
<tr><td><code>ERRORE caricando la dll (err=126)</code></td>
|
||||
<td>Antivirus quarantined the extracted dll → allow
|
||||
<code>pscapture.dll</code> in the antivirus, then press
|
||||
<b>Install driver</b> again</td></tr>
|
||||
<tr><td>Camera listed but image is black</td>
|
||||
<td>Stream not started → check the pill, press <b>Deploy payload</b>
|
||||
and/or <b>START STREAMING</b></td></tr>
|
||||
<tr><td>Colors look wrong</td>
|
||||
<td><code>gain</code> was moved → set it back to 1.0 and Apply</td></tr>
|
||||
<tr><td>Image off-center / black bar</td>
|
||||
<td>Alignment → tune <code>shift px</code> with even numbers</td></tr>
|
||||
<tr><td>Discord shows 720p</td>
|
||||
<td>Discord's engine caps every camera at 720p → use OBS for 1080p</td></tr>
|
||||
<tr><td>OBS sees the camera, Discord doesn't</td>
|
||||
<td>Discord was open before the driver install → fully quit Discord
|
||||
(tray included) and reopen</td></tr>
|
||||
<tr><td>Anything else</td>
|
||||
<td>Read <code>pscapture-app.log</code> (next to the exe or in
|
||||
<code>%TEMP%</code>) and the console log
|
||||
<code>/data/pscapture.log</code> over FTP</td></tr>
|
||||
</table>
|
||||
<section id="build" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">Build from source</div>
|
||||
<h2>Two halves, two toolchains.</h2>
|
||||
<p class="sub">The repository holds sources only; ready-made binaries are on <a href="https://github.com/fstat13/PSCapture/releases">Releases</a>. The full walkthrough (toolchain install, checks, pitfalls) is in <a href="https://github.com/fstat13/PSCapture/blob/main/docs/BUILD.md">BUILD.md</a>.</p>
|
||||
</div>
|
||||
|
||||
<h2 id="build">Build from source</h2>
|
||||
<div class="build-step">
|
||||
<div class="num">Step 1 · console</div>
|
||||
<h3>Payload → <code>pscapture.elf</code></h3>
|
||||
<p>Needs Docker and the PS5 payload SDK image (prospero-clang; any tag works, here <code>ps5sdk:18</code>).</p>
|
||||
<div class="codeblock"><pre><span class="p">$ </span>docker run --rm -v "$PWD/payload:/payload" -w /payload ps5sdk:18 make</pre></div>
|
||||
</div>
|
||||
|
||||
<p style="color:var(--dim)">Sources only — the repo contains no binaries.
|
||||
Two halves, two toolchains. The full walk-through (toolchain install,
|
||||
verification, gotchas) is in <a href="BUILD.md">docs/BUILD.md</a>.</p>
|
||||
|
||||
<h3>1 · Console payload → <code>pscapture.elf</code></h3>
|
||||
<pre><span class="c"># needs Docker + the PS5 payload SDK image (prospero-clang; here tagged ps5sdk:18)</span>
|
||||
docker run --rm -v "<repo>/payload:/payload" -w /payload ps5sdk:18 make</pre>
|
||||
|
||||
<h3>2 · PC side → <code>pscapture.exe</code> + <code>pscapture.dll</code></h3>
|
||||
<p style="color:var(--dim)">Needs MinGW-w64 (<code>gcc</code> +
|
||||
<code>windres</code>). <b>The order is mandatory</b>: the
|
||||
<code>.res</code> embeds the driver and the payload as they are on disk.</p>
|
||||
<pre><span class="c"># from the repo root</span>
|
||||
cp payload/pscapture.elf pc/ <span class="c"># it gets embedded as-is</span>
|
||||
<div class="build-step">
|
||||
<div class="num">Step 2 · PC</div>
|
||||
<h3>App and driver → <code>pscapture.exe</code> + <code>pscapture.dll</code></h3>
|
||||
<p>Needs MinGW-w64 (<code>gcc</code> + <code>windres</code>). <b>The order matters</b>: the <code>.res</code> embeds the driver and the payload exactly as they are on disk.</p>
|
||||
<div class="codeblock"><pre><span class="c"># from the repo root</span>
|
||||
cp payload/pscapture.elf pc/
|
||||
cd pc
|
||||
|
||||
<span class="c"># 1) the capture-card driver (DirectShow source filter)</span>
|
||||
@@ -280,73 +356,87 @@ windres pscapture.rc -O coff -o pscapture.res
|
||||
|
||||
<span class="c"># 3) the single-file app</span>
|
||||
gcc -O2 -mwindows -o pscapture.exe pscapture.c pscapture.res \
|
||||
-lws2_32 -lshell32 -ladvapi32 -luxtheme</pre>
|
||||
-lws2_32 -lshell32 -ladvapi32 -luxtheme</pre></div>
|
||||
</div>
|
||||
|
||||
<details>
|
||||
<summary>Why the order? (and the two classic build mistakes)</summary>
|
||||
<p><b>windres embeds files as they are on disk:</b> if the DLL or the
|
||||
payload is rebuilt after step 2, the exe still carries the old ones.
|
||||
Rebuild = DLL → windres → exe, every time.<br>
|
||||
<b><code>-static -static-libgcc</code> on the DLL is mandatory:</b>
|
||||
without it Windows can fail to load the driver with the cryptic
|
||||
“the specified module could not be found” (missing mingw runtime).</p>
|
||||
</details>
|
||||
<div class="callout info" style="margin-top:22px">
|
||||
<svg class="i"><use href="#i-info"/></svg>
|
||||
<p><b>The two classic mistakes.</b> Rebuilding the DLL or the payload <i>after</i> <code>windres</code> leaves the old ones inside the exe, so always go DLL → windres → exe. And <code>-static -static-libgcc</code> on the DLL is mandatory: without it Windows may refuse to load the driver with “the specified module could not be found” (missing MinGW runtime).</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h2>Requirements</h2>
|
||||
<table>
|
||||
<tr><th>Where</th><th>What</th></tr>
|
||||
<tr><td>PS5</td><td>Jailbroken (payload loader + FTP + pldmgr autoloader)</td></tr>
|
||||
<tr><td>PS5</td><td>Latest tested firmware: <b>13.60</b> — see the FAQ for other versions</td></tr>
|
||||
<tr><td>PC</td><td>Windows 10/11 64-bit, wired network recommended</td></tr>
|
||||
<tr><td>Network</td><td>Both on the same LAN (gigabit is plenty for 1080p30)</td></tr>
|
||||
</table>
|
||||
<section id="faq" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">FAQ</div>
|
||||
<h2>Questions.</h2>
|
||||
</div>
|
||||
<div class="faq">
|
||||
<details><summary>Does it work on firmwares other than 13.60?</summary>
|
||||
<div class="body"><p>The PC side works with any firmware: the app and the driver only use TCP, FTP and shared memory. The console payload is the version-specific part. It was built and tuned on <b>13.60</b> using display-engine anchors found on that firmware. Other versions may need a small porting pass to find the same anchors. <a href="https://github.com/fstat13/PSCapture/issues">Open an issue</a> with your firmware version.</p></div></details>
|
||||
<details><summary>Why is the camera 720p in Discord calls?</summary>
|
||||
<div class="body"><p>That's Discord's voice engine: it requests 1280×720 from every camera. In OBS, PS5 Capture runs at the full 1920×1080. Discord's screen-share goes up to 1080p60 with Nitro.</p></div></details>
|
||||
<details><summary>Do I need a capture card or Remote Play?</summary>
|
||||
<div class="body"><p>No. PSCapture never touches Remote Play. The payload reads the display engine on the console itself and sends raw frames over your LAN.</p></div></details>
|
||||
<details><summary>Does it capture game audio?</summary>
|
||||
<div class="body"><p>Not yet. PSCapture is video-only for now.</p></div></details>
|
||||
<details><summary>Does it work on macOS or Linux?</summary>
|
||||
<div class="body"><p>The PC side is Windows-only, because the camera is a DirectShow device.</p></div></details>
|
||||
<details><summary>How do I uninstall it?</summary>
|
||||
<div class="body"><ol>
|
||||
<li>Close the app.</li>
|
||||
<li>Run <code>rundll32 "%ProgramFiles%\PSCapture\pscapture.dll",DllUnregisterServer</code> to remove the camera.</li>
|
||||
<li>Delete <code>C:\Program Files\PSCapture</code>.</li>
|
||||
<li>Optional, on the console: delete <code>/data/pldmgr/payloads/pscapture/</code> so the autoloader stops starting it.</li>
|
||||
</ol></div></details>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h2 id="faq">FAQ</h2>
|
||||
<div class="band reveal">
|
||||
<div>
|
||||
<h2>Useful? Leave a star.</h2>
|
||||
<p>PSCapture is free. A star on GitHub helps other PS5 homebrew users find it.</p>
|
||||
</div>
|
||||
<div class="cta">
|
||||
<a class="btn btn-primary" href="https://github.com/fstat13/PSCapture"><svg class="i"><use href="#i-star"/></svg>Star on GitHub <span class="stars" data-stars hidden></span></a>
|
||||
<a class="btn btn-ghost" href="https://github.com/fstat13/PSCapture/issues">Report an issue</a>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<details>
|
||||
<summary>Does it work on firmware versions older than 13.60?</summary>
|
||||
<p>The PC side works on every firmware: the app and the driver only speak
|
||||
TCP/FTP and shared memory. The console payload is the version-specific
|
||||
part — it was built and tuned on <b>13.60</b>, using display-engine
|
||||
anchors found on that firmware. On other firmwares it may need a small
|
||||
porting pass (the fix is finding the same anchors on that system).
|
||||
If you have another firmware, open an issue with your version and we
|
||||
can add a profile.</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Why is the call camera 720p and not 1080p?</summary>
|
||||
<p>That cap is Discord's voice engine, not PSCapture: it requests 1280x720
|
||||
from every camera. For full-quality capture use OBS (where PS5 Capture
|
||||
runs at 1920x1080) or Discord's screen-share, which goes up to
|
||||
1080p60 with Nitro.</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Is a capture card or Remote Play needed?</summary>
|
||||
<p>No. PSCapture never touches Remote Play: the payload reads the display
|
||||
engine on the console itself and streams raw frames over your LAN.</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>How do I uninstall it?</summary>
|
||||
<p>Close the app, then <code>rundll32 "%ProgramFiles%\PSCapture\pscapture.dll",DllUnregisterServer</code>,
|
||||
delete <code>C:\Program Files\PSCapture</code>, and optionally delete
|
||||
<code>/data/pldmgr/payloads/pscapture/</code> on the console so the
|
||||
autoloader stops starting the payload.</p>
|
||||
</details>
|
||||
|
||||
<footer>
|
||||
PSCapture — bring your PS5 screen anywhere on your LAN, no card, no cloud.
|
||||
<br><b>by fstat13</b> · source-available. Built for the homebrew community. <span class="ok">Play responsibly.</span>
|
||||
<br><br>
|
||||
Docs: <a href="GUIDE.md">fool-proof guide (md)</a> ·
|
||||
<a href="BUILD.md">build from source (md)</a> ·
|
||||
<a href="INSTALLER.md">what the installer does inside</a> ·
|
||||
<a href="REVERSE_ENGINEERING.md">reverse engineering</a> ·
|
||||
<a href="ENGINEERING_LOG.md">engineering log</a>
|
||||
</footer>
|
||||
</div>
|
||||
<footer>
|
||||
<div class="wrap">
|
||||
<div class="foot">
|
||||
<div>
|
||||
<a class="logo" href="#top"><img src="pscapture.png" alt="">PSCapture</a>
|
||||
<p>Your PS5 screen anywhere on your LAN. No card, no cloud.<br>by <b>fstat13</b></p>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Guides</h4>
|
||||
<ul>
|
||||
<li><a href="https://github.com/fstat13/PSCapture/blob/main/docs/GUIDE.md">Step-by-step guide</a></li>
|
||||
<li><a href="https://github.com/fstat13/PSCapture/blob/main/docs/BUILD.md">Build from source</a></li>
|
||||
<li><a href="https://github.com/fstat13/PSCapture/blob/main/docs/INSTALLER.md">What the installer does</a></li>
|
||||
<li><a href="https://github.com/fstat13/PSCapture/blob/main/docs/REVERSE_ENGINEERING.md">Reverse engineering</a></li>
|
||||
<li><a href="https://github.com/fstat13/PSCapture/blob/main/docs/ENGINEERING_LOG.md">Engineering log</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Project</h4>
|
||||
<ul>
|
||||
<li><a href="https://github.com/fstat13/PSCapture">GitHub</a></li>
|
||||
<li><a href="https://github.com/fstat13/PSCapture/releases">Releases</a></li>
|
||||
<li><a href="https://github.com/fstat13/PSCapture/issues">Issues</a></li>
|
||||
<li><a href="https://github.com/fstat13/PSCapture/blob/main/LICENSE">License</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="legal">
|
||||
<span>© 2026 fstat13 · source-available</span>
|
||||
<span>Not affiliated with Sony Interactive Entertainment. “PlayStation” and “PS5” are trademarks of their respective owners.</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
+398
-313
@@ -1,358 +1,443 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="it">
|
||||
<html lang="it" class="no-js">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>PSCapture di fstat13 — la PS5 come scheda di acquisizione sul PC</title>
|
||||
<style>
|
||||
:root{
|
||||
--bg:#0d1015; --card:#151a22; --card2:#1b222d; --line:#242c38;
|
||||
--fg:#e8edf4; --dim:#96a0b0; --accent:#0070d1; --accent2:#35a3ff;
|
||||
--rec:#e22236; --ok:#1fbf6b;
|
||||
}
|
||||
*{box-sizing:border-box}
|
||||
body{margin:0;background:var(--bg);color:var(--fg);
|
||||
font:16px/1.65 "Segoe UI",system-ui,-apple-system,Roboto,sans-serif;}
|
||||
a{color:var(--accent2);text-decoration:none}
|
||||
a:hover{text-decoration:underline}
|
||||
.wrap{max-width:880px;margin:0 auto;padding:0 20px}
|
||||
header{background:
|
||||
radial-gradient(900px 320px at 20% -40%, rgba(0,112,209,.35), transparent 60%),
|
||||
radial-gradient(700px 300px at 90% -30%, rgba(226,34,54,.22), transparent 60%),
|
||||
var(--bg);
|
||||
border-bottom:1px solid var(--line);padding:56px 0 40px}
|
||||
.brand{display:flex;align-items:center;gap:18px}
|
||||
.brand img{width:84px;height:84px;border-radius:20px;box-shadow:0 8px 30px rgba(0,0,0,.5)}
|
||||
h1{font-size:44px;margin:0;letter-spacing:.5px}
|
||||
.tag{color:var(--dim);font-size:18px;margin-top:6px}
|
||||
.badges{margin-top:22px;display:flex;gap:10px;flex-wrap:wrap}
|
||||
.badge{border:1px solid var(--line);background:var(--card);
|
||||
padding:5px 12px;border-radius:999px;font-size:13px;color:var(--dim)}
|
||||
.badge b{color:var(--fg)}
|
||||
h2{margin:52px 0 14px;font-size:26px}
|
||||
h3{margin:26px 0 10px;font-size:19px}
|
||||
.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px}
|
||||
.card{background:var(--card);border:1px solid var(--line);border-radius:14px;padding:18px 20px}
|
||||
.card h3{margin:0 0 8px;font-size:17px}
|
||||
.card p{margin:0;color:var(--dim);font-size:14.5px}
|
||||
.flow{display:flex;gap:10px;align-items:stretch;flex-wrap:wrap;margin-top:16px}
|
||||
.box{flex:1;min-width:180px;background:var(--card2);border:1px solid var(--line);
|
||||
border-radius:12px;padding:14px 16px}
|
||||
.box b{display:block;margin-bottom:6px}
|
||||
.box div{color:var(--dim);font-size:13.5px}
|
||||
.arrow{align-self:center;color:var(--accent2);font-size:22px;padding:0 2px}
|
||||
ol.steps{counter-reset:s;list-style:none;padding:0;margin:18px 0 0}
|
||||
ol.steps li{counter-increment:s;position:relative;padding:0 0 18px 54px}
|
||||
ol.steps li::before{content:counter(s);position:absolute;left:0;top:0;
|
||||
width:34px;height:34px;border-radius:10px;background:var(--accent);
|
||||
color:#fff;font-weight:600;display:flex;align-items:center;justify-content:center}
|
||||
ol.steps b{color:var(--fg)}
|
||||
ol.steps span{color:var(--dim)}
|
||||
ul.plain{color:var(--dim);padding-left:22px}
|
||||
ul.plain b{color:var(--fg)}
|
||||
table{width:100%;border-collapse:collapse;margin-top:14px;font-size:14.5px}
|
||||
th,td{text-align:left;padding:10px 12px;border-bottom:1px solid var(--line);
|
||||
vertical-align:top}
|
||||
th{color:var(--dim);font-weight:500}
|
||||
td code,th code{white-space:nowrap}
|
||||
code,kbd{background:#0a0d12;border:1px solid var(--line);border-radius:6px;
|
||||
padding:1px 7px;font:13.5px/1.5 Consolas,monospace;color:#cfe3ff}
|
||||
pre{background:#0a0d12;border:1px solid var(--line);border-radius:12px;
|
||||
padding:14px 16px;overflow-x:auto;font:13.5px/1.6 Consolas,monospace;
|
||||
color:#cfe3ff}
|
||||
pre .c{color:#5f7186}
|
||||
details{background:var(--card);border:1px solid var(--line);border-radius:12px;
|
||||
padding:14px 18px;margin:10px 0}
|
||||
summary{cursor:pointer;font-weight:600}
|
||||
details p{color:var(--dim);margin:10px 0 0}
|
||||
.note{background:linear-gradient(0deg,rgba(0,112,209,.08),rgba(0,112,209,.08)),
|
||||
var(--card);border:1px solid #23405f;border-radius:12px;padding:14px 18px;color:#cfe3ff}
|
||||
.warn{background:linear-gradient(0deg,rgba(226,34,54,.07),rgba(226,34,54,.07)),
|
||||
var(--card);border:1px solid #5f2330;border-radius:12px;padding:14px 18px;color:#f3cdd3}
|
||||
footer{color:var(--dim);border-top:1px solid var(--line);margin-top:70px;
|
||||
padding:26px 0 40px;font-size:13.5px}
|
||||
.dot{display:inline-block;width:9px;height:9px;border-radius:50%;
|
||||
background:var(--rec);margin-right:8px;vertical-align:1px}
|
||||
.ok{color:var(--ok);font-weight:600}
|
||||
.toc{display:flex;gap:8px;flex-wrap:wrap;margin-top:18px}
|
||||
.toc a{border:1px solid var(--line);background:var(--card);border-radius:999px;
|
||||
padding:4px 12px;font-size:13px}
|
||||
.lang{position:absolute;top:18px;right:22px;font-size:13.5px}
|
||||
</style>
|
||||
<title>PSCapture — la PS5 come scheda di acquisizione sul PC</title>
|
||||
<meta name="description" content="PSCapture trasforma una PS5 jailbroken in una scheda di acquisizione per il PC: lo schermo della console passa sulla tua rete locale e compare in Discord, OBS e ffmpeg come la webcam “PS5 Capture”.">
|
||||
<meta name="theme-color" content="#07090d">
|
||||
<link rel="icon" type="image/png" href="pscapture.png">
|
||||
<link rel="alternate" hreflang="en" href="https://fstat13.github.io/PSCapture/">
|
||||
<link rel="alternate" hreflang="it" href="https://fstat13.github.io/PSCapture/index.it.html">
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:locale" content="it_IT">
|
||||
<meta property="og:title" content="PSCapture — lo schermo della PS5, live sul tuo PC">
|
||||
<meta property="og:description" content="Lo schermo della PS5 compare in Discord, OBS e ffmpeg come la webcam “PS5 Capture”. Niente capture card, niente Remote Play, niente cloud.">
|
||||
<meta property="og:image" content="https://fstat13.github.io/PSCapture/pscapture.png">
|
||||
<meta property="og:url" content="https://fstat13.github.io/PSCapture/index.it.html">
|
||||
<meta name="twitter:card" content="summary">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<header style="position:relative">
|
||||
<div class="lang">🇬🇧 <a href="index.html">English</a></div>
|
||||
<svg width="0" height="0" style="position:absolute" aria-hidden="true">
|
||||
<symbol id="i-download" viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" y1="15" x2="12" y2="3"/></symbol>
|
||||
<symbol id="i-star" viewBox="0 0 24 24"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></symbol>
|
||||
<symbol id="i-check" viewBox="0 0 24 24"><polyline points="20 6 9 17 4 12"/></symbol>
|
||||
<symbol id="i-video" viewBox="0 0 24 24"><path d="m22 8-6 4 6 4V8Z"/><rect x="2" y="6" width="14" height="12" rx="2"/></symbol>
|
||||
<symbol id="i-zap" viewBox="0 0 24 24"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></symbol>
|
||||
<symbol id="i-file" viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/></symbol>
|
||||
<symbol id="i-refresh" viewBox="0 0 24 24"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></symbol>
|
||||
<symbol id="i-sliders" viewBox="0 0 24 24"><line x1="4" y1="21" x2="4" y2="14"/><line x1="4" y1="10" x2="4" y2="3"/><line x1="12" y1="21" x2="12" y2="12"/><line x1="12" y1="8" x2="12" y2="3"/><line x1="20" y1="21" x2="20" y2="16"/><line x1="20" y1="12" x2="20" y2="3"/><line x1="1" y1="14" x2="7" y2="14"/><line x1="9" y1="8" x2="15" y2="8"/><line x1="17" y1="16" x2="23" y2="16"/></symbol>
|
||||
<symbol id="i-lock" viewBox="0 0 24 24"><rect x="3" y="11" width="18" height="11" rx="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></symbol>
|
||||
<symbol id="i-console" viewBox="0 0 24 24"><rect x="2" y="6" width="20" height="12" rx="3"/><line x1="6" y1="12" x2="10" y2="12"/><line x1="8" y1="10" x2="8" y2="14"/><circle cx="16" cy="11" r=".6"/><circle cx="18" cy="13" r=".6"/></symbol>
|
||||
<symbol id="i-monitor" viewBox="0 0 24 24"><rect x="2" y="3" width="20" height="14" rx="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></symbol>
|
||||
<symbol id="i-info" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><line x1="12" y1="16" x2="12" y2="12"/><line x1="12" y1="8" x2="12.01" y2="8"/></symbol>
|
||||
<symbol id="i-alert" viewBox="0 0 24 24"><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></symbol>
|
||||
<symbol id="i-search" viewBox="0 0 24 24"><circle cx="11" cy="11" r="8"/><line x1="21" y1="21" x2="16.65" y2="16.65"/></symbol>
|
||||
</svg>
|
||||
|
||||
<nav class="nav">
|
||||
<div class="wrap">
|
||||
<div class="brand">
|
||||
<img src="pscapture.png" alt="PSCapture">
|
||||
<div>
|
||||
<h1>PSCapture</h1>
|
||||
<div class="tag">Lo schermo della PlayStation 5, live sul tuo PC — come una vera scheda di acquisizione.</div>
|
||||
<a class="logo" href="#top"><img src="pscapture.png" alt="">PSCapture</a>
|
||||
<div class="nav-links">
|
||||
<a href="#how">Come funziona</a>
|
||||
<a href="#start">Installazione</a>
|
||||
<a href="#trouble">Problemi</a>
|
||||
<a href="#build">Build</a>
|
||||
<a href="#faq">FAQ</a>
|
||||
</div>
|
||||
<div class="nav-right">
|
||||
<a class="lang" href="index.html" hreflang="en">English</a>
|
||||
<a class="btn btn-ghost btn-sm" href="https://github.com/fstat13/PSCapture"><svg class="i"><use href="#i-star"/></svg>Star <span class="stars" data-stars hidden></span></a>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<header class="hero" id="top">
|
||||
<div class="wrap hero-grid">
|
||||
<div>
|
||||
<span class="eyebrow"><span class="tagv">v0.1</span>Testato sul firmware PS5 13.60</span>
|
||||
<h1>Lo schermo della PS5,<br><span class="grad">live sul tuo PC.</span></h1>
|
||||
<p class="lead">PSCapture trasforma una PlayStation 5 jailbroken in una scheda di acquisizione.
|
||||
La console manda il proprio schermo sulla tua rete locale e Windows lo vede come una
|
||||
webcam chiamata <b>PS5 Capture</b>, pronta per Discord, OBS e ffmpeg.</p>
|
||||
<div class="cta">
|
||||
<a class="btn btn-primary" href="https://github.com/fstat13/PSCapture/releases"><svg class="i"><use href="#i-download"/></svg>Scarica per Windows</a>
|
||||
<a class="btn btn-ghost" href="https://github.com/fstat13/PSCapture"><svg class="i"><use href="#i-star"/></svg>Metti una stella <span class="stars" data-stars hidden></span></a>
|
||||
</div>
|
||||
<div class="hero-meta">
|
||||
<span><svg class="i"><use href="#i-check"/></svg>Niente capture card</span>
|
||||
<span><svg class="i"><use href="#i-check"/></svg>Niente Remote Play</span>
|
||||
<span><svg class="i"><use href="#i-check"/></svg>Niente cloud</span>
|
||||
<span><svg class="i"><use href="#i-check"/></svg>Un solo .exe</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="badges">
|
||||
<span class="badge"><b>PS5</b> jailbroken</span>
|
||||
<span class="badge"><b>Windows</b> 10 / 11</span>
|
||||
<span class="badge"><span class="dot"></span><b>Niente</b> capture card</span>
|
||||
<span class="badge"><b>Niente</b> Remote Play</span>
|
||||
<span class="badge">1080p · ~30 fps</span>
|
||||
|
||||
<div class="app" role="img" aria-label="La finestra di PSCapture: il log mostra il controllo del driver, l'invio del payload e la connessione dello stream; la pillola di stato dice STREAMING.">
|
||||
<div class="app-bar">
|
||||
<img src="pscapture.png" alt="">
|
||||
<span class="t">PSCapture by fstat13 - PS5 screen to PC</span>
|
||||
<span class="w"><span>–</span><span>□</span><span>✕</span></span>
|
||||
</div>
|
||||
<div class="app-body">
|
||||
<div class="app-head">
|
||||
<div class="app-title">PSCapture<small>PS5 screen to PC</small></div>
|
||||
<span class="pill live"><i></i> STREAMING 29.8 fps</span>
|
||||
</div>
|
||||
<div class="app-row">
|
||||
<span class="app-lbl">PS5 IP</span><span class="app-in">192.168.0.36</span>
|
||||
<span class="app-btn">Deploy payload</span><span class="app-btn">Install driver</span>
|
||||
</div>
|
||||
<div class="app-row">
|
||||
<span class="app-btn big">START STREAMING</span><span class="app-btn stop">STOP</span>
|
||||
<span class="app-knobs app-row" style="margin:0">
|
||||
<span class="app-lbl">gain</span><span class="app-in">1.0</span>
|
||||
<span class="app-lbl">shift px</span><span class="app-in">0</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="app-log" aria-hidden="true">
|
||||
<div>PSCapture pronto: premo Start e faccio tutto da solo.</div>
|
||||
<div>--- AVVIO AUTOMATICO ---</div>
|
||||
<div>driver gia' installato</div>
|
||||
<div>payload dall'eseguibile (175480 byte)</div>
|
||||
<div>payload 175480 byte, invio a 192.168.0.36</div>
|
||||
<div>autoloader aggiornato (pldmgr)</div>
|
||||
<div class="hl">payload avviato - la PS5 deve mostrare la notifica PSCapture</div>
|
||||
<div>porta stream: 5599</div>
|
||||
<div class="ok">collegato a 192.168.0.36:5599</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="toc">
|
||||
<a href="#start">Avvio rapido</a>
|
||||
<a href="#daily">Uso quotidiano</a>
|
||||
<a href="#trouble">Problemi</a>
|
||||
<a href="#build">Build dai sorgenti</a>
|
||||
<a href="#faq">FAQ</a>
|
||||
</div>
|
||||
|
||||
<div class="wrap">
|
||||
<div class="stats">
|
||||
<div class="stat"><div class="n">1920×1080</div><div class="l">full HD in OBS</div></div>
|
||||
<div class="stat"><div class="n">~30 fps</div><div class="l">su una normale LAN</div></div>
|
||||
<div class="stat"><div class="n">0</div><div class="l">ricodifiche sulla console</div></div>
|
||||
<div class="stat"><div class="n">1 file</div><div class="l">driver e payload inclusi</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="wrap">
|
||||
<main class="wrap">
|
||||
|
||||
<h2>Cos'è</h2>
|
||||
<div class="cards">
|
||||
<div class="card">
|
||||
<h3>🎥 Scheda di acquisizione virtuale</h3>
|
||||
<p>PSCapture registra un dispositivo DirectShow chiamato <b>PS5 Capture</b>.
|
||||
Discord, OBS e ffmpeg lo vedono come un'Elgato — scegli la camera e vai
|
||||
live.</p>
|
||||
<section id="why" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">Perché PSCapture</div>
|
||||
<h2>Una capture card, senza la capture card.</h2>
|
||||
<p class="sub">Funziona tutto con quello che hai già: la console, la tua rete e il tuo PC.</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>⚡ Direttamente dalla GPU</h3>
|
||||
<p>Il payload sulla console legge direttamente il buffer di scan-out del
|
||||
display engine e manda i frame NV12 sulla tua LAN. Nessuna
|
||||
ricodifica, nessun cloud.</p>
|
||||
<div class="grid g3">
|
||||
<div class="card"><div class="ico"><svg class="i"><use href="#i-video"/></svg></div>
|
||||
<h3>Una vera webcam</h3>
|
||||
<p>Un filtro sorgente DirectShow chiamato <b>PS5 Capture</b>. Qualsiasi programma che apre una webcam può aprire la tua console.</p></div>
|
||||
<div class="card"><div class="ico v"><svg class="i"><use href="#i-zap"/></svg></div>
|
||||
<h3>Direttamente dal display engine</h3>
|
||||
<p>Il payload legge il buffer di scan-out della console e manda frame NV12 grezzi. Niente ricodifica, quindi niente attese per un encoder.</p></div>
|
||||
<div class="card"><div class="ico g"><svg class="i"><use href="#i-file"/></svg></div>
|
||||
<h3>Un file, una finestra</h3>
|
||||
<p><b>PSCapture.exe</b> installa il driver, manda il payload, lo registra nell'autoloader e si collega. Tutto da solo.</p></div>
|
||||
<div class="card"><div class="ico a"><svg class="i"><use href="#i-refresh"/></svg></div>
|
||||
<h3>Si riprende da solo</h3>
|
||||
<p>Console ancora spenta? Riprova ogni 2 secondi. Stream caduto? Si ricollega. Non devi stargli dietro.</p></div>
|
||||
<div class="card"><div class="ico"><svg class="i"><use href="#i-sliders"/></svg></div>
|
||||
<h3>Regolazioni in diretta</h3>
|
||||
<p><code>gain</code> del colore e <code>shift</code> orizzontale si applicano in circa un secondo e restano salvati in <code>pscapture.ini</code>.</p></div>
|
||||
<div class="card"><div class="ico v"><svg class="i"><use href="#i-lock"/></svg></div>
|
||||
<h3>Resta nella tua rete</h3>
|
||||
<p>Niente account, niente server esterni, niente Remote Play. I frame vanno dalla console al PC e basta.</p></div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>🖱️ Un solo eseguibile</h3>
|
||||
<p><b>PSCapture.exe</b> contiene già il payload per la console:
|
||||
installa il driver, manda il payload, avvia lo stream — una finestra,
|
||||
un click.</p>
|
||||
</section>
|
||||
|
||||
<section id="how" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">Come funziona</div>
|
||||
<h2>Tre pezzi piccoli, una webcam.</h2>
|
||||
<p class="sub">Un payload sulla console, un feeder e un driver sul PC. I programmi che usi già vedono semplicemente una webcam.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pipe">
|
||||
<div class="node"><div class="where">PS5</div><h3>Payload</h3>
|
||||
<p>Legge il ring di scan-out del display engine, costruisce i frame NV12 e li serve sulla porta TCP <code>5599</code>. Mostra la notifica <i>“PSCapture is streaming on:5599”</i>.</p></div>
|
||||
<div class="link"><span>TCP · NV12<br>rete locale</span><div class="line"></div></div>
|
||||
<div class="node"><div class="where">PC · PSCapture.exe</div><h3>Feeder</h3>
|
||||
<p>Riceve i frame e li pubblica in un ring di memoria condivisa.</p></div>
|
||||
<div class="link"><span>memoria<br>condivisa</span><div class="line"></div></div>
|
||||
<div class="node"><div class="where">PC · pscapture.dll</div><h3>Driver</h3>
|
||||
<p>Un filtro sorgente DirectShow che espone il ring come la webcam <b>PS5 Capture</b>.</p></div>
|
||||
<div class="link"><span>DirectShow</span><div class="line"></div></div>
|
||||
<div class="node end"><div class="where">I tuoi programmi</div><h3>Qualsiasi app video</h3>
|
||||
<p>Scegli <b>PS5 Capture</b> come una webcam qualunque.</p>
|
||||
<div class="chips"><span class="chip">Discord</span><span class="chip">OBS</span><span class="chip">ffmpeg</span></div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h2>Come funziona</h2>
|
||||
<div class="flow">
|
||||
<div class="box"><b>PS5 · payload</b>
|
||||
<div>legge il ring di scan-out del display engine, costruisce i frame
|
||||
NV12, li serve su una porta TCP e mostra il toast:
|
||||
<i>“PSCapture is streaming on:PORT”</i>.</div></div>
|
||||
<div class="arrow">→</div>
|
||||
<div class="box"><b>PC · feeder</b>
|
||||
<div>riceve i frame e li pubblica in un ring di memoria condivisa.</div></div>
|
||||
<div class="arrow">→</div>
|
||||
<div class="box"><b>PC · driver</b>
|
||||
<div>il filtro DirectShow espone il ring come una camera per tutti i
|
||||
programmi.</div></div>
|
||||
</div>
|
||||
<section id="requirements" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">Prima di iniziare</div>
|
||||
<h2>Cosa ti serve.</h2>
|
||||
</div>
|
||||
<div class="grid g2">
|
||||
<div class="req">
|
||||
<div class="req-h"><div class="ico"><svg class="i"><use href="#i-console"/></svg></div><h3>Sulla PS5</h3></div>
|
||||
<ul>
|
||||
<li><svg class="i"><use href="#i-check"/></svg><span>Una console jailbroken<small>Sviluppato e tarato sul firmware <b>13.60</b>. Per le altre versioni vedi la FAQ.</small></span></li>
|
||||
<li><svg class="i"><use href="#i-check"/></svg><span>Payload loader sulla porta TCP <code>9021</code><small>Tipo <code>elfldr</code>, come in tutti i setup di jailbreak attuali.</small></span></li>
|
||||
<li><svg class="i"><use href="#i-check"/></svg><span>FTP anonimo sulla porta TCP <code>2121</code><small>L'app legge e scrive alcuni file sulla console.</small></span></li>
|
||||
<li class="opt"><svg class="i"><use href="#i-check"/></svg><span>Autoloader <code>pldmgr</code> <span class="tagopt">opzionale</span><small>Avvia il payload a ogni accensione, così non devi mai mandarlo a mano.</small></span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="req">
|
||||
<div class="req-h"><div class="ico v"><svg class="i"><use href="#i-monitor"/></svg></div><h3>Sul PC</h3></div>
|
||||
<ul>
|
||||
<li><svg class="i"><use href="#i-check"/></svg><span>Windows 10 o 11, 64 bit<small>La webcam è un dispositivo DirectShow, quindi il lato PC è solo per Windows.</small></span></li>
|
||||
<li><svg class="i"><use href="#i-check"/></svg><span>Stessa rete della console<small>Meglio via cavo. Il gigabit basta e avanza per 1080p a 30 fps.</small></span></li>
|
||||
<li><svg class="i"><use href="#i-check"/></svg><span>Permessi di amministratore, una volta<small>Per registrare la webcam per tutti i programmi del PC.</small></span></li>
|
||||
<li><svg class="i"><use href="#i-check"/></svg><span><b>PSCapture.exe</b> dalle <a href="https://github.com/fstat13/PSCapture/releases">Releases</a><small>Un unico file: payload e driver sono già dentro.</small></span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h2 id="start">Avvio rapido — passo per passo</h2>
|
||||
<section id="start" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">Installazione</div>
|
||||
<h2>Da zero a live in cinque passi.</h2>
|
||||
<p class="sub">Dal passo 2 in poi ti basta guardare: l'app fa il resto e ti dice cosa sta facendo.</p>
|
||||
</div>
|
||||
<ol class="steps">
|
||||
<li><h3>Fai il jailbreak della console</h3>
|
||||
<p>Avvia il tuo solito jailbreak, così il payload loader (<code>9021</code>) e l'FTP (<code>2121</code>) sono attivi.</p></li>
|
||||
<li><h3>Doppio clic su <code>PSCapture.exe</code></h3>
|
||||
<p>Windows chiede <i>“Consentire a questa app di apportare modifiche al dispositivo?”</i>. Clicca <b>Sì</b>. L'app chiede da sola i permessi, non serve il tasto destro.</p></li>
|
||||
<li><h3>Controlla l'IP</h3>
|
||||
<p>Quello predefinito è <code>192.168.0.36</code>. Se la tua PS5 ha un altro indirizzo, scrivilo in <b>PS5 IP</b> e premi <b>Apply</b>: viene ricordato. Lo trovi sulla console in <i>Impostazioni → Rete → Stato della connessione → Visualizza stato della connessione</i>.</p></li>
|
||||
<li><h3>Non toccare niente</h3>
|
||||
<p>Al primo avvio l'app installa il driver, poi manda il payload e si collega. Sulla console compare <i>“PSCapture is streaming on:5599”</i> e la pillola di stato diventa <b style="color:var(--green)">verde: STREAMING</b>.</p></li>
|
||||
<li><h3>Scegli <b>PS5 Capture</b> nel tuo programma</h3>
|
||||
<p>Discord, OBS o ffmpeg. Più sotto trovi <a href="#use">dove trovarla</a>.</p></li>
|
||||
</ol>
|
||||
|
||||
<div class="note" style="margin-bottom:20px">
|
||||
<b>Cosa serve prima.</b> Una PS5 jailbroken con il setup standard:
|
||||
un payload loader sulla porta TCP <code>9021</code> (tipo
|
||||
<code>elfldr</code>), FTP anonimo sulla <code>2121</code>, e opzionalmente
|
||||
l'autoloader <code>pldmgr</code> così il payload parte a ogni boot.
|
||||
PC e console sulla stessa LAN. Scarica <b>PSCapture.exe</b> dalla pagina
|
||||
Releases — <b>è un unico file</b>: il payload per la console e il driver
|
||||
per Windows sono dentro di lui.
|
||||
</div>
|
||||
<h3 style="margin:30px 0 6px">Come leggere il log</h3>
|
||||
<p style="color:var(--dim)">Queste sono le righe che vedrai, nell'ordine in cui compaiono.</p>
|
||||
<div class="term" style="margin-top:14px">
|
||||
<div class="term-bar"><i></i><i></i><i></i><b>pscapture-app.log</b></div>
|
||||
<div class="term-row"><code>driver gia' installato</code><span class="m">La webcam è già registrata. Niente da fare.</span></div>
|
||||
<div class="term-row"><code>driver non installato: lo installo ora (primo avvio)<br>driver estratto dall'eseguibile (… byte)<br>driver registrato - la webcam 'PS5 Capture' e' pronta</code><span class="m">Primo avvio: il driver viene estratto dall'exe e registrato.</span></div>
|
||||
<div class="term-row"><code>payload dall'eseguibile (… byte)<br>payload … byte, invio a 192.168.0.36</code><span class="m">Il payload sta andando verso la console.</span></div>
|
||||
<div class="term-row"><code>autoloader aggiornato (pldmgr)</code><span class="m">Il payload è stato copiato nell'autoloader: partirà a ogni accensione.</span></div>
|
||||
<div class="term-row"><code>payload avviato - la PS5 deve mostrare la notifica PSCapture</code><span class="m">Il payload gira. Cerca la notifica sulla TV.</span></div>
|
||||
<div class="term-row ok"><code>porta stream: 5599<br>collegato a 192.168.0.36:5599</code><span class="m">Collegato. La pillola dice <b>STREAMING</b> con gli fps in tempo reale.</span></div>
|
||||
</div>
|
||||
|
||||
<ol class="steps">
|
||||
<li><b>Fai il jailbreak della console</b><br>
|
||||
<span>Qualsiasi jailbreak kernel-capable che ti dia il payload loader
|
||||
(:9021), l'FTP anonimo (:2121) e — opzionale — l'autoloader
|
||||
<code>pldmgr</code>.</span></li>
|
||||
<li><b>Doppio click su <code>PSCapture.exe</code></b><br>
|
||||
<span>Windows chiede <i>“Consenti a questa app di apportare modifiche?”</i>
|
||||
→ <b>Sì</b>. L'app si eleva da sola; i privilegi servono una volta, per
|
||||
registrare la webcam virtuale per tutti i programmi.</span></li>
|
||||
<li><b>Controlla l'IP</b><br>
|
||||
<span>Se la tua PS5 non è a <code>192.168.0.36</code>, scrivi il suo
|
||||
indirizzo nel campo <b>PS5 IP</b> e premi <b>Apply</b>.</span></li>
|
||||
<li><b>Guarda e non premere niente</b><br>
|
||||
<span>L'app fa tutto da sola, e te lo racconta nel pannello log scuro
|
||||
(tabella qui sotto). Sulla console vedrai anche la notifica di sistema
|
||||
<i>“PSCapture is streaming on:PORT”</i>.</span></li>
|
||||
<li><b>Usalo in qualsiasi programma</b><br>
|
||||
<span>Discord (in chiamata): <i>Impostazioni → Voce e video →
|
||||
Telecamera</i> → <b>PS5 Capture</b> (720p — Discord chiede 720p a tutte
|
||||
le camere, capture card incluse). OBS: aggiungi un <i>Video Capture
|
||||
Device</i> → <b>1920x1080</b> pieno. ffmpeg:
|
||||
<code>-f dshow -i video="PS5 Capture"</code>.</span></li>
|
||||
</ol>
|
||||
<div class="callout warn" style="margin-top:18px">
|
||||
<svg class="i"><use href="#i-alert"/></svg>
|
||||
<p><b>Pillola ferma su “IN ATTESA DELLA PS5”?</b> La console è spenta, il jailbreak non è ancora partito o l'IP è sbagliato. Non serve riavviare niente: l'app riprova ogni 2 secondi e si collega appena le porte <code>9021</code> e <code>2121</code> rispondono.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h3>Cosa devi vedere nel log dell'app</h3>
|
||||
<table>
|
||||
<tr><th>Riga</th><th>Significato</th></tr>
|
||||
<tr><td><code>driver gia' installato</code></td>
|
||||
<td>camera già registrata — niente da fare</td></tr>
|
||||
<tr><td><code>driver estratto dall'eseguibile (… byte)</code><br>
|
||||
<code>driver registrato - la webcam 'PS5 Capture' e' pronta</code></td>
|
||||
<td>primo avvio: il driver è stato estratto dall'exe e registrato</td></tr>
|
||||
<tr><td><code>payload dall'eseguibile (… byte)</code></td>
|
||||
<td>il payload sta viaggiando verso la PS5</td></tr>
|
||||
<tr><td><code>payload avviato - la PS5 deve mostrare la notifica PSCapture</code></td>
|
||||
<td>il payload sta girando sulla console</td></tr>
|
||||
<tr><td><code>porta stream: 9xxx</code> → <code>collegato a …:9xxx</code></td>
|
||||
<td>stream connesso — la pillola diventa <span class="ok">verde: STREAMING</span></td></tr>
|
||||
</table>
|
||||
<section id="use" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">Usalo</div>
|
||||
<h2>Funziona ovunque funzioni una webcam.</h2>
|
||||
</div>
|
||||
<div class="grid g3">
|
||||
<div class="card target"><h3>Discord</h3>
|
||||
<div class="path"><i>Impostazioni → Voce e video → Videocamera</i> → <b>PS5 Capture</b></div>
|
||||
<p style="margin-top:10px">Discord chiede 720p a tutte le webcam, capture card comprese. Per il 1080p60 usa la condivisione schermo (Nitro).</p>
|
||||
<div class="res">in chiamata <b>1280×720</b></div></div>
|
||||
<div class="card target"><h3>OBS Studio</h3>
|
||||
<div class="path"><i>Fonti → + → Dispositivo di acquisizione video</i> → <b>PS5 Capture</b></div>
|
||||
<p style="margin-top:10px">Risoluzione piena, pronta per registrare o andare in live.</p>
|
||||
<div class="res">nativo <b>1920×1080</b></div></div>
|
||||
<div class="card target"><h3>ffmpeg</h3>
|
||||
<div class="path"><code>ffmpeg -f dshow -i video="PS5 Capture" capture.mkv</code></div>
|
||||
<p style="margin-top:10px">Per catture da script e test veloci.</p>
|
||||
<div class="res">nativo <b>1920×1080</b></div></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="warn" style="margin-top:18px">
|
||||
<b>Pillola ferma su “IN ATTESA DELLA PS5 — accesa e col jailbreak avviato?”</b><br>
|
||||
La console è spenta, non ancora jailbroken, o l'IP è sbagliato. L'app
|
||||
riprova ogni 2 secondi: nel momento in cui la console è pronta si connette
|
||||
da sola. Porte da controllare sulla console: <code>9021</code> e
|
||||
<code>2121</code> devono essere aperte.
|
||||
</div>
|
||||
<section id="daily" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">Uso quotidiano</div>
|
||||
<h2>Aprilo e gioca.</h2>
|
||||
</div>
|
||||
<div class="grid g3">
|
||||
<div class="card knob"><span class="k">ogni giorno</span>
|
||||
<p>Apri <b>PSCapture.exe</b> e accetta il prompt UAC. Con l'autoloader lo stream parte da solo.</p>
|
||||
<ul>
|
||||
<li><b>Deploy payload</b>: rimanda il payload a mano, dopo un riavvio senza autoloader.</li>
|
||||
<li><b>Install driver</b>: registra di nuovo la webcam se il log mostra un errore del driver.</li>
|
||||
<li><b>STOP</b> o chiudere l'app: la webcam si ferma sull'ultimo frame e resta nell'elenco.</li>
|
||||
</ul></div>
|
||||
<div class="card knob"><span class="k">gain</span>
|
||||
<p>Intensità del colore (croma).</p>
|
||||
<ul><li><code>1.0</code> è il valore grezzo e corretto.</li><li>Cambialo solo se i colori sembrano sbagliati.</li></ul></div>
|
||||
<div class="card knob"><span class="k">shift px</span>
|
||||
<p>Sposta l'immagine a destra o a sinistra.</p>
|
||||
<ul><li><b>Solo numeri pari</b>: un valore dispari scambia i colori.</li><li>Le scritte dei titoli della console sono un buon riferimento.</li></ul></div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h2 id="daily">Uso quotidiano e regolazioni</h2>
|
||||
<ul class="plain">
|
||||
<li>Apri <b>PSCapture.exe</b> (UAC → Sì). Se il payload è già sulla console
|
||||
(autoloader) lo stream parte da solo; altrimenti premi
|
||||
<b>Deploy payload</b> una volta.</li>
|
||||
<li><b>Stop</b> / chiudere l'app ferma lo stream — la camera si congela
|
||||
sull'ultimo frame e gli altri programmi continuano a vedere il
|
||||
dispositivo.</li>
|
||||
<li><b>gain</b> — forza del colore. <b>Lascia 1.0</b> (grezzo) a meno che i
|
||||
colori non sembrino sbagliati.</li>
|
||||
<li><b>shift px</b> — allineamento orizzontale. <b>Solo numeri PARI</b>
|
||||
(un valore dispari inverte i colori). Si applica in diretta ed è
|
||||
salvato in <code>pscapture.ini</code> accanto all'exe.</li>
|
||||
</ul>
|
||||
<section id="trouble" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">Problemi</div>
|
||||
<h2>Sintomo → rimedio.</h2>
|
||||
<p class="sub">Scrivi cosa vedi, oppure incolla una riga del log.</p>
|
||||
</div>
|
||||
<div class="search"><svg class="i"><use href="#i-search"/></svg>
|
||||
<input id="q" type="search" placeholder="es. nera, 720p, err=126, ATTESA…" autocomplete="off" aria-label="Filtra i problemi"></div>
|
||||
<div class="issues">
|
||||
<div class="issue"><div class="sym">La pillola resta su <code>AVVIO…</code> o <code>IN ATTESA DELLA PS5</code></div>
|
||||
<div class="fix"><span class="cause">console spenta, senza jailbreak o IP sbagliato</span>Accendi la console, avvia il jailbreak (le porte 9021 e 2121 devono essere attive), controlla il campo <b>PS5 IP</b>. L'app continua a riprovare.</div></div>
|
||||
<div class="issue"><div class="sym">Il log ripete <code>PS5 non raggiungibile (…), riprovo</code></div>
|
||||
<div class="fix"><span class="cause">console non raggiungibile</span>Come sopra. Si collega da sola appena la console risponde.</div></div>
|
||||
<div class="issue"><div class="sym">Log: <code>elfldr :9021 non raggiungibile</code></div>
|
||||
<div class="fix"><span class="cause">payload loader non attivo</span>Rilancia il jailbreak, poi premi <b>Deploy payload</b>.</div></div>
|
||||
<div class="issue"><div class="sym">La webcam <b>PS5 Capture</b> non compare in Discord o OBS</div>
|
||||
<div class="fix"><span class="cause">driver non registrato</span>Premi <b>Install driver</b> e leggi la riga successiva del log: riporta l'errore vero.</div></div>
|
||||
<div class="issue"><div class="sym">Log: <code>ERRORE: driver non scrivibile in C:\Program Files\PSCapture (serve admin?)</code></div>
|
||||
<div class="fix"><span class="cause">app senza permessi di amministratore</span>Chiudila, riapri <code>PSCapture.exe</code> e rispondi <b>Sì</b> al prompt UAC.</div></div>
|
||||
<div class="issue"><div class="sym">Log: <code>elevazione rifiutata: continuo senza privilegi</code></div>
|
||||
<div class="fix"><span class="cause">al prompt UAC hai risposto “No”</span>Lo stream può funzionare lo stesso, ma il driver non si installa. Riavvia l'app e clicca <b>Sì</b>.</div></div>
|
||||
<div class="issue"><div class="sym">Log: <code>ERRORE caricamento dll (err=126)</code></div>
|
||||
<div class="fix"><span class="cause">l'antivirus ha messo in quarantena il driver</span>Ripristina e consenti <code>pscapture.dll</code> nell'antivirus, poi premi di nuovo <b>Install driver</b>.</div></div>
|
||||
<div class="issue"><div class="sym">Log: <code>autoloader: copia FALLITA (pldmgr c'e'?)</code></div>
|
||||
<div class="fix"><span class="cause"><code>pldmgr</code> non installato</span>Nessun danno: lo stream funziona. Senza autoloader, però, dopo ogni riavvio della console devi premere <b>Deploy payload</b>.</div></div>
|
||||
<div class="issue"><div class="sym">La webcam compare ma l'immagine è nera</div>
|
||||
<div class="fix"><span class="cause">stream non partito</span>Guarda la pillola. Premi <b>Deploy payload</b> e/o <b>START STREAMING</b>.</div></div>
|
||||
<div class="issue"><div class="sym">Log: <code>stream caduto, riconnetto</code></div>
|
||||
<div class="fix"><span class="cause">problema di rete o console in modalità riposo</span>L'app si ricollega da sola. Se succede spesso, passa dal Wi-Fi al cavo.</div></div>
|
||||
<div class="issue"><div class="sym">I colori sembrano sbagliati (pelle rossastra, cielo arancione)</div>
|
||||
<div class="fix"><span class="cause">hai cambiato <code>gain</code></span>Rimetti <code>gain</code> a <code>1.0</code> e premi <b>Apply</b>.</div></div>
|
||||
<div class="issue"><div class="sym">Colori invertiti, barra nera, immagine decentrata</div>
|
||||
<div class="fix"><span class="cause">allineamento</span>Regola <code>shift px</code> usando solo valori <b>pari</b>. Un valore dispari scambia i colori.</div></div>
|
||||
<div class="issue"><div class="sym">Discord mostra solo 720p</div>
|
||||
<div class="fix"><span class="cause">limite di Discord, non di PSCapture</span>In chiamata Discord limita ogni webcam a 720p. Usa OBS per il 1080p, o la condivisione schermo di Discord (1080p60 con Nitro).</div></div>
|
||||
<div class="issue"><div class="sym">OBS vede la webcam, Discord no</div>
|
||||
<div class="fix"><span class="cause">Discord era aperto durante l'installazione del driver</span>Chiudi Discord del tutto (anche dall'icona nella tray) e riaprilo.</div></div>
|
||||
<div class="issue"><div class="sym">Tutto il resto</div>
|
||||
<div class="fix"><span class="cause">leggi i log</span><code>pscapture-app.log</code> (accanto all'exe o in <code>%TEMP%</code>) e il log della console <code>/data/pscapture.log</code> via FTP. Poi <a href="https://github.com/fstat13/PSCapture/issues">apri una issue</a> allegandoli.</div></div>
|
||||
<div class="noresult" hidden>Nessun risultato. <a href="https://github.com/fstat13/PSCapture/issues">Apri una issue</a> con il tuo <code>pscapture-app.log</code>.</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h2 id="trouble">Problemi — sintomo → rimedio</h2>
|
||||
<table>
|
||||
<tr><th>Sintomo</th><th>Causa → rimedio</th></tr>
|
||||
<tr><td>La pillola resta su <code>AVVIO…</code> / <code>IN ATTESA DELLA PS5</code></td>
|
||||
<td>Console spenta o non jailbroken, o IP sbagliato → accendila, avvia
|
||||
il jailbreak, controlla il campo IP</td></tr>
|
||||
<tr><td>Il log ripete <code>PS5 non raggiungibile</code></td>
|
||||
<td>Come sopra — l'app riprova da sola</td></tr>
|
||||
<tr><td>La camera <b>PS5 Capture</b> non appare in Discord/OBS</td>
|
||||
<td>Driver mai registrato → premi <b>Install driver</b>; il log ora
|
||||
riporta l'errore vero</td></tr>
|
||||
<tr><td><code>ERRORE: driver non scrivibile in C:\Program Files\PSCapture (serve admin?)</code></td>
|
||||
<td>App non elevata → riavvia PSCapture.exe e accetta il prompt UAC</td></tr>
|
||||
<tr><td><code>ERRORE caricando la dll (err=126)</code></td>
|
||||
<td>L'antivirus ha messo in quarantena la dll estratta → sblocca
|
||||
<code>pscapture.dll</code> nell'antivirus, poi premi di nuovo
|
||||
<b>Install driver</b></td></tr>
|
||||
<tr><td>La camera appare ma l'immagine è nera</td>
|
||||
<td>Stream non partito → controlla la pillola, premi <b>Deploy
|
||||
payload</b> e/o <b>START STREAMING</b></td></tr>
|
||||
<tr><td>I colori sembrano sbagliati</td>
|
||||
<td>Hai toccato <code>gain</code> → rimettilo a 1.0 e Apply</td></tr>
|
||||
<tr><td>Immagine decentrata / barra nera</td>
|
||||
<td>Allineamento → regola <code>shift px</code> con numeri pari</td></tr>
|
||||
<tr><td>Discord mostra 720p</td>
|
||||
<td>Il motore di Discord limita ogni camera a 720p → usa OBS per il
|
||||
1080p</td></tr>
|
||||
<tr><td>OBS vede la camera, Discord no</td>
|
||||
<td>Discord era aperto prima dell'installazione del driver → chiudilo
|
||||
COMPLETAMENTE (anche dalla tray) e riaprilo</td></tr>
|
||||
<tr><td>Tutto il resto</td>
|
||||
<td>Leggi <code>pscapture-app.log</code> (accanto all'exe o in
|
||||
<code>%TEMP%</code>) e il log della console
|
||||
<code>/data/pscapture.log</code> via FTP</td></tr>
|
||||
</table>
|
||||
<section id="build" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">Build dai sorgenti</div>
|
||||
<h2>Due metà, due toolchain.</h2>
|
||||
<p class="sub">La repo contiene solo i sorgenti; i binari pronti sono nelle <a href="https://github.com/fstat13/PSCapture/releases">Releases</a>. La guida completa (installazione toolchain, verifiche, trappole) è in <a href="https://github.com/fstat13/PSCapture/blob/main/docs/BUILD.it.md">BUILD.it.md</a>.</p>
|
||||
</div>
|
||||
|
||||
<h2 id="build">Build dai sorgenti</h2>
|
||||
<div class="build-step">
|
||||
<div class="num">Passo 1 · console</div>
|
||||
<h3>Payload → <code>pscapture.elf</code></h3>
|
||||
<p>Servono Docker e l'immagine del PS5 payload SDK (prospero-clang; va bene qualsiasi tag, qui <code>ps5sdk:18</code>).</p>
|
||||
<div class="codeblock"><pre><span class="p">$ </span>docker run --rm -v "$PWD/payload:/payload" -w /payload ps5sdk:18 make</pre></div>
|
||||
</div>
|
||||
|
||||
<p style="color:var(--dim)">Solo sorgenti — nella repo non ci sono binari.
|
||||
Due metà, due toolchain. Il walk-through completo (installazione toolchain,
|
||||
verifiche, trappole) è in <a href="BUILD.it.md">docs/BUILD.it.md</a>.</p>
|
||||
|
||||
<h3>1 · Payload console → <code>pscapture.elf</code></h3>
|
||||
<pre><span class="c"># servono Docker + l'immagine del PS5 payload SDK (prospero-clang; qui tag ps5sdk:18)</span>
|
||||
docker run --rm -v "<repo>/payload:/payload" -w /payload ps5sdk:18 make</pre>
|
||||
|
||||
<h3>2 · Lato PC → <code>pscapture.exe</code> + <code>pscapture.dll</code></h3>
|
||||
<p style="color:var(--dim)">Serve MinGW-w64 (<code>gcc</code> +
|
||||
<code>windres</code>). <b>L'ordine è obbligatorio</b>: il
|
||||
<code>.res</code> incastra driver e payload così come sono su disco.</p>
|
||||
<pre><span class="c"># dalla radice della repo</span>
|
||||
cp payload/pscapture.elf pc/ <span class="c"># viene incastrato così com'è</span>
|
||||
<div class="build-step">
|
||||
<div class="num">Passo 2 · PC</div>
|
||||
<h3>App e driver → <code>pscapture.exe</code> + <code>pscapture.dll</code></h3>
|
||||
<p>Serve MinGW-w64 (<code>gcc</code> + <code>windres</code>). <b>L'ordine conta</b>: il <code>.res</code> incorpora driver e payload esattamente come sono su disco.</p>
|
||||
<div class="codeblock"><pre><span class="c"># dalla radice della repo</span>
|
||||
cp payload/pscapture.elf pc/
|
||||
cd pc
|
||||
|
||||
<span class="c"># 1) il driver della capture card (filtro sorgente DirectShow)</span>
|
||||
gcc -O2 -shared -static -static-libgcc -o pscapture.dll ps5cam.c \
|
||||
-lole32 -loleaut32 -luser32 -ladvapi32 -lws2_32
|
||||
|
||||
<span class="c"># 2) bundle: icona + payload + driver nell'oggetto risorse</span>
|
||||
<span class="c"># 2) icona + payload + driver nell'oggetto risorse</span>
|
||||
windres pscapture.rc -O coff -o pscapture.res
|
||||
|
||||
<span class="c"># 3) l'app a file unico</span>
|
||||
<span class="c"># 3) l'app in un unico file</span>
|
||||
gcc -O2 -mwindows -o pscapture.exe pscapture.c pscapture.res \
|
||||
-lws2_32 -lshell32 -ladvapi32 -luxtheme</pre>
|
||||
-lws2_32 -lshell32 -ladvapi32 -luxtheme</pre></div>
|
||||
</div>
|
||||
|
||||
<details>
|
||||
<summary>Perché quest'ordine? (e i due errori classici di build)</summary>
|
||||
<p><b>windres incastra i file come sono su disco:</b> se la DLL o il
|
||||
payload vengono ricompilati dopo il passo 2, l'exe continua a portarsi
|
||||
dentro quelli vecchi. Rebuild = DLL → windres → exe, ogni volta.<br>
|
||||
<b><code>-static -static-libgcc</code> sulla DLL è obbligatorio:</b>
|
||||
senza, Windows può rifiutarsi di caricare il driver con il cryptico
|
||||
“impossibile trovare il modulo specificato” (runtime mingw mancante).</p>
|
||||
</details>
|
||||
<div class="callout info" style="margin-top:22px">
|
||||
<svg class="i"><use href="#i-info"/></svg>
|
||||
<p><b>I due errori classici.</b> Se ricompili la DLL o il payload <i>dopo</i> <code>windres</code>, l'exe si porta dentro quelli vecchi: l'ordine è sempre DLL → windres → exe. E <code>-static -static-libgcc</code> sulla DLL è obbligatorio: senza, Windows può rifiutarsi di caricare il driver con “impossibile trovare il modulo specificato” (manca il runtime MinGW).</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h2>Requisiti</h2>
|
||||
<table>
|
||||
<tr><th>Dove</th><th>Cosa</th></tr>
|
||||
<tr><td>PS5</td><td>Jailbroken (payload loader + FTP + autoloader pldmgr)</td></tr>
|
||||
<tr><td>PS5</td><td>Firmware testato: <b>13.60</b> — vedi la FAQ per le altre versioni</td></tr>
|
||||
<tr><td>PC</td><td>Windows 10/11 64-bit, rete cablata consigliata</td></tr>
|
||||
<tr><td>Rete</td><td>Entrambi sulla stessa LAN (il gigabit basta per 1080p30)</td></tr>
|
||||
</table>
|
||||
<section id="faq" class="reveal">
|
||||
<div class="sec-head">
|
||||
<div class="kicker">FAQ</div>
|
||||
<h2>Domande.</h2>
|
||||
</div>
|
||||
<div class="faq">
|
||||
<details><summary>Funziona su firmware diversi dal 13.60?</summary>
|
||||
<div class="body"><p>Il lato PC funziona con qualsiasi firmware: app e driver usano solo TCP, FTP e memoria condivisa. La parte legata alla versione è il payload della console, sviluppato e tarato sul <b>13.60</b> usando gli ancoraggi del display engine di quel firmware. Su altre versioni può servire un piccolo porting per ritrovare gli stessi ancoraggi. <a href="https://github.com/fstat13/PSCapture/issues">Apri una issue</a> indicando il tuo firmware.</p></div></details>
|
||||
<details><summary>Perché in chiamata su Discord la webcam è a 720p?</summary>
|
||||
<div class="body"><p>È il motore vocale di Discord: chiede 1280×720 a ogni webcam. In OBS, PS5 Capture va a 1920×1080 pieni. La condivisione schermo di Discord arriva a 1080p60 con Nitro.</p></div></details>
|
||||
<details><summary>Servono una capture card o il Remote Play?</summary>
|
||||
<div class="body"><p>No. PSCapture non usa mai il Remote Play: il payload legge il display engine direttamente sulla console e manda i frame grezzi sulla tua rete locale.</p></div></details>
|
||||
<details><summary>Cattura anche l'audio del gioco?</summary>
|
||||
<div class="body"><p>Non ancora. Per ora PSCapture trasmette solo il video.</p></div></details>
|
||||
<details><summary>Funziona su macOS o Linux?</summary>
|
||||
<div class="body"><p>Il lato PC è solo per Windows, perché la webcam è un dispositivo DirectShow.</p></div></details>
|
||||
<details><summary>Come si disinstalla?</summary>
|
||||
<div class="body"><ol>
|
||||
<li>Chiudi l'app.</li>
|
||||
<li>Esegui <code>rundll32 "%ProgramFiles%\PSCapture\pscapture.dll",DllUnregisterServer</code> per rimuovere la webcam.</li>
|
||||
<li>Cancella <code>C:\Program Files\PSCapture</code>.</li>
|
||||
<li>Facoltativo, sulla console: cancella <code>/data/pldmgr/payloads/pscapture/</code> così l'autoloader smette di avviarlo.</li>
|
||||
</ol></div></details>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<h2 id="faq">FAQ</h2>
|
||||
<div class="band reveal">
|
||||
<div>
|
||||
<h2>Ti è utile? Lascia una stella.</h2>
|
||||
<p>PSCapture è gratuito. Una stella su GitHub aiuta altri appassionati di homebrew PS5 a trovarlo.</p>
|
||||
</div>
|
||||
<div class="cta">
|
||||
<a class="btn btn-primary" href="https://github.com/fstat13/PSCapture"><svg class="i"><use href="#i-star"/></svg>Metti una stella <span class="stars" data-stars hidden></span></a>
|
||||
<a class="btn btn-ghost" href="https://github.com/fstat13/PSCapture/issues">Segnala un problema</a>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<details>
|
||||
<summary>Funziona su firmware precedenti al 13.60?</summary>
|
||||
<p>Il lato PC funziona su qualsiasi firmware: app e driver parlano solo
|
||||
TCP/FTP e memoria condivisa. La parte version-specifica è il payload
|
||||
della console — è stato compilato e tarato sul <b>13.60</b>, usando gli
|
||||
ancoraggi del display engine trovati su quel firmware. Su altri
|
||||
firmware può servire un piccolo lavoro di porting (cioè ritrovare gli
|
||||
stessi ancoraggi su quel sistema). Se hai un'altra versione, apri una
|
||||
issue con il tuo firmware e possiamo aggiungere un profilo.</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Perché la camera in chiamata è 720p e non 1080p?</summary>
|
||||
<p>Quel limite è del motore vocale di Discord, non di PSCapture: chiede
|
||||
1280x720 a ogni camera. Per la qualità piena usa OBS (dove PS5 Capture
|
||||
va a 1920x1080) o la condivisione schermo di Discord, che arriva a
|
||||
1080p60 con Nitro.</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Servono una capture card o il Remote Play?</summary>
|
||||
<p>No. PSCapture non tocca mai il Remote Play: il payload legge il display
|
||||
engine sulla console stessa e manda i frame grezzi sulla tua LAN.</p>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Come si disinstalla?</summary>
|
||||
<p>Chiudi l'app, poi <code>rundll32 "%ProgramFiles%\PSCapture\pscapture.dll",DllUnregisterServer</code>,
|
||||
cancella <code>C:\Program Files\PSCapture</code>, e opzionalmente
|
||||
cancella <code>/data/pldmgr/payloads/pscapture/</code> sulla console
|
||||
così l'autoloader smette di avviare il payload.</p>
|
||||
</details>
|
||||
|
||||
<footer>
|
||||
PSCapture — porta lo schermo della PS5 ovunque nella tua LAN, senza card e senza cloud.
|
||||
<br><b>di fstat13</b> · source-available. Fatto per la community homebrew. <span class="ok">Gioca responsabilmente.</span>
|
||||
<br><br>
|
||||
Documenti: <a href="GUIDE.it.md">guida a prova di scemo (md)</a> ·
|
||||
<a href="BUILD.it.md">build dai sorgenti (md)</a> ·
|
||||
<a href="INSTALLER.md">cosa fa l'installer dentro</a> ·
|
||||
<a href="REVERSE_ENGINEERING.md">reverse engineering</a> ·
|
||||
<a href="ENGINEERING_LOG.md">engineering log</a>
|
||||
</footer>
|
||||
</div>
|
||||
<footer>
|
||||
<div class="wrap">
|
||||
<div class="foot">
|
||||
<div>
|
||||
<a class="logo" href="#top"><img src="pscapture.png" alt="">PSCapture</a>
|
||||
<p>Lo schermo della PS5 ovunque nella tua rete. Senza card, senza cloud.<br>di <b>fstat13</b></p>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Guide</h4>
|
||||
<ul>
|
||||
<li><a href="https://github.com/fstat13/PSCapture/blob/main/docs/GUIDE.it.md">Guida passo-passo</a></li>
|
||||
<li><a href="https://github.com/fstat13/PSCapture/blob/main/docs/BUILD.it.md">Build dai sorgenti</a></li>
|
||||
<li><a href="https://github.com/fstat13/PSCapture/blob/main/docs/INSTALLER.md">Cosa fa l'installer (EN)</a></li>
|
||||
<li><a href="https://github.com/fstat13/PSCapture/blob/main/docs/REVERSE_ENGINEERING.md">Reverse engineering (EN)</a></li>
|
||||
<li><a href="https://github.com/fstat13/PSCapture/blob/main/docs/ENGINEERING_LOG.md">Engineering log (EN)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h4>Progetto</h4>
|
||||
<ul>
|
||||
<li><a href="https://github.com/fstat13/PSCapture">GitHub</a></li>
|
||||
<li><a href="https://github.com/fstat13/PSCapture/releases">Releases</a></li>
|
||||
<li><a href="https://github.com/fstat13/PSCapture/issues">Issues</a></li>
|
||||
<li><a href="https://github.com/fstat13/PSCapture/blob/main/LICENSE">Licenza</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="legal">
|
||||
<span>© 2026 fstat13 · source-available</span>
|
||||
<span>Non affiliato a Sony Interactive Entertainment. “PlayStation” e “PS5” sono marchi dei rispettivi proprietari.</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script src="main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
/* PSCapture — page behaviour shared by index.html / index.it.html */
|
||||
(function () {
|
||||
var doc = document.documentElement;
|
||||
doc.classList.remove('no-js');
|
||||
var it = doc.lang === 'it';
|
||||
var reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
||||
|
||||
/* nav border once the page scrolls */
|
||||
var nav = document.querySelector('.nav');
|
||||
function onScroll() { nav.classList.toggle('scrolled', window.scrollY > 8); }
|
||||
window.addEventListener('scroll', onScroll, { passive: true });
|
||||
onScroll();
|
||||
|
||||
/* app mock: replay the real start-up log, then flip the pill to STREAMING */
|
||||
var log = document.querySelector('.app-log');
|
||||
var pill = document.querySelector('.pill');
|
||||
if (log && pill) {
|
||||
var lines = Array.prototype.slice.call(log.children);
|
||||
var live = function () {
|
||||
pill.classList.add('live');
|
||||
pill.lastChild.textContent = ' STREAMING 29.8 fps';
|
||||
};
|
||||
/* the HTML ships in the final state, so no-JS and reduced-motion visitors see it as-is */
|
||||
if (!reduce) {
|
||||
pill.classList.remove('live');
|
||||
pill.lastChild.textContent = ' AVVIO...';
|
||||
lines.forEach(function (l) { l.style.display = 'none'; });
|
||||
var i = 0;
|
||||
(function next() {
|
||||
if (i < lines.length) {
|
||||
lines[i].style.display = '';
|
||||
i++;
|
||||
setTimeout(next, i === 1 ? 500 : 420 + Math.random() * 380);
|
||||
} else {
|
||||
live();
|
||||
}
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
||||
/* copy buttons on code blocks (prompts and comments are not copied) */
|
||||
document.querySelectorAll('.codeblock').forEach(function (block) {
|
||||
var btn = document.createElement('button');
|
||||
btn.className = 'copy';
|
||||
btn.type = 'button';
|
||||
btn.textContent = it ? 'Copia' : 'Copy';
|
||||
btn.addEventListener('click', function () {
|
||||
var pre = block.querySelector('pre').cloneNode(true);
|
||||
pre.querySelectorAll('.p, .c').forEach(function (n) { n.remove(); });
|
||||
var text = pre.textContent.split('\n')
|
||||
.map(function (s) { return s.replace(/\s+$/, ''); })
|
||||
.filter(function (s) { return s.length; })
|
||||
.join('\n');
|
||||
navigator.clipboard.writeText(text).then(function () {
|
||||
btn.textContent = it ? 'Copiato ✓' : 'Copied ✓';
|
||||
btn.classList.add('done');
|
||||
setTimeout(function () {
|
||||
btn.textContent = it ? 'Copia' : 'Copy';
|
||||
btn.classList.remove('done');
|
||||
}, 1600);
|
||||
});
|
||||
});
|
||||
block.appendChild(btn);
|
||||
});
|
||||
|
||||
/* troubleshooting filter */
|
||||
var q = document.getElementById('q');
|
||||
if (q) {
|
||||
var issues = document.querySelectorAll('.issue');
|
||||
var none = document.querySelector('.noresult');
|
||||
q.addEventListener('input', function () {
|
||||
var words = q.value.toLowerCase().trim().split(/\s+/).filter(Boolean);
|
||||
var shown = 0;
|
||||
issues.forEach(function (el) {
|
||||
var txt = el.textContent.toLowerCase();
|
||||
var ok = words.every(function (w) { return txt.indexOf(w) !== -1; });
|
||||
el.hidden = !ok;
|
||||
if (ok) shown++;
|
||||
});
|
||||
none.hidden = shown !== 0;
|
||||
});
|
||||
}
|
||||
|
||||
/* live star count on the GitHub buttons */
|
||||
fetch('https://api.github.com/repos/fstat13/PSCapture')
|
||||
.then(function (r) { return r.ok ? r.json() : null; })
|
||||
.then(function (d) {
|
||||
if (!d || typeof d.stargazers_count !== 'number') return;
|
||||
document.querySelectorAll('[data-stars]').forEach(function (el) {
|
||||
el.textContent = d.stargazers_count.toLocaleString(doc.lang);
|
||||
el.hidden = false;
|
||||
});
|
||||
})
|
||||
.catch(function () {});
|
||||
|
||||
/* fade sections in as they scroll into view */
|
||||
if ('IntersectionObserver' in window && !reduce) {
|
||||
var io = new IntersectionObserver(function (entries) {
|
||||
entries.forEach(function (e) {
|
||||
if (e.isIntersecting) { e.target.classList.add('in'); io.unobserve(e.target); }
|
||||
});
|
||||
}, { rootMargin: '0px 0px -8% 0px' });
|
||||
document.querySelectorAll('.reveal').forEach(function (el) { io.observe(el); });
|
||||
} else {
|
||||
document.querySelectorAll('.reveal').forEach(function (el) { el.classList.add('in'); });
|
||||
}
|
||||
})();
|
||||
+395
@@ -0,0 +1,395 @@
|
||||
/* PSCapture — shared stylesheet for index.html / index.it.html */
|
||||
|
||||
:root{
|
||||
color-scheme: dark;
|
||||
--bg:#07090d;
|
||||
--bg-2:#0b0e14;
|
||||
--surface:#10141c;
|
||||
--surface-2:#151b25;
|
||||
--surface-3:#1b2230;
|
||||
--line:#1f2733;
|
||||
--line-2:#2a3445;
|
||||
--fg:#eef2f8;
|
||||
--fg-2:#c3cbd8;
|
||||
--dim:#8a95a8;
|
||||
--dim-2:#5f6b7f;
|
||||
--accent:#2986eb; /* same blue as the app's START button */
|
||||
--accent-2:#5aa8ff;
|
||||
--accent-glow:rgba(41,134,235,.35);
|
||||
--violet:#7c5cff;
|
||||
--green:#22c55e;
|
||||
--amber:#f59e0b;
|
||||
--red:#ef4444;
|
||||
--radius:16px;
|
||||
--radius-sm:10px;
|
||||
--maxw:1120px;
|
||||
--font:"Inter",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
|
||||
--mono:"JetBrains Mono",ui-monospace,Consolas,"Cascadia Mono",monospace;
|
||||
}
|
||||
|
||||
*,*::before,*::after{box-sizing:border-box}
|
||||
html{scroll-behavior:smooth;scroll-padding-top:84px;-webkit-text-size-adjust:100%}
|
||||
body{
|
||||
margin:0;background:var(--bg);color:var(--fg);
|
||||
font:16px/1.65 var(--font);
|
||||
-webkit-font-smoothing:antialiased;
|
||||
overflow-x:hidden;
|
||||
}
|
||||
img{max-width:100%;display:block}
|
||||
a{color:var(--accent-2);text-decoration:none}
|
||||
a:hover{text-decoration:underline;text-underline-offset:3px}
|
||||
b,strong{color:var(--fg);font-weight:600}
|
||||
::selection{background:var(--accent);color:#fff}
|
||||
|
||||
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 24px}
|
||||
@media (max-width:600px){.wrap{padding:0 16px}}
|
||||
|
||||
/* ───────── nav ───────── */
|
||||
.nav{
|
||||
position:sticky;top:0;z-index:50;
|
||||
background:rgba(7,9,13,.72);
|
||||
backdrop-filter:saturate(160%) blur(14px);
|
||||
-webkit-backdrop-filter:saturate(160%) blur(14px);
|
||||
border-bottom:1px solid transparent;
|
||||
transition:border-color .2s;
|
||||
}
|
||||
.nav.scrolled{border-bottom-color:var(--line)}
|
||||
.nav .wrap{display:flex;align-items:center;gap:20px;height:64px}
|
||||
.logo{display:flex;align-items:center;gap:10px;color:var(--fg);font-weight:700;letter-spacing:-.01em}
|
||||
.logo:hover{text-decoration:none}
|
||||
.logo img{width:30px;height:30px;border-radius:8px}
|
||||
.nav-links{display:flex;gap:4px;margin-left:auto}
|
||||
.nav-links a{color:var(--dim);font-size:14px;padding:6px 10px;border-radius:8px}
|
||||
.nav-links a:hover{color:var(--fg);background:var(--surface);text-decoration:none}
|
||||
.nav-right{display:flex;align-items:center;gap:8px}
|
||||
.lang{font-size:13px;color:var(--dim);border:1px solid var(--line-2);border-radius:999px;padding:4px 11px}
|
||||
.lang:hover{color:var(--fg);text-decoration:none;border-color:var(--dim-2)}
|
||||
@media (max-width:860px){.nav-links{display:none}.nav-right{margin-left:auto}}
|
||||
|
||||
/* ───────── buttons ───────── */
|
||||
.btn{
|
||||
display:inline-flex;align-items:center;gap:9px;
|
||||
font:600 15px/1 var(--font);
|
||||
padding:13px 20px;border-radius:12px;border:1px solid transparent;
|
||||
cursor:pointer;transition:transform .15s,background .15s,border-color .15s,box-shadow .15s;
|
||||
white-space:nowrap;
|
||||
}
|
||||
.btn:hover{text-decoration:none;transform:translateY(-1px)}
|
||||
.btn svg{width:18px;height:18px;flex:none}
|
||||
.btn-primary{background:var(--accent);color:#fff;box-shadow:0 8px 30px -8px var(--accent-glow),inset 0 1px 0 rgba(255,255,255,.18)}
|
||||
.btn-primary:hover{background:#3592f5}
|
||||
.btn-ghost{background:var(--surface);color:var(--fg);border-color:var(--line-2)}
|
||||
.btn-ghost:hover{border-color:var(--dim-2)}
|
||||
.btn-sm{padding:8px 13px;font-size:13.5px;border-radius:9px}
|
||||
|
||||
/* ───────── hero ───────── */
|
||||
.hero{position:relative;padding:72px 0 56px;isolation:isolate}
|
||||
.hero::before{
|
||||
content:"";position:absolute;inset:-64px 0 0;z-index:-1;
|
||||
background:
|
||||
radial-gradient(600px 380px at 12% 8%, rgba(41,134,235,.22), transparent 70%),
|
||||
radial-gradient(520px 360px at 88% 18%, rgba(124,92,255,.16), transparent 70%);
|
||||
}
|
||||
.hero::after{
|
||||
content:"";position:absolute;inset:-64px 0 0;z-index:-1;
|
||||
background-image:linear-gradient(var(--line) 1px,transparent 1px),linear-gradient(90deg,var(--line) 1px,transparent 1px);
|
||||
background-size:56px 56px;opacity:.28;
|
||||
-webkit-mask-image:radial-gradient(ellipse 70% 60% at 50% 20%,#000 30%,transparent 75%);
|
||||
mask-image:radial-gradient(ellipse 70% 60% at 50% 20%,#000 30%,transparent 75%);
|
||||
}
|
||||
.hero-grid{display:grid;grid-template-columns:1fr 1.08fr;gap:56px;align-items:center}
|
||||
@media (max-width:960px){.hero-grid{grid-template-columns:1fr;gap:44px}}
|
||||
.eyebrow{
|
||||
display:inline-flex;align-items:center;gap:8px;
|
||||
font-size:13px;color:var(--fg-2);
|
||||
border:1px solid var(--line-2);background:rgba(16,20,28,.7);
|
||||
padding:5px 12px 5px 8px;border-radius:999px;
|
||||
}
|
||||
.eyebrow .tagv{background:var(--accent);color:#fff;font-weight:700;font-size:11.5px;padding:2px 8px;border-radius:999px}
|
||||
.hero h1{
|
||||
font-size:clamp(38px,5.6vw,62px);line-height:1.04;letter-spacing:-.035em;
|
||||
margin:20px 0 18px;font-weight:800;
|
||||
}
|
||||
.grad{background:linear-gradient(100deg,#fff 10%,var(--accent-2) 55%,var(--violet));-webkit-background-clip:text;background-clip:text;color:transparent}
|
||||
.lead{font-size:18.5px;color:var(--fg-2);margin:0 0 30px;max-width:540px}
|
||||
.cta{display:flex;gap:12px;flex-wrap:wrap}
|
||||
.hero-meta{display:flex;flex-wrap:wrap;gap:8px 18px;margin-top:26px;color:var(--dim);font-size:14px}
|
||||
.hero-meta span{display:inline-flex;align-items:center;gap:7px}
|
||||
.hero-meta svg{width:16px;height:16px;color:var(--green)}
|
||||
|
||||
/* ───────── app mock ───────── */
|
||||
.app{
|
||||
position:relative;
|
||||
background:#10141b;border:1px solid var(--line-2);border-radius:14px;
|
||||
box-shadow:0 40px 80px -30px rgba(0,0,0,.8),0 0 0 1px rgba(255,255,255,.02),0 0 120px -40px var(--accent-glow);
|
||||
overflow:hidden;font-size:13px;
|
||||
}
|
||||
.app-bar{display:flex;align-items:center;gap:10px;background:#0b0e13;border-bottom:1px solid #202733;padding:10px 14px}
|
||||
.app-bar img{width:18px;height:18px;border-radius:4px}
|
||||
.app-bar .t{color:var(--fg-2);font-size:12.5px;flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
|
||||
.app-bar .w{display:flex;gap:14px;color:var(--dim-2);font-size:12px}
|
||||
.app-body{padding:18px 18px 16px}
|
||||
.app-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:16px}
|
||||
.app-title{font-weight:700;font-size:17px;letter-spacing:-.01em}
|
||||
.app-title small{display:block;color:var(--dim);font-weight:400;font-size:12px}
|
||||
.pill{
|
||||
display:inline-flex;align-items:center;gap:8px;white-space:nowrap;
|
||||
background:#1a2130;border:1px solid #273042;border-radius:999px;
|
||||
padding:6px 12px;font:600 11.5px/1 var(--mono);letter-spacing:.02em;color:var(--amber);
|
||||
transition:color .3s;
|
||||
}
|
||||
.pill i{width:8px;height:8px;border-radius:50%;background:currentColor;box-shadow:0 0 0 0 currentColor;animation:pulse 1.6s infinite}
|
||||
.pill.live{color:var(--green)}
|
||||
@keyframes pulse{0%{box-shadow:0 0 0 0 color-mix(in srgb,currentColor 60%,transparent)}70%{box-shadow:0 0 0 7px transparent}100%{box-shadow:0 0 0 0 transparent}}
|
||||
.app-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:10px}
|
||||
.app-lbl{color:var(--dim);font-size:12px}
|
||||
.app-in{background:#0c0f15;border:1px solid #202733;border-radius:7px;padding:6px 10px;color:#cbd3e0;font:12px var(--mono)}
|
||||
.app-btn{background:#1a2029;border:1px solid #2c3646;border-radius:7px;padding:6px 11px;color:var(--fg-2);font-size:12px}
|
||||
.app-btn.big{background:var(--accent);border-color:var(--accent);color:#fff;font-weight:700;padding:12px 22px;font-size:13px;letter-spacing:.02em}
|
||||
.app-btn.stop{padding:12px 18px;font-weight:600}
|
||||
.app-log{
|
||||
margin-top:14px;background:#0c0f15;border:1px solid #202733;border-radius:9px;
|
||||
padding:12px 14px;height:196px;overflow:hidden;
|
||||
font:11.5px/1.75 var(--mono);color:#aeb8c8;
|
||||
display:flex;flex-direction:column;justify-content:flex-end;
|
||||
}
|
||||
.app-log div{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;animation:logIn .35s ease-out both}
|
||||
.app-log .ok{color:#7ee2a5}
|
||||
.app-log .hl{color:#8fc3ff}
|
||||
@keyframes logIn{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
|
||||
@media (max-width:520px){
|
||||
.app-bar .w{display:none}
|
||||
.app-knobs{display:none}
|
||||
}
|
||||
|
||||
/* ───────── sections ───────── */
|
||||
section{padding:84px 0 0}
|
||||
.sec-head{max-width:720px;margin-bottom:34px}
|
||||
.kicker{font:600 12.5px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--accent-2);margin-bottom:14px}
|
||||
h2{font-size:clamp(28px,3.6vw,40px);line-height:1.12;letter-spacing:-.028em;margin:0 0 14px;font-weight:750}
|
||||
h3{font-size:18px;letter-spacing:-.01em;margin:0 0 8px;font-weight:650}
|
||||
.sub{color:var(--dim);font-size:17px;margin:0}
|
||||
p{margin:0 0 14px}
|
||||
|
||||
/* stats */
|
||||
.stats{display:grid;grid-template-columns:repeat(4,1fr);border:1px solid var(--line);border-radius:var(--radius);background:var(--bg-2);overflow:hidden;margin-top:12px}
|
||||
.stat{padding:22px 24px;border-left:1px solid var(--line)}
|
||||
.stat:first-child{border-left:0}
|
||||
.stat .n{font-size:28px;font-weight:750;letter-spacing:-.03em}
|
||||
.stat .l{color:var(--dim);font-size:13.5px}
|
||||
@media (max-width:760px){.stats{grid-template-columns:repeat(2,1fr)}.stat:nth-child(3){border-left:0}.stat:nth-child(n+3){border-top:1px solid var(--line)}}
|
||||
|
||||
/* feature cards */
|
||||
.grid{display:grid;gap:16px}
|
||||
.g3{grid-template-columns:repeat(3,1fr)}
|
||||
.g2{grid-template-columns:repeat(2,1fr)}
|
||||
@media (max-width:900px){.g3{grid-template-columns:1fr 1fr}}
|
||||
@media (max-width:640px){.g3,.g2{grid-template-columns:1fr}}
|
||||
.card{
|
||||
position:relative;background:linear-gradient(180deg,var(--surface),var(--bg-2));
|
||||
border:1px solid var(--line);border-radius:var(--radius);padding:24px;
|
||||
transition:border-color .2s,transform .2s;
|
||||
}
|
||||
.card:hover{border-color:var(--line-2)}
|
||||
.card p{color:var(--dim);font-size:15px;margin:0}
|
||||
.ico{
|
||||
width:42px;height:42px;border-radius:11px;display:grid;place-items:center;margin-bottom:16px;
|
||||
background:rgba(41,134,235,.12);color:var(--accent-2);border:1px solid rgba(41,134,235,.25);
|
||||
}
|
||||
.ico svg{width:21px;height:21px}
|
||||
.ico.v{background:rgba(124,92,255,.12);color:#a996ff;border-color:rgba(124,92,255,.28)}
|
||||
.ico.g{background:rgba(34,197,94,.1);color:#5fdc8f;border-color:rgba(34,197,94,.25)}
|
||||
.ico.a{background:rgba(245,158,11,.1);color:#fbbf4a;border-color:rgba(245,158,11,.25)}
|
||||
|
||||
/* pipeline */
|
||||
.pipe{display:grid;grid-template-columns:1fr auto 1fr auto 1fr auto 1fr;align-items:stretch;gap:0}
|
||||
.node{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:20px}
|
||||
.node .where{font:600 11px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--dim-2);margin-bottom:10px}
|
||||
.node h3{font-size:16px}
|
||||
.node p{color:var(--dim);font-size:14px;margin:0}
|
||||
.node.end{background:linear-gradient(160deg,rgba(41,134,235,.14),var(--surface) 60%);border-color:rgba(41,134,235,.35)}
|
||||
.chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:12px}
|
||||
.chip{font-size:12px;color:var(--fg-2);background:var(--surface-3);border:1px solid var(--line-2);border-radius:999px;padding:3px 10px}
|
||||
.link{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:0 10px;color:var(--dim-2);min-width:64px}
|
||||
.link span{font:500 10.5px/1.2 var(--mono);text-align:center;margin-bottom:6px;color:var(--dim)}
|
||||
.link .line{position:relative;width:100%;height:2px;background:linear-gradient(90deg,var(--line-2),var(--accent),var(--line-2));background-size:200% 100%;animation:flow 2.2s linear infinite;border-radius:2px}
|
||||
.link .line::after{content:"";position:absolute;right:-1px;top:-4px;border:5px solid transparent;border-left-color:var(--accent);border-right:0}
|
||||
@keyframes flow{from{background-position:100% 0}to{background-position:-100% 0}}
|
||||
@media (max-width:960px){
|
||||
.pipe{grid-template-columns:1fr}
|
||||
.link{flex-direction:row;gap:10px;padding:10px 0;min-height:44px}
|
||||
.link span{margin:0;order:2}
|
||||
.link .line{width:2px;height:28px;background:linear-gradient(180deg,var(--line-2),var(--accent),var(--line-2));background-size:100% 200%}
|
||||
.link .line::after{right:-4px;top:auto;bottom:-1px;border:5px solid transparent;border-top-color:var(--accent);border-bottom:0}
|
||||
}
|
||||
|
||||
/* requirements */
|
||||
.req{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius);padding:24px}
|
||||
.req-h{display:flex;align-items:center;gap:12px;margin-bottom:16px}
|
||||
.req-h .ico{margin:0}
|
||||
.req-h h3{margin:0}
|
||||
.req ul{list-style:none;margin:0;padding:0}
|
||||
.req li{display:flex;gap:12px;padding:11px 0;border-top:1px solid var(--line);font-size:15px;color:var(--fg-2)}
|
||||
.req li:first-child{border-top:0;padding-top:0}
|
||||
.req li svg{width:18px;height:18px;flex:none;margin-top:3px;color:var(--green)}
|
||||
.req li.opt svg{color:var(--dim-2)}
|
||||
.req li small{color:var(--dim);display:block;font-size:13.5px}
|
||||
.tagopt{font:600 10.5px/1 var(--mono);color:var(--dim);border:1px solid var(--line-2);border-radius:5px;padding:2px 6px;margin-left:6px;vertical-align:2px;text-transform:uppercase;letter-spacing:.06em}
|
||||
|
||||
/* steps */
|
||||
.steps{list-style:none;margin:0;padding:0;counter-reset:s;position:relative}
|
||||
.steps>li{counter-increment:s;position:relative;padding:0 0 30px 68px}
|
||||
.steps>li::before{
|
||||
content:counter(s);position:absolute;left:0;top:-2px;
|
||||
width:44px;height:44px;border-radius:13px;display:grid;place-items:center;
|
||||
font:700 17px/1 var(--font);color:#fff;
|
||||
background:linear-gradient(160deg,var(--accent),#1a5fb4);
|
||||
box-shadow:0 8px 24px -8px var(--accent-glow),inset 0 1px 0 rgba(255,255,255,.2);
|
||||
}
|
||||
.steps>li::after{content:"";position:absolute;left:21px;top:50px;bottom:6px;width:2px;background:linear-gradient(var(--line-2),transparent)}
|
||||
.steps>li:last-child::after{display:none}
|
||||
.steps h3{margin:6px 0 6px;font-size:18.5px}
|
||||
.steps p{color:var(--dim);margin:0}
|
||||
|
||||
/* callouts */
|
||||
.callout{display:flex;gap:14px;border-radius:var(--radius);padding:18px 20px;border:1px solid;font-size:15px}
|
||||
.callout svg{width:20px;height:20px;flex:none;margin-top:2px}
|
||||
.callout p{margin:0;color:inherit}
|
||||
.callout.info{background:rgba(41,134,235,.07);border-color:rgba(41,134,235,.3);color:#cfe3ff}
|
||||
.callout.info svg{color:var(--accent-2)}
|
||||
.callout.warn{background:rgba(245,158,11,.06);border-color:rgba(245,158,11,.3);color:#f6e2bd}
|
||||
.callout.warn svg{color:var(--amber)}
|
||||
|
||||
/* terminal-style log legend */
|
||||
.term{background:#0a0d12;border:1px solid var(--line);border-radius:var(--radius);overflow:hidden}
|
||||
.term-bar{display:flex;align-items:center;gap:8px;padding:11px 16px;border-bottom:1px solid var(--line);background:var(--bg-2);font:12px var(--mono);color:var(--dim)}
|
||||
.term-bar i{width:10px;height:10px;border-radius:50%;background:var(--line-2)}
|
||||
.term-bar b{margin-left:8px;font-weight:500;color:var(--dim)}
|
||||
.term-row{display:grid;grid-template-columns:minmax(0,1.25fr) minmax(0,1fr);gap:20px;padding:14px 18px;border-top:1px solid var(--line)}
|
||||
.term-row:first-of-type{border-top:0}
|
||||
.term-row code{background:none;border:0;padding:0;color:#9fd0ff;font-size:13px;display:block;word-break:break-word}
|
||||
.term-row .m{color:var(--fg-2);font-size:14.5px}
|
||||
.term-row.ok code{color:#7ee2a5}
|
||||
@media (max-width:700px){.term-row{grid-template-columns:1fr;gap:6px}}
|
||||
|
||||
/* app targets */
|
||||
.target{display:flex;flex-direction:column}
|
||||
.target .res{margin-top:auto;padding-top:16px;display:flex;align-items:center;justify-content:space-between;gap:10px;border-top:1px dashed var(--line-2);margin-top:18px;font-size:13.5px;color:var(--dim)}
|
||||
.target .res b{font:700 15px var(--mono);color:var(--fg)}
|
||||
.target .path{font-size:14px;color:var(--fg-2);margin-top:6px}
|
||||
|
||||
/* knobs */
|
||||
.knob .k{display:inline-block;font:600 14px var(--mono);color:var(--fg);background:var(--surface-3);border:1px solid var(--line-2);border-radius:7px;padding:3px 9px;margin-bottom:12px}
|
||||
.knob ul{margin:12px 0 0;padding-left:18px;color:var(--dim);font-size:14.5px}
|
||||
.knob li{margin:4px 0}
|
||||
|
||||
/* troubleshooting */
|
||||
.search{position:relative;margin-bottom:16px}
|
||||
.search svg{position:absolute;left:16px;top:50%;transform:translateY(-50%);width:18px;height:18px;color:var(--dim-2)}
|
||||
.search input{
|
||||
width:100%;font:15px var(--font);color:var(--fg);
|
||||
background:var(--surface);border:1px solid var(--line-2);border-radius:12px;
|
||||
padding:14px 16px 14px 46px;outline:none;transition:border-color .15s,box-shadow .15s;
|
||||
}
|
||||
.search input::placeholder{color:var(--dim-2)}
|
||||
.search input:focus{border-color:var(--accent);box-shadow:0 0 0 4px rgba(41,134,235,.15)}
|
||||
.issues{display:grid;gap:10px}
|
||||
.issue{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);gap:24px;background:var(--surface);border:1px solid var(--line);border-radius:14px;padding:18px 20px}
|
||||
.issue .sym{font-weight:600;color:var(--fg)}
|
||||
.issue .sym code{font-weight:400}
|
||||
.issue .fix{color:var(--dim);font-size:15px}
|
||||
.issue .fix b{color:var(--fg-2)}
|
||||
.issue .cause{display:block;font-size:12px;font-family:var(--mono);color:var(--dim-2);text-transform:uppercase;letter-spacing:.08em;margin-bottom:4px}
|
||||
.issue[hidden]{display:none}
|
||||
.noresult{color:var(--dim);padding:18px;text-align:center;border:1px dashed var(--line-2);border-radius:14px}
|
||||
@media (max-width:700px){.issue{grid-template-columns:1fr;gap:10px}}
|
||||
|
||||
/* code */
|
||||
code,kbd{
|
||||
font:.86em/1.5 var(--mono);color:#cfe3ff;
|
||||
background:var(--surface-3);border:1px solid var(--line-2);border-radius:6px;padding:1px 6px;
|
||||
overflow-wrap:anywhere;
|
||||
}
|
||||
.codeblock{position:relative;margin:12px 0 0}
|
||||
.codeblock pre{
|
||||
margin:0;background:#0a0d12;border:1px solid var(--line);border-radius:14px;
|
||||
padding:18px 20px;overflow-x:auto;font:13.5px/1.7 var(--mono);color:#d6e4f5;
|
||||
}
|
||||
.codeblock pre .c{color:#5d6b80}
|
||||
.codeblock pre .p{color:var(--accent-2);user-select:none}
|
||||
.copy{
|
||||
position:absolute;top:10px;right:10px;
|
||||
font:500 12px var(--font);color:var(--dim);
|
||||
background:var(--surface-2);border:1px solid var(--line-2);border-radius:8px;
|
||||
padding:5px 10px;cursor:pointer;opacity:.85;transition:all .15s;
|
||||
}
|
||||
.copy:hover{color:var(--fg);opacity:1}
|
||||
.copy.done{color:var(--green);border-color:rgba(34,197,94,.4)}
|
||||
.build-step{margin-top:34px}
|
||||
.build-step:first-child{margin-top:0}
|
||||
.build-step .num{font:600 12px var(--mono);color:var(--accent-2);letter-spacing:.08em;text-transform:uppercase}
|
||||
.build-step h3{margin:6px 0 6px;font-size:20px}
|
||||
.build-step>p{color:var(--dim);margin:0}
|
||||
|
||||
/* faq */
|
||||
.faq{display:grid;gap:10px}
|
||||
details{background:var(--surface);border:1px solid var(--line);border-radius:14px;transition:border-color .2s}
|
||||
details[open]{border-color:var(--line-2)}
|
||||
summary{
|
||||
list-style:none;cursor:pointer;padding:18px 54px 18px 20px;position:relative;
|
||||
font-weight:600;font-size:16px;
|
||||
}
|
||||
summary::-webkit-details-marker{display:none}
|
||||
summary::after{
|
||||
content:"";position:absolute;right:22px;top:50%;width:9px;height:9px;
|
||||
border-right:2px solid var(--dim);border-bottom:2px solid var(--dim);
|
||||
transform:translateY(-70%) rotate(45deg);transition:transform .2s;
|
||||
}
|
||||
details[open] summary::after{transform:translateY(-30%) rotate(-135deg)}
|
||||
details .body{padding:0 20px 18px;color:var(--dim);font-size:15px}
|
||||
details .body p:last-child{margin:0}
|
||||
details .body ol{margin:0;padding-left:20px}
|
||||
details .body li{margin:6px 0}
|
||||
|
||||
/* cta band */
|
||||
.band{
|
||||
margin-top:96px;position:relative;overflow:hidden;
|
||||
border:1px solid rgba(41,134,235,.3);border-radius:22px;padding:48px 40px;
|
||||
background:
|
||||
radial-gradient(500px 260px at 0% 0%,rgba(41,134,235,.25),transparent 70%),
|
||||
radial-gradient(500px 260px at 100% 100%,rgba(124,92,255,.18),transparent 70%),
|
||||
var(--bg-2);
|
||||
display:flex;align-items:center;justify-content:space-between;gap:28px;flex-wrap:wrap;
|
||||
}
|
||||
.band h2{margin:0 0 6px;font-size:clamp(24px,3vw,32px)}
|
||||
.band p{margin:0;color:var(--fg-2)}
|
||||
@media (max-width:600px){.band{padding:32px 22px}}
|
||||
|
||||
/* footer */
|
||||
footer{margin-top:80px;border-top:1px solid var(--line);padding:44px 0 56px;color:var(--dim);font-size:14px}
|
||||
.foot{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:32px}
|
||||
@media (max-width:760px){.foot{grid-template-columns:1fr}}
|
||||
.foot h4{margin:0 0 12px;font-size:12px;font-family:var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--dim-2);font-weight:600}
|
||||
.foot ul{list-style:none;margin:0;padding:0}
|
||||
.foot li{margin:7px 0}
|
||||
.foot a{color:var(--fg-2)}
|
||||
.foot .logo{margin-bottom:12px}
|
||||
.legal{margin-top:36px;padding-top:22px;border-top:1px solid var(--line);font-size:12.5px;color:var(--dim-2);display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap}
|
||||
|
||||
/* reveal on scroll */
|
||||
.reveal{opacity:0;transform:translateY(14px);transition:opacity .6s ease,transform .6s ease}
|
||||
.reveal.in{opacity:1;transform:none}
|
||||
.no-js .reveal{opacity:1;transform:none}
|
||||
|
||||
@media (prefers-reduced-motion:reduce){
|
||||
html{scroll-behavior:auto}
|
||||
*,*::before,*::after{animation:none!important;transition:none!important}
|
||||
.reveal{opacity:1;transform:none}
|
||||
}
|
||||
|
||||
/* star counter inside GitHub buttons */
|
||||
.stars{font:600 12.5px/1 var(--mono);color:var(--fg-2);background:var(--surface-3);border:1px solid var(--line-2);border-radius:6px;padding:3px 7px;margin-left:2px}
|
||||
.btn-primary .stars{background:rgba(255,255,255,.16);border-color:rgba(255,255,255,.22);color:#fff}
|
||||
|
||||
/* inline svg icons (sprite in each page) */
|
||||
.i{fill:none;stroke:currentColor;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
|
||||
Reference in new issue
Block a user