diff --git a/src/LibVLCSharp/Shared/LibVLC.cs b/src/LibVLCSharp/Shared/LibVLC.cs
index 3bfd7a66..c7a7658a 100644
--- a/src/LibVLCSharp/Shared/LibVLC.cs
+++ b/src/LibVLCSharp/Shared/LibVLC.cs
@@ -189,6 +189,38 @@ internal struct Native
#endif
}
+ ///
+ /// Create and initialize a libvlc instance using a object.
+ /// This constructor allows for strongly-typed, flexible configuration of libvlc command-line parameters,
+ /// including platform-specific defaults, logging verbosity, resamplers, caching, and rendering settings.
+ /// LibVLC may create threads. Therefore, any thread-unsafe process
+ /// initialization must be performed before calling libvlc_new(). In particular:
+ /// - setlocale() and textdomain(),
+ /// - setenv(), unsetenv(), and putenv(),
+ /// - On Microsoft Windows, SetErrorMode().
+ /// On POSIX systems, certain signals must be handled properly (e.g., SIGCHLD must not be ignored).
+ /// This will throw a if the native libvlc libraries cannot be found or loaded.
+ /// It may also throw a if the LibVLC and LibVLCSharp major versions do not match.
+ /// See https://code.videolan.org/videolan/LibVLCSharp/-/blob/master/docs/versioning.md for more info about the versioning strategy.
+ ///
+ ///
+ /// var options = new LibVLCOptionsBuilder()
+ /// .EnableDebugLogs()
+ /// .SetAudioResampler("soxr")
+ /// .Build();
+ ///
+ /// using var libvlc = new LibVLC(options);
+ ///
+ ///
+ ///
+ /// An instance of containing libvlc configuration parameters.
+
+ public LibVLC(LibVLCOptions options)
+ : base(() => MarshalUtils.CreateWithOptions(options.Options, Native.LibVLCNew), Native.LibVLCRelease)
+ {
+ _gcHandle = GCHandle.Alloc(this);
+ }
+
///
/// Create and initialize a libvlc instance.
/// This functions accept a list of "command line" arguments similar to the
@@ -239,10 +271,8 @@ internal struct Native
/// list of arguments, in the form "--option=value"
/// the libvlc instance or NULL in case of error
public LibVLC(params string[] options)
- : base(() => MarshalUtils.CreateWithOptions(PatchOptions(options), Native.LibVLCNew), Native.LibVLCRelease)
- {
- _gcHandle = GCHandle.Alloc(this);
- }
+ : this(new LibVLCOptionsBuilder().AddOptions(options).Build()) { }
+
///
/// Create and initialize a libvlc instance.
@@ -286,31 +316,11 @@ public LibVLC(params string[] options)
/// enable verbose debug logs
/// list of arguments (should be NULL)
public LibVLC(bool enableDebugLogs, params string[] options)
- : base(() => MarshalUtils.CreateWithOptions(PatchOptions(options, enableDebugLogs), Native.LibVLCNew), Native.LibVLCRelease)
- {
- _gcHandle = GCHandle.Alloc(this);
- }
-
- ///
- /// Make dirty hacks to include necessary defaults on some platforms.
- ///
- /// The options given by the user
- /// enable debug logs
- /// The patched options
- static string[] PatchOptions(string[] options, bool enableDebugLogs = false)
- {
- if(enableDebugLogs)
- {
- options = options.Concat(new[] { "--verbose=2" }).ToArray();
- }
-#if UWP
- return options.Concat(new[] {"--aout=winstore", "--audio-resampler=speex_resampler"}).ToArray();
-#elif ANDROID
- return options.Concat(new[] {"--audio-resampler=soxr"}).ToArray();
-#else
- return options;
-#endif
- }
+ : this(new LibVLCOptionsBuilder()
+ .AddOptions(options)
+ .EnableDebugLogs()
+ .Build())
+ { }
///
/// Dispose of this libvlc instance
diff --git a/src/LibVLCSharp/Shared/LibVLCOptions.cs b/src/LibVLCSharp/Shared/LibVLCOptions.cs
new file mode 100644
index 00000000..1f95ebd4
--- /dev/null
+++ b/src/LibVLCSharp/Shared/LibVLCOptions.cs
@@ -0,0 +1,219 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace LibVLCSharp.Shared
+{
+ ///
+ /// Fluent builder for constructing LibVLC options.
+ /// Mirrors many common libvlc command line parameters.
+ /// See https://wiki.videolan.org/VLC_command-line_help for more details about available parameters.
+ /// OPTIONS ARE PROVIDED AS-IS, WITHOUT ANY GUARANTEE OF FORWARD/BACKWARD COMPATIBILITY.
+ ///
+ public class LibVLCOptionsBuilder
+ {
+ private readonly List _options = new();
+ private bool _includeDebugLogs = false;
+
+#if UWP || ANDROID
+ private bool _audioResamplerOverridden = false;
+#endif
+
+ ///
+ /// Enables verbose debug logging by adding "--verbose=2".
+ ///
+ public LibVLCOptionsBuilder EnableDebugLogs()
+ {
+ _includeDebugLogs = true;
+ return this;
+ }
+
+ ///
+ /// Sets the verbosity level of the log output.
+ ///
+ /// Verbosity level (e.g. 0=errors only, 2=debug).
+ public LibVLCOptionsBuilder SetVerbosity(int level)
+ {
+ _options.Add($"--verbose={level}");
+ return this;
+ }
+
+ ///
+ /// Sets the audio resampler module.
+ ///
+ /// The name of the resampler (e.g. speex_resampler, soxr).
+ public LibVLCOptionsBuilder SetAudioResampler(string resampler)
+ {
+ _options.Add($"--audio-resampler={resampler}");
+#if UWP || ANDROID
+ _audioResamplerOverridden = true;
+#endif
+ return this;
+ }
+
+#if UWP || ANDROID
+ ///
+ /// Disables the default resampler for the current platform.
+ ///
+ public LibVLCOptionsBuilder DisableDefaultResampler()
+ {
+ _audioResamplerOverridden = true;
+ return this;
+ }
+#endif
+
+ ///
+ /// Sets the audio output module (e.g. "--aout=directsound").
+ ///
+ /// The audio output module name.
+ public LibVLCOptionsBuilder SetAudioOutput(string output)
+ {
+ _options.Add($"--aout={output}");
+ return this;
+ }
+
+ ///
+ /// Disables video output.
+ ///
+ public LibVLCOptionsBuilder DisableVideo()
+ {
+ _options.Add("--no-video");
+ return this;
+ }
+
+ ///
+ /// Disables audio output.
+ ///
+ public LibVLCOptionsBuilder DisableAudio()
+ {
+ _options.Add("--no-audio");
+ return this;
+ }
+
+ ///
+ /// Sets the network caching value in milliseconds.
+ ///
+ /// Caching delay in ms (e.g. 300).
+ public LibVLCOptionsBuilder SetNetworkCaching(int milliseconds)
+ {
+ _options.Add($"--network-caching={milliseconds}");
+ return this;
+ }
+
+ ///
+ /// Sets the file caching value in milliseconds.
+ ///
+ /// Caching delay in ms (e.g. 300).
+ public LibVLCOptionsBuilder SetFileCaching(int milliseconds)
+ {
+ _options.Add($"--file-caching={milliseconds}");
+ return this;
+ }
+
+ ///
+ /// Enables hardware-accelerated decoding using the specified method.
+ ///
+ /// Decoding method (e.g. dxva2, vaapi, d3d11va).
+ public LibVLCOptionsBuilder EnableHardwareDecoding(string method)
+ {
+ _options.Add($"--avcodec-hw={method}");
+ return this;
+ }
+
+ ///
+ /// Enables dropping of late video frames.
+ ///
+ public LibVLCOptionsBuilder DropLateFrames()
+ {
+ _options.Add("--drop-late-frames");
+ return this;
+ }
+
+ ///
+ /// Enables frame skipping.
+ ///
+ public LibVLCOptionsBuilder SkipFrames()
+ {
+ _options.Add("--skip-frames");
+ return this;
+ }
+
+ ///
+ /// Enables or disables use of Xlib.
+ ///
+ /// True to enable Xlib, false to disable.
+ public LibVLCOptionsBuilder UseXlib(bool enabled)
+ {
+ _options.Add(enabled ? "--xlib" : "--no-xlib");
+ return this;
+ }
+
+ ///
+ /// Adds a custom libvlc option.
+ ///
+ /// The command-line option to add.
+ public LibVLCOptionsBuilder AddOption(string option)
+ {
+ _options.Add(option);
+ return this;
+ }
+
+ ///
+ /// Adds multiple custom libvlc options.
+ ///
+ /// The options to add.
+ public LibVLCOptionsBuilder AddOptions(IEnumerable options)
+ {
+ _options.AddRange(options);
+ return this;
+ }
+
+
+ ///
+ /// Builds the final LibVLCOptions object including any platform-specific defaults.
+ ///
+ public LibVLCOptions Build()
+ {
+ var finalOptions = _options;
+
+ if (_includeDebugLogs)
+ finalOptions.Add("--verbose=2");
+
+#if UWP
+ finalOptions.Add("--aout=winstore");
+ if (!_audioResamplerOverridden)
+ finalOptions.Add("--audio-resampler=speex_resampler");
+#elif ANDROID
+ if (!_audioResamplerOverridden)
+ finalOptions.Add("--audio-resampler=soxr");
+#endif
+
+ return new LibVLCOptions(finalOptions);
+ }
+ }
+
+ ///
+ /// Represents the finalized LibVLC options as an array of command-line arguments.
+ ///
+ public class LibVLCOptions
+ {
+ ///
+ /// Gets the collection of command-line arguments.
+ ///
+ public string[] Options { get; }
+
+ ///
+ /// Initializes a new instance of LibVLCOptions with the specified options.
+ ///
+ /// The options to include.
+ public LibVLCOptions(IEnumerable? options)
+ {
+ Options = options?.ToArray() ?? new string[0];
+ }
+
+ ///
+ /// Gets an empty LibVLCOptions instance.
+ ///
+ public static LibVLCOptions Empty => new LibVLCOptions(new string[0]);
+ }
+}