Repository navigation
Expand file tree
/
Copy pathirl-stats.lua
More file actions
115 lines (97 loc) · 4.07 KB
/
Copy pathirl-stats.lua
File metadata and controls
115 lines (97 loc) · 4.07 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
-- Updates a text source with IRL Source stats.
--
-- The stats come from the plugin's "get_stats" proc handler, the same entry
-- point the obs-websocket vendor extension calls, so both report the same
-- numbers. Field names and types are documented in README.md.
obs = obslua
local last_text = nil
-- Empty means "find the source by its plugin id", which works whatever the
-- user renamed it to. Set it only when more than one IRL source exists.
local irl_source_name = ""
local text_source_name = "IRL Stats"
local IRL_SOURCE_ID = "irl_source"
function script_description()
return "Updates a text source with IRL Source stats.\n\n" ..
"Leave the source name empty to use the first IRL Source found."
end
function script_defaults(settings)
obs.obs_data_set_default_string(settings, "irl_source_name", "")
obs.obs_data_set_default_string(settings, "text_source_name", "IRL Stats")
end
function script_properties()
local props = obs.obs_properties_create()
obs.obs_properties_add_text(props, "irl_source_name",
"IRL source name (optional)", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_text(props, "text_source_name",
"Text source to update", obs.OBS_TEXT_DEFAULT)
return props
end
function script_update(settings)
irl_source_name = obs.obs_data_get_string(settings, "irl_source_name")
text_source_name = obs.obs_data_get_string(settings, "text_source_name")
last_text = nil
end
-- Returns a source reference the caller must release, or nil.
local function find_irl_source()
if irl_source_name ~= "" then
return obs.obs_get_source_by_name(irl_source_name)
end
-- By id rather than by display name: the source can be renamed, and the
-- default name is localised.
local found = nil
local sources = obs.obs_enum_sources()
if sources ~= nil then
for _, source in ipairs(sources) do
if obs.obs_source_get_unversioned_id(source) == IRL_SOURCE_ID then
found = obs.obs_source_get_ref(source)
break
end
end
obs.source_list_release(sources)
end
return found
end
function update_stats()
local source = find_irl_source()
if not source then return end
local ph = obs.obs_source_get_proc_handler(source)
local cd = obs.calldata_create()
obs.proc_handler_call(ph, "get_stats", cd)
local buf_ms = obs.calldata_int(cd, "buffer_fill_ms")
local speed = obs.calldata_float(cd, "current_speed")
local reconnecting = obs.calldata_bool(cd, "reconnecting")
local video = obs.calldata_int(cd, "total_video_frames")
local audio = obs.calldata_int(cd, "total_audio_frames")
local max_gap = obs.calldata_int(cd, "pts_max_gap_ms")
local underruns = obs.calldata_int(cd, "audio_underruns")
local restarts = obs.calldata_int(cd, "audio_output_restarts")
local video_delay = obs.calldata_int(cd, "video_delay_ms")
local skew = obs.calldata_int(cd, "av_skew_ms")
local hold = obs.calldata_int(cd, "audio_hold_ms")
obs.calldata_destroy(cd)
obs.obs_source_release(source)
local status = reconnecting and "RECONNECTING" or "LIVE"
local text = string.format(
"Status: %s\nBuffer: %dms\nSpeed: %.3fx\nA/V skew: %dms (hold %dms, video delay %dms)\nUnderruns/Restarts: %d/%d\nMax PTS gap: %dms\nFrames: %d/%d (v/a)",
status, buf_ms, speed, skew, hold, video_delay, underruns, restarts,
max_gap, video, audio
)
-- Re-rendering the text texture is the expensive part; skip it
-- when nothing changed (e.g. while reconnecting or idle).
if text == last_text then return end
local text_source = obs.obs_get_source_by_name(text_source_name)
if text_source then
local settings = obs.obs_data_create()
obs.obs_data_set_string(settings, "text", text)
obs.obs_source_update(text_source, settings)
obs.obs_data_release(settings)
obs.obs_source_release(text_source)
last_text = text
end
end
function script_load(settings)
obs.timer_add(update_stats, 1000)
end
function script_unload()
obs.timer_remove(update_stats)
end