Skip to content

Instantly share code, notes, and snippets.

@AldeRoberge
Created February 7, 2025 16:06
Show Gist options
  • Save AldeRoberge/2e314909a5cd45cd05593c73925a08e4 to your computer and use it in GitHub Desktop.
Save AldeRoberge/2e314909a5cd45cd05593c73925a08e4 to your computer and use it in GitHub Desktop.
Set the OBS output file name
using FluentResults;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OBSStudioClient;
using OBSStudioClient.Enums;
using Polly;
namespace ADG.Recording.OBS
{
public class ObsServiceOptions
{
public string Ip { get; set; } = "localhost";
public int Port { get; set; } = 4455;
public string Password { get; set; } = "sfrUy5ZHxUIXAOFx";
}
public interface IObsService
{
Task<Result> UpdateOutputFileNameFormat(string fileNameFormatting);
}
public class ObsService(IOptions<ObsServiceOptions> options, ILogger<ObsService> logger) : IObsService
{
private readonly ObsServiceOptions _options = options.Value;
public async Task<Result> UpdateOutputFileNameFormat(string fileNameFormatting)
{
if (string.IsNullOrWhiteSpace(fileNameFormatting))
return Result.Fail("File name formatting must not be empty.");
using var client = new ObsClient();
logger.LogInformation("Connecting to OBS at {Ip}:{Port}", _options.Ip, _options.Port);
bool connectionResult =
await client.ConnectAsync(
password: _options.Password,
hostname: _options.Ip,
port: _options.Port
).ConfigureAwait(false);
if (!connectionResult)
{
string errorMsg = $"Connection failed to OBS at {_options.Ip}:{_options.Port}. \n" +
"Is the WebSocket started? \n" +
"Tools > WebSocket Server > Enable";
logger.LogError(errorMsg);
return Result.Fail(errorMsg);
}
logger.LogInformation("Connected to OBS. Waiting for Authentication to complete.");
// Await for authentication (client.ConnectionState == ConnectionState.Authenticated), max timeout 10 seconds
await Policy.TimeoutAsync(TimeSpan.FromSeconds(10))
.WrapAsync(Policy.HandleResult<bool>(r => !r)
.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(1)))
.ExecuteAsync(async () =>
{
await Task.Delay(1000);
return client.ConnectionState == ConnectionState.Connected;
});
try
{
var currentFilenameFormatting = await client
.GetProfileParameter("Output", "FilenameFormatting")
.ConfigureAwait(false);
logger.LogInformation("Current output file name formatting: {Formatting}", currentFilenameFormatting.ParameterValue);
await client
.SetProfileParameter("Output", "FilenameFormatting", fileNameFormatting)
.ConfigureAwait(false);
logger.LogInformation("Updated output file name formatting to: {FolderName}", fileNameFormatting);
return Result.Ok();
}
catch (Exception ex)
{
logger.LogError(ex, "Failed to update OBS folder name.");
return Result.Fail(new ExceptionalError("OBS folder name update failed.", ex));
}
}
}
}
@AldeRoberge
Copy link
Author

You can use this Program.cs to call the above code

using ADG.Recording.OBS;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Serilog;

Log.Logger = new LoggerConfiguration()
    .Enrich.FromLogContext()
    .WriteTo.Console()
    .CreateLogger();

var serviceProvider = new ServiceCollection()
    .AddLogging(builder => builder.AddSerilog(dispose: true))
    .AddSingleton<ILoggerFactory, LoggerFactory>()
    .Configure<ObsServiceOptions>(options =>
    {
        options.Ip = "localhost";
        options.Port = 4455;
        options.Password = "sfrUy5ZHxUIXAOFx";
    })
    .AddSingleton<IObsService, ObsService>()
    .BuildServiceProvider();

var logger = serviceProvider.GetRequiredService<ILogger<Program>>();
var obsService = serviceProvider.GetRequiredService<IObsService>();

var result = await obsService.UpdateOutputFileNameFormat("MyFolderName");

if (result.IsSuccess)
{
    logger.LogInformation("Output file name format updated successfully.");
}
else
{
    logger.LogError("Failed to update output file name format: {Error}", result.Errors[0].Message);
}

Log.CloseAndFlush();

@AldeRoberge
Copy link
Author

Uses OBS web sockets : https://github.com/obsproject/obs-websocket/blob/master/docs/generated/protocol.md

Make sure you enable Web Sockets

image
image

Thanks to @tinodo for his C# library obs client. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment