Repository navigation
Expand file tree
/
Copy pathplugin.json
More file actions
150 lines (150 loc) · 5.62 KB
/
Copy pathplugin.json
File metadata and controls
150 lines (150 loc) · 5.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
{
"name": "Underfed",
"version": "0.6.0",
"description": "Moves a channel off a source that is starving it, drifting its sound or refusing it: to the next source when the stream arrives at a fraction of its bitrate or with its timestamps apart, to the back of the chain when the provider answers 403.",
"author": "PilaScat",
"license": "MIT",
"source_type": "external",
"repo_url": "https://github.com/PilaScat/underfed",
"help_url": "https://github.com/PilaScat/underfed#readme",
"source_url": "https://github.com/PilaScat/underfed/releases/download/v{version}/underfed-{version}.zip",
"fields": [
{
"id": "api_key",
"label": "API key *",
"type": "string",
"default": "",
"help_text": "A Dispatcharr API key. Settings → Users → the account whose key you want to use. The watcher needs it to read channel status and to change source."
},
{
"id": "observe_only",
"label": "Observe only",
"type": "boolean",
"default": true,
"help_text": "Records what it would have done without doing it. Leave it on for the first evening, then read the journal under Check status."
},
{
"id": "ratio_percent",
"label": "Trigger below (% of content rate)",
"type": "number",
"default": 70,
"help_text": "reservoarr reports how many bytes have arrived (in_total) and how many bits the picture needs (crate). Below this share over the last 45 seconds, with the cushion empty, the source counts as underfed."
},
{
"id": "confirm_seconds",
"label": "Confirm for (seconds)",
"type": "number",
"default": 45,
"help_text": "How long a shortfall must last before acting. Short dips recover on their own: the provider's CDN delivers in bursts of about ten seconds."
},
{
"id": "max_switches",
"label": "Switches per hour, per channel",
"type": "number",
"default": 2,
"help_text": "Stops a channel bouncing between two sources that are both weak."
},
{
"id": "warmup_seconds",
"label": "Ignore first (seconds)",
"type": "number",
"default": 60,
"help_text": "Right after a channel opens the measured content rate is not trustworthy yet."
},
{
"id": "stable_seconds",
"label": "Stable after (seconds)",
"type": "number",
"default": 180,
"help_text": "A source that holds up this long is treated as recovered."
},
{
"id": "storm_per_minute",
"label": "Timestamp discontinuities (per minute)",
"type": "number",
"default": 100,
"help_text": "When a source's audio and video timestamps are far apart, the sound drifts away from the picture and reservoarr's ffmpeg logs hundreds of \"timestamp discontinuity\" lines a minute; a healthy source logs a handful. At this many the source is switched. 0 turns it off."
},
{
"id": "storm_confirm_seconds",
"label": "Confirm discontinuities for (seconds)",
"type": "number",
"default": 15,
"help_text": "How long the timestamp discontinuities must stay above the threshold before acting. A storm is unmistakable and the sound drifts further with every second of it, so this is shorter than the shortfall's confirmation."
},
{
"id": "demote_minutes",
"label": "Refused source held back (minutes)",
"type": "number",
"default": 30,
"help_text": "A source the provider answers 403 to goes last in its channel's chain, ahead of the fallback card, so the next tune-in does not start on it again. It climbs back after these minutes. 0 turns it off."
},
{
"id": "exclude_channels",
"label": "Excluded channels",
"type": "text",
"default": "",
"help_text": "One channel name per line. Those keep whatever source they are on."
},
{
"id": "telemetry_path",
"label": "reservoarr log",
"type": "string",
"default": "/data/scripts/logs/delaybuf.log",
"help_text": "Where reservoarr writes delaybuf.log inside this container. Change it only if RESV_LOG_DIR was moved."
},
{
"id": "api_url",
"label": "Dispatcharr URL",
"type": "string",
"default": "http://127.0.0.1:9191",
"help_text": "Reached from inside the container. Change it only on a non-standard port."
}
],
"actions": [
{
"id": "apply",
"label": "Apply settings",
"description": "Applies the settings above and starts the watcher.",
"button_label": "Apply",
"button_variant": "filled"
},
{
"id": "status",
"label": "Check status",
"description": "Reports whether the watcher is running and what it changed recently.",
"button_label": "Check",
"button_variant": "default"
},
{
"id": "test",
"label": "Replay the log",
"description": "Runs the current thresholds over the whole log without changing anything.",
"button_label": "Replay",
"button_variant": "default"
},
{
"id": "restart",
"label": "Restart watcher",
"description": "Starts the watcher again if it is down.",
"button_label": "Restart",
"button_variant": "default",
"events": [
"channel_start"
]
},
{
"id": "remove",
"label": "Stop watcher",
"description": "Stops the watcher and leaves every channel on its current source.",
"button_label": "Stop",
"button_variant": "default",
"button_color": "red",
"confirm": {
"required": true,
"title": "Stop the watcher?",
"message": "Underfed sources will no longer be moved to the next source in the chain."
}
}
]
}