First commit
This commit is contained in:
commit
68a84becdc
|
@ -0,0 +1,10 @@
|
|||
[DEFAULT]
|
||||
# User config folder
|
||||
# These settings can override all of the other settings
|
||||
userConfig=$SYS:HOME$/.config/ffreplay/ffreplay.ini
|
||||
|
||||
# Input options
|
||||
input=["-f","pulse","-i","1","-framerate","30","-f","x11grab","-i",":0.0+0,0"]
|
||||
|
||||
# Temporary storage folder. THIS FOLDER WILL BE DELETED. CHOOSE A NON-EXISTANT FOLDER.
|
||||
temp=/dev/shm/ffreplay-$PID$
|
|
@ -0,0 +1,10 @@
|
|||
[DEFAULT]
|
||||
# User config folder
|
||||
# These settings can override all of the other settings
|
||||
userConfig=$SYS:APPDATA$/ffreplay/ffreplay.ini
|
||||
|
||||
# Input options
|
||||
input=["-f","dshow","-i","audio=virtual-audio-capturer","-f","gdigrab","-framerate","30","-i","desktop"]
|
||||
|
||||
# Temporary storage folder. THIS FOLDER WILL BE DELETED. CHOOSE A NON-EXISTANT FOLDER.
|
||||
temp=$SYS:TEMP$/ffreplay-$PID$
|
|
@ -0,0 +1,19 @@
|
|||
[DEFAULT]
|
||||
# Binary
|
||||
# The path to the binary to run for recording
|
||||
binary=ffmpeg
|
||||
|
||||
# Output path
|
||||
# Where should replays be saved?
|
||||
outputPath=$SP$/ffreplay-$TIME$
|
||||
|
||||
# Segment time
|
||||
# How long a segment of video is, in seconds
|
||||
segmentTime=30
|
||||
|
||||
# Segment amount
|
||||
# How many segments should be recorded at maximum. If you want a recording that is 10 minutes at least, and your segment time is 30, you want to set 21 -- 21 * 30 seconds = 630 seconds at maximum, 600 seconds at minimum
|
||||
segmentCount=21
|
||||
|
||||
# Output options, formatted in json
|
||||
output=["-c:v","libx264","-pix_fmt","yuv420p","-preset","ultrafast","-c:a","aac","-b:a","128k","-bufsize","20M","-maxrate","10M","-f","mpegts","-f","segment","-segment_time","$CONF:DEFAULT/segmentTime$","-segment_wrap","$CONF:DEFAULT/segmentCount$","-segment_list","$CONF:DEFAULT/temp$/segments.ffcat","-segment_list_type","ffconcat","-segment_list_size","$CONF:DEFAULT/segmentCount$","$CONF:DEFAULT/temp$/seg%d.ts"]
|
|
@ -0,0 +1,166 @@
|
|||
#!/usr/bin/env python3
|
||||
import sys
|
||||
|
||||
oldexcepthook = sys.excepthook
|
||||
def newexcepthook(type,value,traceback):
|
||||
oldexcepthook(type,value,traceback)
|
||||
input("Press ENTER to quit.")
|
||||
sys.excepthook = newexcepthook
|
||||
|
||||
import os
|
||||
p = os.path.join
|
||||
pUp = os.path.dirname
|
||||
s = False
|
||||
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
|
||||
s = os.path.realpath(sys.executable)
|
||||
else:
|
||||
s = os.path.realpath(__file__)
|
||||
sp = pUp(s)
|
||||
|
||||
import platform
|
||||
import configparser
|
||||
import subprocess
|
||||
import json
|
||||
import shutil
|
||||
import datetime
|
||||
import math
|
||||
|
||||
print("Grabbing system info...")
|
||||
pid = os.getpid()
|
||||
osName = platform.system().lower()
|
||||
if osName == "darwin": osName = "macos"
|
||||
|
||||
def configToDict(conf):
|
||||
out = {}
|
||||
for group in conf:
|
||||
out[group] = {}
|
||||
for key in conf[group]:
|
||||
out[group][key] = conf[group][key]
|
||||
return out
|
||||
|
||||
def makeEnvironment(config = False):
|
||||
print("Creating environment...")
|
||||
cenv = {}
|
||||
cenv["SP"] = sp
|
||||
cenv["OS"] = osName
|
||||
cenv["PID"] = pid
|
||||
if config:
|
||||
for group in config:
|
||||
for key in config[group]:
|
||||
value = config[group][key]
|
||||
path = group+ "/" +key
|
||||
cenv["CONF:" +path] = value
|
||||
|
||||
for env in os.environ:
|
||||
cenv["SYS:" +env] = os.environ[env]
|
||||
|
||||
print(json.dumps(cenv,indent=2))
|
||||
print("")
|
||||
return cenv
|
||||
|
||||
def applyEnvironment(cenv,config):
|
||||
print("Applying environment...")
|
||||
found = True
|
||||
while found == True:
|
||||
found = False
|
||||
for group in config:
|
||||
for key in config[group]:
|
||||
value = config[group][key]
|
||||
for var in cenv:
|
||||
varStr = "$" +var+ "$"
|
||||
if varStr in value:
|
||||
found = True
|
||||
value = value.replace(varStr,str(cenv[var]))
|
||||
config[group][key] = value
|
||||
print(json.dumps(configToDict(config),indent=2))
|
||||
print("")
|
||||
|
||||
def waitForInput():
|
||||
inp = sys.stdin.read(1)
|
||||
return
|
||||
|
||||
def getTimeString():
|
||||
now = datetime.datetime.now()
|
||||
nowl = [
|
||||
str(now.year),str(now.month),str(now.day),
|
||||
str(now.hour),str(now.minute),str(now.second),
|
||||
str(math.floor(now.microsecond / 10000))
|
||||
]
|
||||
|
||||
index = 0
|
||||
while (index < 7):
|
||||
value = nowl[index]
|
||||
if len(value) < 2: nowl[index] = "0" + value
|
||||
index = index + 1
|
||||
|
||||
return "-".join(nowl[0:3]) + "_" + "-".join(nowl[3:6]) + "." +nowl[6]
|
||||
|
||||
def main():
|
||||
# Setup
|
||||
print("Loading configs...")
|
||||
configPath = os.path.splitext(s)[0]
|
||||
configPathOS = configPath + "-" +osName+ ".ini"
|
||||
if not os.path.isfile(configPathOS):
|
||||
print("Warning: No OS-specific config found (" +configPathOS+ "), falling back to linux defaults")
|
||||
configPathOS = configPath + "-linux.ini"
|
||||
configPath += ".ini"
|
||||
|
||||
config = configparser.ConfigParser(interpolation=None)
|
||||
config.optionxform = str
|
||||
config.read(configPath)
|
||||
if os.path.isfile(configPathOS): config.read(configPathOS)
|
||||
|
||||
ffrEnv = makeEnvironment(config)
|
||||
applyEnvironment(ffrEnv,config)
|
||||
|
||||
if os.path.isfile(config["DEFAULT"]["userConfig"]):
|
||||
print("Reading user-specific config...")
|
||||
config.read(config["DEFAULT"]["userConfig"])
|
||||
ffrEnv = makeEnvironment(config)
|
||||
applyEnvironment(ffrEnv,config)
|
||||
|
||||
cmdBinary = config["DEFAULT"]["binary"]
|
||||
cmdInput = json.loads(config["DEFAULT"]["input"])
|
||||
cmdOutput = json.loads(config["DEFAULT"]["output"])
|
||||
|
||||
# Main
|
||||
if len(sys.argv[1:]) > 0:
|
||||
if sys.argv[1] in ["c","convert"]:
|
||||
for arg in sys.argv[2:]:
|
||||
proc = subprocess.Popen([cmdBinary,"-f","concat","-safe","0","-i",p(arg,"segments.ffcat"),"-c","copy","-map","0","-movflags","+faststart",arg + ".mp4"])
|
||||
proc.wait()
|
||||
sys.exit(0)
|
||||
|
||||
if os.path.isdir(config["DEFAULT"]["temp"]):
|
||||
shutil.rmtree(config["DEFAULT"]["temp"])
|
||||
|
||||
proc = False
|
||||
try:
|
||||
while True:
|
||||
os.makedirs(config["DEFAULT"]["temp"])
|
||||
proc = subprocess.Popen(
|
||||
[cmdBinary] + cmdInput + cmdOutput,
|
||||
stdin=subprocess.PIPE
|
||||
)
|
||||
|
||||
waitForInput()
|
||||
timeString = getTimeString()
|
||||
proc.communicate(input=b'q')
|
||||
proc.wait()
|
||||
|
||||
shutil.copytree(config["DEFAULT"]["temp"],config["DEFAULT"]["outputPath"].replace("$TIME$",timeString))
|
||||
shutil.rmtree(config["DEFAULT"]["temp"])
|
||||
except:
|
||||
try:
|
||||
proc.communicate(input=b'q')
|
||||
proc.wait()
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
shutil.rmtree(config["DEFAULT"]["temp"])
|
||||
except Exception as e2:
|
||||
raise e2
|
||||
raise
|
||||
|
||||
main()
|
Loading…
Reference in New Issue