This commit is contained in:
Izaya 2022-04-19 02:17:22 +10:00
parent eb281f99e6
commit 963a7365c3
5 changed files with 137 additions and 1 deletions

View File

@ -1,3 +1,29 @@
# stream-scripts
Scripts to help automate my cursed streaming setup
This is a set of scripts to help automate my cursed streaming setup. It's divided into two parts:
- The "client" side, ie my desktop. This part spews video and audio minimally compressed over the LAN to the server side.
- The "server" side, which does all the heavy lifting to reduce the load on my desktop.
## Requiremens
- ffmpeg
- pulseaudio
- bash
- Lua (optional)
## Client side.
Included are two scripts, `recordscreen.sh`, and `paremap.lua`.
`recordscreen.sh` is fairly self-explanatory, it records the screen, pulls audio from pulseaudio, and spews it over the LAN. Doesn't take any arguments, but you'll need to modify it for your needs if you're going to use it yourself.
`paremap.lua` is less obvious. I listen to music when I stream games, and I want to be able to keep that separate for any actual recordings, for both legal reasons potential future technical reasons. This script will automatically shift over any matching applications to the third, not-included part of the client setup, detailed below.
In order to keep game audio (or whatever else) separate from the rest of my system, I'm using the pulseaudio `module-combine-sink` module, which just creates a secondary sink that also outputs to my speakers/headphones, but can be recorded from separately. To set one up, use `load-module module-combine-sink` in your default.pa.
## Server side.
`record.sh` is a straightforward recording program that won't waste tonnes of space. It takes input over the LAN and records it to disk, with all the audio streams intact. Takes the prefix as an argument, so it can label the file.
`stream.sh` is more ... interesting. It does everything that record.sh does, but also spews the video and one audio track to a stream URL of your choice. Takes the file prefix, and a stream URL, as arguments.

25
client/paremap.lua Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/env lua
local games = {"mpv Media Player"}
for k,v in pairs(games) do
games[v] = true
end
local sinkname = "combined"
local running = {}
local input
for line in io.popen("pactl list sink-inputs 2>&1","r"):read("*a"):gmatch("[^\n]+") do
if line:match("Sink Input #(%d+)") then
input = line:match("Sink Input #(%d+)")
elseif line:match('application.name = "([^"]+)') then
running[line:match('application.name = "([^"]+)')] = input
end
end
for k,v in pairs(running) do
if games[k] then
print("Match",k)
print(string.format("pacmd move-sink-input '%d' '%s'",v,sinkname))
os.execute(string.format("pacmd move-sink-input '%d' '%s'",v,sinkname))
end
end

34
client/recordscreen.sh Executable file
View File

@ -0,0 +1,34 @@
#!/bin/bash
monitor=$(pactl list short sources | grep output | grep monitor | cut -d ' ' -f 2)
mic=$(pactl list short sources | grep input | cut -d ' ' -f 2)
combined=$(pactl list short sources | grep combined | cut -d ' ' -f 2)
echo $monitor $mic $combined
ffmpeg \
-hide_banner \
-thread_queue_size 512 \
-video_size 1920x1200 \
-framerate 30 \
-f x11grab \
-i :0.0+1050+0 \
-thread_queue_size 512 \
-f pulse \
-channel_layout stereo \
-i "$monitor" \
-thread_queue_size 512 \
-f pulse \
-channel_layout stereo \
-i "$mic" \
-thread_queue_size 512 \
-f pulse \
-channel_layout stereo \
-i "$combined" \
-c:a aac \
-b:a 256k \
-c:v libx264rgb \
-crf 0 \
-preset ultrafast \
-f mpegts \
-map 0 \
-map 1 \
-map 2 \
-map 3 tcp://10.0.1.22:9999

18
server/record.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
ofile="$1-$(date +%Y-%m-%dT%H-%M-%S).mkv"
ffmpeg \
-hide_banner \
-protocol_whitelist rtp,file,udp,crypto,tcp \
-listen 1 \
-i tcp://10.0.1.22:9999?listen,overrun_nonfatal \
-c:v libx264 -pix_fmt yuv420p -threads 0 \
-map 0 \
-c:a copy \
-crf 18 \
-tune zerolatency \
-preset slow \
-maxrate 7.5M \
-bufsize 35M \
-max_muxing_queue_size 9999 \
"$ofile"
echo "$ofile"

33
server/stream.sh Executable file
View File

@ -0,0 +1,33 @@
#!/bin/bash
ofile="$1-$(date +%Y-%m-%dT%H-%M-%S).mkv"
ffmpeg \
-hide_banner \
-protocol_whitelist rtp,file,udp,crypto,tcp \
-listen 1 \
-i tcp://10.0.1.22:9999?listen,overrun_nonfatal \
-filter_complex '[0:v]split=2[v1][v2];[0:a:0]asplit=2[a1][a2];[v2]scale=w=1280:h=-1[v3]' \
-map '[v1]' \
-map '[a1]' \
-map '0:a:1' \
-map '0:a:2' \
-c:v libx264 -pix_fmt yuv420p -threads 0 \
-c:a libopus -b:a 128k \
-crf 18 \
-tune zerolatency \
-preset slow \
-maxrate 7.5M \
-bufsize 35M \
-max_muxing_queue_size 9999 \
"$ofile" \
-map '[v3]' \
-map '[a2]' \
-c:v libx264 -pix_fmt yuv420p -threads 0 \
-c:a aac -b:a 128k \
-crf 18 \
-tune zerolatency \
-preset slow \
-maxrate 3.5M \
-bufsize 35M \
-f flv \
"$2"
echo "$ofile"