A kotlin application for automatic recording lives from StripChat.
usage:
-f,--file <arg> Room List File [default: list.conf]
-post <arg> Post Processor Config File [default: postprocessor.json]
-o,--output <arg> Output Dir [default: out]
-p,--port <arg> Server Port [default: 8090]
-t,--tmp <arg> Temp Dir [default: tmp]
java -jar XhRec-all.jarjava -jar XhRec-all.jar -p 12340 -f list.conf -post postprocessor.json -t /path/to/temp/folder -o /path/to/destnation/folder-
Go to the Extensions page by entering
chrome://extensionsin a new tab. (By designchrome://URLs are not linkable.)- Alternatively, click the Extensions menu puzzle button and select Manage Extensions at the bottom of the menu.
- Or, click the Chrome menu, hover over More Tools, then select Extensions.
-
Enable Developer Mode by clicking the toggle switch next to Developer mode.
-
Replace
docker.lan:8090inextension/popup.jsto your own server address. -
Click the Load unpacked button and select the
extensiondirectory.

# https://zh.xhamsterlive.com/modelA q:720p limit:120
; https://zh.xhamsterlive.com/modelB q:240p
https://zh.xhamsterlive.com/modelC q:raw
- Start with
#or;will be marked asINACTIVE, means will not automatically start recording. - limit:120 means record time (in seconds). NOT RECOMMEND, MAY EASILY CORRUPT YOUR VIDEO.
- q:XXXX means preferred quality, raw means original quality. If no quality matches, program will select closest one.
zh.is optional, dont care about it.
Run processors one by one.
{
"default": [
{
"type": "fix_stamp",
"output": "out"
},
{
"type": "move",
//{{ROOM_NAME}} Model/Room name
//{{ROOM_ID}} 12345
//{{RECORD_START}} formated date time using "date_pattern"
//{{RECORD_END}} formated date time using "date_pattern"
//{{RECORD_DURATION}} 90
//{{RECORD_DURATION_STR}} 00h01m30s
//{{INPUT}} /path/to/input/video/folder/a.mp4
//{{INPUT_DIR}} /path/to/input/video/folder
//{{FILE_NAME}} a.mp4
//{{FILE_NAME_NOEXT}} a
//{{TOTAL_FRAMES}} slow but accurate frame count
//{{TOTAL_FRAMES_GUESS}} FPS*Duration
"dest": "out/[{{ROOM_ID}}]{{ROOM_NAME}}@{{RECORD_START}}-{{RECORD_END}} {{RECORD_DURATION_STR}}",
"date_pattern": "yyyy年MM月dd日HH时mm分ss秒"
},
{
"type": "slice",
"duration": "1m10s"
},
// generate grid thumbnail (20x20, 400pic total)
{
"type": "shell",
"noreturn": true,
// default: true
"remove_input": false,
//{{ROOM_NAME}} Model/Room name
//{{ROOM_ID}} 12345
//{{RECORD_START}} formated date time using "ISO_DATE_TIME" format
//{{RECORD_END}} formated date time using "ISO_DATE_TIME" format
//{{RECORD_DURATION}} 90
//{{RECORD_DURATION_STR}} 00h01m30s
//{{INPUT}} /path/to/input/video/folder/a.mp4
//{{INPUT_DIR}} /path/to/input/video/folder
//{{FILE_NAME}} a.mp4
//{{FILE_NAME_NOEXT}} a
//{{TOTAL_FRAMES}} slow but accurate frame count
//{{TOTAL_FRAMES_GUESS}} FPS*Duration
"args": [
"ffmpeg",
"-hide_banner",
"-loglevel",
"error",
"-stats",
"-i",
"{{INPUT}}",
"-vf",
// if you change grid size, please recalculate total pic size
// or replace '{{TOTAL_FRAMES_GUESS}}/400' to 50, which means every 50 frames will be one thumbnail
"thumbnail={{TOTAL_FRAMES_GUESS}}/400,scale=200:-1,tile=20x20",
"-vframes",
"1",
"{{INPUT_DIR}}\\{{FILE_NAME_NOEXT}}.thumb.png",
"-y"
]
}
]
}| Parameter | Description |
|---|---|
| slug | Room/Model name |
| quality | Quality, default 720p |
| active | Start auto recording |
Temporary stop recording
| Parameter | Description |
|---|---|
| slug | Room/Model name |
| Parameter | Description |
|---|---|
| slug | Room/Model name |
| Parameter | Description |
|---|---|
| slug | Room/Model name |
| Parameter | Description |
|---|---|
| slug | Room/Model name |
| Parameter | Description |
|---|---|
| slug | Room/Model name |
| quality | Quality |
Simple json status list
Json status
{
"Model Name": {
//total segments
"total": 10046,
//succeed segments
"success": 9933,
//failed segments
"failed": 98,
//total bytes
"bytesWrite": 1409108341,
//running segments
"running": {
"https://xxxx_part3.mp4": {
// using PROXY
"type": "PROXY",
// start download time
"startAt": 1756357723403
},
"https://xxxx_part1.mp4": {
"type": "DIRECT",
"startAt": 1756357716154
}
}
}
}[
{
"name": "Model Name",
"id": 12345,
"quality": "720p60",
// record limit, PT2M means 2 minutes (ISO-8601 Duration format)
// not recommand, may easily break you video.
"limit": "PT2M",
// useless for now
"lastSeen": null
}
]Finish all recording tasks. The server won't shut down for some reason, but it's safe to kill the process when this api responds.
Prometheus metrics
You can build monitor like this:
Custom logging: #16
Logs will be saved to ./logs.
Daily rename logs to logs/xhrec.%d{yyyy-MM-dd}.log.


