Closed ghost closed 3 years ago
If you have ShadowPlay installed you already have some kind of API. GFE uses Nodejs backend with Express server, it runs at http://localhost, basically it's rest api. You can check it in C:\Program Files (x86)\NVIDIA Corporation\NvNode (should be static path for x64 systems). ShadowPlay related stuff stored in "NvShadowPlayAPI.js"
So in order to communicate with it you need to know secret token and port - both of them are random with every launch and stored in memory mapped file called {8BA1E16C-FC54-4595-9782-E370A5FBE8DA}
If I understand correctly you can't read memory mapped file from native cmd but you can from powershell.
This script should work, it can start\stop manual record and save replay you can run it with command "Powershell.exe -File "Shadowplay.ps1 start"
function GetConfig
{
$config_handle = [System.IO.MemoryMappedFiles.MemoryMappedFile]::OpenExisting('{8BA1E16C-FC54-4595-9782-E370A5FBE8DA}');
$stream = $config_handle.CreateViewStream();
$stream_reader = New-Object System.IO.StreamReader -ArgumentList $stream;
$config_data = $stream_reader.ReadToEnd().Replace("`0", "");
$stream_reader.Dispose();
$stream.Dispose();
return $config_data | ConvertFrom-Json;
}
$config = GetConfig
function SetRecording
{
Param($state)
$headers = @{"X_LOCAL_SECURITY_COOKIE" = $config.secret};
$body = @{status = $state} | ConvertTo-Json;
$uri = "http://localhost:$($config.port)/ShadowPlay/v.1.0/Record/Enable";
Invoke-RestMethod -Uri $uri -Method "Post" -ContentType "application/json" -Headers $headers -Body $body;
}
function SaveIR
{
$headers = @{"X_LOCAL_SECURITY_COOKIE" = $config.secret};
$uri = "http://localhost:$($config.port)/ShadowPlay/v.1.0/InstantReplay/Save";
Invoke-RestMethod -Uri $uri -Method "Post" -Headers $headers;
}
if ($args[0] -eq "start"){
SetRecording $true;
} elseif ($args[0] -eq "stop"){
SetRecording $false;
} elseif ($args[0] -eq "replay"){
SaveIR;
} else {
write-host("Command line arguments:");
write-host("start start manual record");
write-host("stop stop and save manual record");
write-host("replay save instant replay");
}
If you have ShadowPlay installed you already have some kind of API. GFE uses Nodejs backend with Express server, it runs at http://localhost, basically it's rest api. You can check it in C:\Program Files (x86)\NVIDIA Corporation\NvNode (should be static path for x64 systems). ShadowPlay related stuff stored in "NvShadowPlayAPI.js"
So in order to communicate with it you need to know secret token and port - both of them are random with every launch and stored in memory mapped file called {8BA1E16C-FC54-4595-9782-E370A5FBE8DA}
If I understand correctly you can't read memory mapped file from native cmd but you can from powershell.
This script should work, it can start\stop manual record and save replay you can run it with command "Powershell.exe -File "Shadowplay.ps1 start"
function GetConfig { $config_handle = [System.IO.MemoryMappedFiles.MemoryMappedFile]::OpenExisting('{8BA1E16C-FC54-4595-9782-E370A5FBE8DA}'); $stream = $config_handle.CreateViewStream(); $stream_reader = New-Object System.IO.StreamReader -ArgumentList $stream; $config_data = $stream_reader.ReadToEnd().Replace("`0", ""); $stream_reader.Dispose(); $stream.Dispose(); return $config_data | ConvertFrom-Json; } $config = GetConfig function SetRecording { Param($state) $headers = @{"X_LOCAL_SECURITY_COOKIE" = $config.secret}; $body = @{status = $state} | ConvertTo-Json; $uri = "http://localhost:$($config.port)/ShadowPlay/v.1.0/Record/Enable"; Invoke-RestMethod -Uri $uri -Method "Post" -ContentType "application/json" -Headers $headers -Body $body; } function SaveIR { $headers = @{"X_LOCAL_SECURITY_COOKIE" = $config.secret}; $uri = "http://localhost:$($config.port)/ShadowPlay/v.1.0/InstantReplay/Save"; Invoke-RestMethod -Uri $uri -Method "Post" -Headers $headers; } if ($args[0] -eq "start"){ SetRecording $true; } elseif ($args[0] -eq "stop"){ SetRecording $false; } elseif ($args[0] -eq "replay"){ SaveIR; } else { write-host("Command line arguments:"); write-host("start start manual record"); write-host("stop stop and save manual record"); write-host("replay save instant replay"); }
You are a legend! Thanks bro! Do you know what is the URI to enable and disable "Instant Replay"?
POST: "/ShadowPlay/v.1.0/InstantReplay/Enable"
BODY: {"status": true/false}
You might want to toggle desktop capture as well
POST: "'/ShadowPlay/v.1.0/DesktopCapture/Enable"
BODY: {"enable": true/false}
POST: "/ShadowPlay/v.1.0/InstantReplay/Enable" BODY: {"status": true/false}
You might want to toggle desktop capture as well
POST: "'/ShadowPlay/v.1.0/DesktopCapture/Enable" BODY: {"enable": true/false}
Again, you're a legend! Thanks dude! I'll be able to slap something together with this info you've given me 😊. I've been wanting to automatically record using scripts for a while now. I'll probably write something in Python or Node.js to automatically start and stop recording when I open certain executables.
Just wanted to say this is super interesting information and it's a shame that it is tucked away in a github issue! 😅 Great job with this repo in general. Thanks for your hard work!
I and others on the Internet would like to be able to control ShadowPlay programmatically using some kind of API. Would you like to create a small CLI application to interact with regular ShadowPlay so that you can enable or disable playback, or start or stop recording using CMD?