SuperZooper
New Member
I recently wrote a script that just fuzes text together and writes it to an obs source. From a bit of testing, it seems to be the cause of a c0000005 I am getting. Here is the info from the thread that crashes. I suspect it has something to do with not releasing an object correctly.
Here is the code for the script that I think is causing the crash. I think the problem will be somewhere in the second part of the code or in `write_output`.
Log file: https://obsproject.com/logs/vUgnwOeVLBIHUvqF
Code:
Unhandled exception: c0000005
Date/Time: 2021-10-26, 10:18:54
Fault address: 7FFF8E131C09 (c:\program files\obs-studio\obs-plugins\64bit\obs-text.dll)
libobs version: 27.1.3 (64-bit)
Windows version: 10.0 build 19043 (release: 2009; revision: 1288; 64-bit)
CPU: AMD Ryzen 5 2600 Six-Core Processor
Thread 12C0: (Crashed)
Stack EIP Arg0 Arg1 Arg2 Arg3 Address
000000D2444FF150 00007FFF8E131C09 0000000000000000 00007FFF8E1CD308 000000D2444FF1A8 00000239062E23E0 obs-text.dll!<lambda_880baa1155d709808c7f0b661ebf8f8d>::operator()+0x99
000000D2444FF180 00007FFF8E17E6DC 000002395F9FAE70 000000D2444FF7A0 0000000000000000 0000000000000000 obs.dll!obs_source_destroy+0x20c
000000D2444FF280 00007FFF8E1910EF 000000D2444FF7A0 00000000FFFFFFFF 0000000000000000 0000000000000160 obs.dll!obs_free_data+0x9f
000000D2444FF2B0 00007FFF8E195203 0000000000000000 000000D2444FF580 000000D2444FF7A0 000000D2444FF6E0 obs.dll!obs_shutdown+0x433
000000D2444FF300 00007FF71909B16A 000000D2444FF3D0 000000D200000000 00007FF719345ED0 000002395F94F5F0 obs64.exe!OBSApp::~OBSApp+0x5a
000000D2444FF330 00007FF7190A718E 0000000000000000 000002395F9743F0 0000023900000000 000002395F971EF0 obs64.exe!run_program+0x93e
000000D2444FF6A0 00007FF7190A9290 0000000000000000 0000000000000000 0000000000000000 FFFFFFFFFFFFFFFF obs64.exe!main+0x6c0
000000D2444FF870 00007FF71923E3D7 0000000000000000 0000000000000000 0000000000000000 0000000000000000 obs64.exe!WinMain+0x157
000000D2444FF900 00007FF71923DC96 0000000000000000 0000000000000000 0000000000000000 0000000000000000 obs64.exe!__scrt_common_main_seh+0x106
000000D2444FF940 00007FFF98E17034 0000000000000000 0000000000000000 0000000000000000 0000000000000000 kernel32.dll!0x7fff98e17034
000000D2444FF970 00007FFF99702651 0000000000000000 0000000000000000 0000000000000000 0000000000000000 ntdll.dll!0x7fff99702651
Here is the code for the script that I think is causing the crash. I think the problem will be somewhere in the second part of the code or in `write_output`.
Python:
import obspython as obs
TSourceOutputName = "" # Text source being written to in OBS
indexFile = "" # List of input text files to fuze
outputFile = "" # Path to the output file
formattingString = "" # Formatting string for the output text
lastString = "" # Compare last and new string
refreshTime = 5 # Refresh time of the text source
sleepTime = 20 # The polling rate when not active
timerSpeed = refreshTime
fileOutput = True
# ACTUAL TEXT UPDATING ------------------------------------------------------------
def update_text(props, prop):
global TSourceOutputName
global indexFile
global formattingString
global lastString
global sleepTime
# Read every line of the file at indexFile and add it to an array
paths = []
with open(indexFile) as file:
a = file.readlines()
for line in a:
paths.append(line.strip())
# Add the text of every file in paths to an array called texts
texts = []
for path in paths:
with open(path) as file:
texts.append(file.read())
outputText = formattingString
# Format the output text
for i in range(len(texts)):
if "%" + str(i+1) in outputText:
outputText = outputText.replace("%" + str(i+1), texts[i])
# Update the text source only if it has changed
if outputText != lastString:
lastString = outputText
write_output(outputText)
# Function to either write to a file, or to the text source in OBS
def write_output(message):
global fileOutput
global outputFile
global TSourceOutputName
# Create a new file called fuzed.txt at the path spectifed in outputFile and write the message to it, then close it
if fileOutput:
with open(outputFile, "a") as file:
# Clear the file
file.truncate(0)
# Write the message to the file
file.write(message)
else:
settings = obs.obs_data_create()
obs.obs_data_set_string(settings, "text", message)
obs.obs_source_update(obs.obs_get_source_by_name(TSourceOutputName), settings)
obs.obs_data_release(settings) # #NoMemLeaks
# OBS SETTINGS STUFF------------------------------------------------------------
def script_description():
return "Fuze text files and inject the output into a text source.\nThe Index file directory should be a list of file directorys for the text files you want to merge. Each file on its own line.\nUse `%I` where I is the number of the file you gave in (1 indexed) in the formating string to define how you want the outputed text to look. EX: `%1 - %2 / Song by: %3` \n\nBy SuperZooper3"
def script_update(settings):
global TSourceOutputName
global indexFile
global refreshTime
global formattingString
global sleepTime
global outputFile
global fileOutput
TSourceOutputName = obs.obs_data_get_string(settings, "TSourceOutputName")
indexFile = obs.obs_data_get_string(settings, "indexFile")
formattingString = obs.obs_data_get_string(settings, "formattingString")
refreshTime = obs.obs_data_get_int(settings, "refreshTime")
sleepTime = obs.obs_data_get_int(settings, "sleepTime")
outputFile = obs.obs_data_get_string(settings, "outputFile")
fileOutput = obs.obs_data_get_bool(settings, "fileOutput")
# Update the refresh timer
obs.timer_remove(refresh_text)
if refreshTime > 0 and indexFile != "" and formattingString != "" and (not fileOutput and TSourceOutputName != "" or (fileOutput and outputFile != "")):
obs.timer_add(refresh_text, refreshTime * 1000)
def script_defaults(settings): # Sets the defaults for the values in the obs editor
obs.obs_data_set_default_int(settings, "refreshTime", 5)
obs.obs_data_set_default_int(settings, "sleepTime", 20)
# This needs to be here for the refresh button to work
def refresh_text():
global timerSpeed
# Update the poling rate to the apporiate value
if obs.obs_source_active(obs.obs_get_source_by_name(TSourceOutputName)) and refreshTime != timerSpeed:
obs.timer_remove(refresh_text)
obs.timer_add(refresh_text, refreshTime * 1000)
timerSpeed = refreshTime
elif not obs.obs_source_active(obs.obs_get_source_by_name(TSourceOutputName)) and timerSpeed != sleepTime:
obs.timer_remove(refresh_text)
obs.timer_add(refresh_text, sleepTime * 1000)
timerSpeed = sleepTime
# Update the text
if obs.obs_source_active(obs.obs_get_source_by_name(TSourceOutputName)):
update_text(props="", prop="")
def script_properties(): # Get the property boxes so we cant use them here
props = obs.obs_properties_create()
# All of the input boxes
# The text source
p = obs.obs_properties_add_list(props, "TSourceOutputName", "Text Output Source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)
sources = obs.obs_enum_sources()
if sources is not None:
for source in sources:
source_id = obs.obs_source_get_unversioned_id(source)
if source_id == "text_gdiplus" or source_id == "text_ft2_source":
name = obs.obs_source_get_name(source)
obs.obs_property_list_add_string(p, name, name)
obs.source_list_release(sources)
obs.obs_properties_add_path(props, "indexFile", "Index File Directory", obs.OBS_PATH_FILE, "", "")
obs.obs_properties_add_text(props, "formattingString", "Formatting String", obs.OBS_TEXT_DEFAULT)
obs.obs_properties_add_int(props, "refreshTime", "Refresh Time", 1, 999, 1)
obs.obs_properties_add_int(props, "sleepTime", "Sleep Refresh Time", 1, 999, 1)
obs.obs_properties_add_path(props, "outputFile", "Output File (.txt)", obs.OBS_PATH_FILE, "", "")
obs.obs_properties_add_bool(props, "fileOutput", "Output to File (true) or to source (false)")
# Refresh button
obs.obs_properties_add_button(props, "button", "Refresh", update_text)
return props
Log file: https://obsproject.com/logs/vUgnwOeVLBIHUvqF