Skip to content

Commit

Permalink
Optionally log library setup info (#25)
Browse files Browse the repository at this point in the history
* Optionally log library setup info

* This will put SeeShark at version 3.1.0
  • Loading branch information
Speykious authored Feb 23, 2022
1 parent 94c0791 commit ce33012
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 38 deletions.
100 changes: 63 additions & 37 deletions SeeShark/FFmpeg/FFmpegManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ public static class FFmpegManager
/// </summary>
public static bool IsFFmpegSetup { get; private set; } = false;

/// <summary>
/// Set that to true if you're struggling to setup FFmpeg properly.
/// </summary>
public static bool LogLibrarySearch { get; set; } = false;

private static void llsLog(string message)
{
if (LogLibrarySearch)
{
Console.ForegroundColor = ConsoleColor.DarkCyan;
Console.Error.WriteLine(message);
Console.ResetColor();
}
}

/// <summary>
/// Informative version string. It is usually the actual release version number or a git commit description. It has no fixed format and can change any time. It should never be parsed by code.
/// <br/>
Expand Down Expand Up @@ -64,6 +79,12 @@ public static void SetupFFmpeg(FFmpegLogLevel logLevel, ConsoleColor logColor, p
if (IsFFmpegSetup)
return;

llsLog("Setting up FFmpeg\nRequired libraries:" +
$"\n - avcodec (v{ffmpeg.LIBAVCODEC_VERSION_MAJOR})" +
$"\n - avdevice (v{ffmpeg.LIBAVDEVICE_VERSION_MAJOR})" +
$"\n - avformat (v{ffmpeg.LIBAVFORMAT_VERSION_MAJOR})" +
$"\n - swscale (v{ffmpeg.LIBSWSCALE_VERSION_MAJOR})");

var requiredLibs = LF.AVCodec | LF.AVDevice | LF.AVFormat | LF.SWScale;

if (paths.Length == 0)
Expand Down Expand Up @@ -104,6 +125,40 @@ internal static unsafe void SetupFFmpegLogging(FFmpegLogLevel logLevel, ConsoleC
ffmpeg.av_log_set_callback(logCallback);
}

/// <summary>
/// Tries to set the RootPath to the first path in which it can find all the native libraries.
/// Ideally, you would want to only call this function once, before doing anything with FFmpeg.
/// </summary>
/// <remarks>
/// This function will not load the native libraries but merely check if they exist.
/// </remarks>
/// <param name="paths">Every path to try out. It will set the RootPath to the first one that works.</param>
public static void TrySetRootPath(params string[] paths) => TrySetRootPath(paths);

/// <summary>
/// Tries to set the RootPath to the first path in which it can find all the required native libraries.
/// Ideally, you would want to only call this function once, before doing anything with FFmpeg.
/// </summary>
/// <remarks>
/// This function will not load the native libraries but merely check if they exist.
/// </remarks>
/// <param name="requiredLibraries">The required libraries. If you don't need all of them, you can specify them here.</param>
/// <param name="paths">Every path to try out. It will set the RootPath to the first one that works.</param>
public static void TrySetRootPath(LF requiredLibraries, params string[] paths)
{
try
{
ffmpeg.RootPath = paths.First((path) => CanLoadLibraries(requiredLibraries, path));
}
catch (InvalidOperationException)
{
string pathList = "\n - " + string.Join("\n - ", paths);
throw new InvalidOperationException(
$"Couldn't find native libraries in the following paths:{pathList}" +
"\nMake sure you installed the correct versions of the native libraries.");
}
}

/// <summary>
/// Tries to load the native libraries from the set root path. <br/>
/// You can specify which libraries need to be loaded with LibraryFlags.
Expand All @@ -112,9 +167,10 @@ internal static unsafe void SetupFFmpegLogging(FFmpegLogLevel logLevel, ConsoleC
/// If you try to do that later, it might unload all of your already loaded libraries and fail to provide them again.
/// </summary>
/// <returns>Whether it succeeded in loading all the requested libraries.</returns>
public static bool CanLoadLibraries(LibraryFlags libraries = LibraryFlags.All, string path = "")
public static bool CanLoadLibraries(LF libraries = LF.All, string path = "")
{
var validated = new List<string>();
llsLog($"Searching for libraries in {path}");
return libraries.ToStrings().All((lib) => canLoadLibrary(lib, path, validated));
}

Expand All @@ -128,46 +184,14 @@ private static bool canLoadLibrary(string lib, string path, List<string> validat
if (validated.Contains(lib))
return true;

var version = ffmpeg.LibraryVersionMap[lib];
int version = ffmpeg.LibraryVersionMap[lib];
if (!canLoadNativeLibrary(path, lib, version))
return false;

validated.Add(lib);
return true;
}

/// <summary>
/// Tries to set the RootPath to the first path in which it can find all the native libraries.
/// Ideally, you would want to only call this function once, before doing anything with FFmpeg.
/// </summary>
/// <remarks>
/// This function will not load the native libraries but merely check if they exist.
/// </remarks>
/// <param name="paths">Every path to try out. It will set the RootPath to the first one that works.</param>
public static void TrySetRootPath(params string[] paths) => TrySetRootPath(paths);

/// <summary>
/// Tries to set the RootPath to the first path in which it can find all the required native libraries.
/// Ideally, you would want to only call this function once, before doing anything with FFmpeg.
/// </summary>
/// <remarks>
/// This function will not load the native libraries but merely check if they exist.
/// </remarks>
/// <param name="requiredLibraries">The required libraries. If you don't need all of them, you can specify them here.</param>
/// <param name="paths">Every path to try out. It will set the RootPath to the first one that works.</param>
public static void TrySetRootPath(LibraryFlags requiredLibraries, params string[] paths)
{
try
{
ffmpeg.RootPath = paths.First((path) => CanLoadLibraries(requiredLibraries, path));
}
catch (InvalidOperationException)
{
var pathList = paths.Aggregate((a, b) => $"'{a}', '{b}'");
throw new InvalidOperationException($"Couldn't find native libraries in the following paths: {pathList}");
}
}

/// <summary>
/// Checks if it can load a native library using platform naming conventions.
/// </summary>
Expand All @@ -177,9 +201,11 @@ public static void TrySetRootPath(LibraryFlags requiredLibraries, params string[
/// <returns>Whether it found the native library in the path.</returns>
private static bool canLoadNativeLibrary(string path, string libraryName, int version)
{
var nativeLibraryName = LibraryLoader.GetNativeLibraryName(libraryName, version);
var fullName = Path.Combine(path, nativeLibraryName);
return File.Exists(fullName);
string nativeLibraryName = LibraryLoader.GetNativeLibraryName(libraryName, version);
string fullName = Path.Combine(path, nativeLibraryName);
bool exists = File.Exists(fullName);
llsLog($" {(exists ? "Found" : "Couldn't find")} library {nativeLibraryName}");
return exists;
}
}
}
2 changes: 1 addition & 1 deletion SeeShark/SeeShark.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<PropertyGroup Label="Nuget">
<PackageId>SeeShark</PackageId>
<Version>3.0.0</Version>
<Version>3.1.0</Version>
<Authors>The Vignette Authors</Authors>
<PackageTags>FFmpeg;Camera;Webcam;Stream;</PackageTags>
<Title>SeeShark</Title>
Expand Down

0 comments on commit ce33012

Please sign in to comment.