How to a create simple custom user interface inside OBS Studio with a Lua Script

12 min read Mar 13, 2021

Here is an example of what can be possible using Lua with OBS Studio

An example of what I created with Lua inside OBS Studio

Some background about myself before we get started…

Hello, my name is Chris Orellana and I recently created a small design startup called MoreBackgroundsPlease, on the popular e-commerce website Etsy, that is focused on creating and selling animated streaming overlays for streamers across Facebook, Youtube, and Twitch.

Please feel free to skip down to the “Tutorial” section to skip all the introductions and to get right to it. Please note that this tutorial was written for the Windows 10 operating system with the current latest version of OBS Studio. (As of this writing on March 12, 2021, the version is 26.1.1)

Although I am incredibly passionate about motion design, a good portion of my background comes from my career as a technician in the field of Information Technology.

I have worked from being a tech assistant to currently as a manager at a prestigious university. I have always dabbled and thrown myself in the world of coding.

On my Github page I have shared several of my code where I have written in various languages such as using Bash to create local server storage backups, to using Swift inside Xcode to create an iOS app that would communicate with the JAMF API.

Small animation displaying the test app I created for one of my IT projects at my curent position

Why Lua and not Python?

Below I will briefly describe why I am using Lua inside OBS Studio but I can break it down into three reasons:

  1. I came across other companies such as Nerd Or Die and Visuals By Impulse that also create Lua scripts and include them in their Stream Overlay Packages that they sell to their customers
  2. OBS Studio can support Python and Lua, but OBS comes with Lua already included
  3. I love learning new things, and Lua was definitely new to me

— Currently, as of March 12, 2021, OBS Studio version 26.1.1 supports two scripting languages, Lua, and Python.

Although I am definitely more familiar with Python, OBS Studio requires that you have already installed a version of Python on your machine, and that you point to where your local version of Python resides.

If you open up the Scripts Window in OBS Studio, you will find that you have to set the Install Path to your Python install.

Lua on the other hand already comes included with an installation of OBS Studio. So this is where we will take advantage of making our own cool user interfaces right inside OBS.

Why I wrote this

Because it was a bit difficult learning on Lua for OBS on my own, since there was such limited resources available online, and just a small niche of people who were actually developing with Lua inside OBS Studio. I have seen some really cool projects and can share them below. I will also share some more useful resources at the end of this article.

How to add a timestamp to your streams: https://dev.to/hectorleiva/start-to-write-plugins-for-obs-with-lua-1172

How to add a cool floating bouncing logo on your stream: https://jbscript.dev/my-first-lua-and-obs-script/

Dreamstime.com is the official owner of this stock footage. I do not claim this image as my own.

With such a popular software within the gaming streaming community, I have seen plenty of graphic designers working on overlays for their streams.

I want to give fellow designers a glimpse into how they can also include a cool an easy script into their workflow and make some really interesting stuff.

You can check out one of my Lua scripts here: https://github.com/Chriscodinglife/OBS-Scene-Creator-Gui-via-Lua-Script

Tutorial

In this tutorial I will cover the following:

  1. How to add text and images (in Base64) to the interface
  2. How to add clickable URL links
  3. How to add a clickable button

I will try my best to explain what I am doing as I go throughout the code. But common programming terms such as methods, libraries, and variables, and what exactly is a script file I will not cover in this tutorial.

If you do not have a text editor such as Sublime Text or Visual Studio, I definitely recommend downloading one now.

(I currently prefer to use Sublime Text 3 since it is completely free and lightweight, and I will be referencing this software as we go along, but please feel free to use any text editor of your choice.)

Let’s get started.

Open up Sublime Text 3, and lets create a new file and save it with any name you like but make sure it has the extension “.lua” at the end. (Without the quotes)

I have named mine “my_script.lua” and you can see the name of your file on the top left on the tab.

To communicate with OBS Studio through Lua, we need to tell OBS to import the OBS Lua library. Type the following:

obs = obslua

We will store or instantiate the “obslua” library as the variable “obs”, that way when we need to access any methods from the obslua library, we can simply use the variable “obs” instead.

Convert an Image to Base 64

Let’s add our first image. Our script can accept images encoded as Base64. Base64 in simple terms is a long string of text data used to represent image data. So to add our image, we will have to convert our image first to Base64.

Find an image you would like to add. I am going to use the MBP in .png format for this example. Visit the following website and drag and drop your image onto the website.

Once completed you should now have the following options.

Select the option “copy image.” This should copy a long data string that we will import into our script. You can also click on “show code” to see how the string looks like.

Back inside our script let us create a new variable called “image1” and assigning it as a local variable. Then within quotes, paste your copied text into your script. You have something like this:

local image1 = "your_copied_text"

For simplicity I have cut off the rest of the text in my example image above. But for your script make sure that your entire copied string rests inside quotation marks.

How to Add Your Image, and adding Text

Create a new local variable called “description” and start it with two open brackets. Add some space below by pressing enter a few times.

local description = [[

If you have experience with coding with HTML, then your in luck, as we will be using some HTML. I thank bfxdev over on the OBSProjects forum for showing how to do this.

On your new line let’s create a title. Add a center tag along with a Header 2 tag and write the name of your user interface. I will name mine “Dope Interface”

<center><h2> Your title goes here</h2></center>

Now lets call our image1 and add it into our description variable. Add a center tag and then define the image width and height. I found that reducing your image dimensions proportionally is best. For example my MBP logo image is 500px by 500px so I defined the width and height as 60 and 60.

When we define source “src” we will be calling our image1 variable. To do this do the following:

<center><img width=60 height=60 src=']] .. image1 .. [['/></center>

You might have noticed two things:

  1. There is a new darkened text above our image1 variable.
  2. I added a new paragraph tag between my “Dope Interface” title and my image1 within the description variable.

To add a comment inside Lua you can use two dashes “-”. Comments are great for letting your future self know what you did in a certain part of your code, or for letting another programmer know about how something works inside your code. Either way, definitely take advantage of comments in any script you make, as it can be a lifesaver in the future.

To add some space between objects, add a “<p>” tag.

How to Add a Clickable URL Link

Now let’s say you want to add a link to your interface that people can click on and take them to a specific website. You can do the following:

<center>Click here to open Google: <a href="https://www.google.com/">Search on Google</a></center>

Now it might be hard to visualize what is going on but hang on for a bit more. So far we have added a Title, an Image, and a URL link that people can click on that will take them to Google. Now let’s add a nice separator to keep everything organized. The do this, add the tag “<hr/>” on a new line below your URL.

Let us also finish up with the description variable. After adding the separator, close up everything with adding “</p>” then adding two closing brackets “]]”

<hr/>
</p> ]]
Forgive the blatant cursor in front of the first closing bracket

Let us see how our work looks so far inside OBS Studio. First, let us call our description variable so that we essentially tell OBS to draw or render what we described inside the description variable.

Let us create a new function called “script_description” and have it return the variable description.

function script_description()
return description
end

Then let us go ahead and import our script into OBS. First make sure to save your script or OBS won’t be able to see what you have done. I have my script located on my Desktop but you might have it saved somewhere else. Open up OBS Studio and go to Tools > Scripts.

A new OBS window will appear. If you have not added a script before, this window should be blank. On the lower left corner should be a Plus symbol “+” where you can import your scripts. Find and import your script here. You should now have a window that looks like something below.

How to Add a Clickable Button

So far you just made your very own interface! But we have to yet to add a button to make this an interactive interface.

To close up this tutorial let’s add a button to our script.

For the sake of length for this tutorial I will not show how to make the button actually do something but only how to create the actual button.

In order to add a button we have to create a “properties” object to add it to. If you see in your interface, you will note that there is a text that says “No properties available.” This is where our button will go.

Although we can create the properties object, we will also have to call the function “script_properties()” inside our script that will define our user properties that are attached to our script. Inside of the OBS Scripting Documentation (you can find it here: https://obsproject.com/docs/scripting.html#script-function-exports) they define script properties as the following:

Called to define user properties associated with the script. These properties are used to define how to show settings properties to a user.

Returns

obs_properties_t object created via obs_properties_create().

So to satisfy this requirement let us create our function “script_properties”, and then create a local variable called “properties” and assign it a properties object by calling “obs.obs_properties_create()”.

function script_properties()
local properties = obs.obs_properties_create()

Essentially what we did is create a new properties object that will store all our user data. Do not worry for now if that did not make sense, but just note that it will be through our properties object that our button will appear.

To add a button we will have to call the method “obs_properties_add_button” from obs and assign it into a variable. When we call this method it will require 4 inputs:

  1. A properties object (we created that already as a local variable “properties”)
  2. A name, which is basically a string
  3. Text, which is the actual text a user will see on the interface
  4. A Callback Function
Provided from the OBS Scripting documentation

Let us first create our callback function. The callback function will basically be what the button will do when we click it. We won’t have the button do anything so we will just tell the button to return nothing. Add your button function right after your script_description function.

function button()
return nil
end

Now let us create the button within our script_properties function by calling “obs.obs_properties_add_button.” After that let us close up our script properties function by returning our properties object and ending our function.

  local button = obs.obs_properties_add_button(properties, "new_button", "My New Button", button)  return properties
end

Save your script again and now let us go back to OBS Studio. There is a refresh button located near the “+” plus symbol on the lower left of the Scripts window. Press it to refresh your scripts. You should now have a new button appear on your interface.

Conclusion and More Resources

And there you have it. If you followed through with this tutorial were you able to successfully create your own basic custom interface for OBS Studio. Definitely feel free to reach out and share what you made! Here is the full code written out here in case you want to easily copy and paste:

obs = obslualocal image1 = "put base64 data here"local description = [[<center><h2>Dope Interface</h2></center>
<p>
<center><img width=60 height=60 src=']] .. image1 .. [['/></center>
<p>
<center>Click here to open Google: <a href="https://www.google.com/">Search on Google</a></center>
<hr/>
</p> ]]
function script_description()

return description
endfunction button()return nilendfunction script_properties()
local properties = obs.obs_properties_create()
local button = obs.obs_properties_add_button(properties, "new_button", "My New Button", button)
return properties
end

I definitely will be making another tutorial on how to make your button do things like create new scenes into your OBS session, and how to have images and videos be imported with a click of a button, so stay tuned!

For more resources on scripting for OBS, here are some great links I used to help me get started:

Official OBS Scripting Documentation:

https://obsproject.com/docs/index.html

Getting Starting with OBS Scripting Wiki(there’s also a Discord server available that you can join from here):

https://obsproject.com/wiki/Getting-Started-With-OBS-Scripting

The Python Scripting CheatSheet for OBS Studio by UpgradeQ:

https://github.com/upgradeQ/OBS-Studio-Python-Scripting-Cheatsheet-obspython-Examples-of-API

Tips and Tricks for Lua Scripts OBS Wiki Forum:

https://obsproject.com/forum/threads/tips-and-tricks-for-lua-scripts.132256/

If you want to dive more into developing your interface more with cool functions for your buttons, check out my second tutorial here:

https://morebackgroundsplease.medium.com/use-a-lua-script-to-import-your-twitch-streaming-overlay-designs-into-obs-studio-b8f688aeb9e8

The current pool of shared resources for scripting inside OBS Studio is fairly new, so there is not much information going around if you try to Google for help, but I encourage anyone who is interested in dabbling with Lua or Python for OBS Studio to share their knowledge as this continues to grow in functionality.

Thanks for sticking by!