Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Customizable FFmpeg logs #45

Closed
wants to merge 3 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Make FFmpeg logs customizable with a delegate
Speykious committed Mar 3, 2023

Verified

This commit was signed with the committer’s verified signature.
gabmontes Gabriel Montes
commit 0e9732a6b49e36ef4cce3ae7d9b360e80ece136c
51 changes: 40 additions & 11 deletions SeeShark/FFmpeg/FFmpegManager.cs
Original file line number Diff line number Diff line change
@@ -63,18 +63,38 @@ public static string FFmpegRootPath
/// <summary>
/// Setup FFmpeg: root path and logging.
/// <br/>
/// It will only setup FFmpeg once. Any non-first call will do nothing.
/// It will only setup FFmpeg once. Any non-first call to this method will do nothing.
/// <br/>
/// SeeShark is designed such that this method is called whenever it is
/// necessary to have FFmpeg ready.
/// <br/>
/// However, if you want to, you can still call it at the beginning of
/// your program to customize your FFmpeg setup.
/// </summary>
/// <param name="rootPath">Root path for loading FFmpeg libraries.</param>
/// <param name="logLevel">Log level for FFmpeg.</param>
/// <param name="logColor">Color of the FFmpeg logs.</param>
/// <param name="paths">List of valid paths for loading FFmpeg libraries.</param>
public static void SetupFFmpeg(FFmpegLogLevel logLevel, ConsoleColor logColor, params string[] paths)
{
SetupFFmpeg(logLevel, logColor, null, paths);
}

/// <summary>
/// Setup FFmpeg: root path and logging, with custom log delegate.
/// <br/>
/// It will only setup FFmpeg once. Any non-first call to this method will do nothing.
/// <br/>
/// SeeShark is designed such that this method is called whenever it is
/// necessary to have FFmpeg ready.
/// <br/>
/// However, if you want to, you can still call it at the beginning of
/// your program to customize your FFmpeg setup.
/// </summary>
/// <param name="logLevel">Log level for FFmpeg.</param>
/// <param name="logColor">Color of the FFmpeg logs.</param>
/// <param name="ffmpegLog">Custom delegate to redirect FFmpeg logs.</param>
/// <param name="paths">List of valid paths for loading FFmpeg libraries.</param>
public static void SetupFFmpeg(FFmpegLogLevel logLevel, ConsoleColor logColor, FFmpegLog? ffmpegLog, params string[] paths)
{
if (IsFFmpegSetup)
return;
@@ -91,35 +111,44 @@ public static void SetupFFmpeg(FFmpegLogLevel logLevel, ConsoleColor logColor, p
TrySetRootPath(requiredLibs, AppDomain.CurrentDomain.BaseDirectory);
else
TrySetRootPath(requiredLibs, paths);
SetupFFmpegLogging(logLevel, logColor);
SetupFFmpegLogging(logLevel, logColor, ffmpegLog);
ffmpeg.avdevice_register_all();

IsFFmpegSetup = true;
}

public static void SetupFFmpeg(params string[] paths) => SetupFFmpeg(FFmpegLogLevel.Panic, ConsoleColor.Yellow, paths);

internal static unsafe void SetupFFmpegLogging(FFmpegLogLevel logLevel, ConsoleColor logColor)
public delegate void FFmpegLog(FFmpegLogLevel logLevel, ConsoleColor logColor, string? message);

private static void defaultFFmpegLog(FFmpegLogLevel logLevel, ConsoleColor logColor, string? message)
{
Console.ForegroundColor = logColor;
Console.Write(message);
Console.ResetColor();
}

internal static unsafe void SetupFFmpegLogging(FFmpegLogLevel logLevel, ConsoleColor logColor, FFmpegLog? ffmpegLog = null)
{
ffmpeg.av_log_set_level((int)logLevel);

ffmpegLog ??= new FFmpegLog(defaultFFmpegLog);

// Do not convert to local function!
logCallback = (p0, level, format, vl) =>
{
if (level > ffmpeg.av_log_get_level())
return;

var lineSize = 1024;
var lineBuffer = stackalloc byte[lineSize];
var printPrefix = 1;
int lineSize = 1024;
byte* lineBuffer = stackalloc byte[lineSize];
int printPrefix = 1;

ffmpeg.av_log_format_line(p0, level, format, vl, lineBuffer, lineSize, &printPrefix);
var line = Marshal.PtrToStringAnsi((IntPtr)lineBuffer);
string? message = Marshal.PtrToStringAnsi((IntPtr)lineBuffer);

// TODO: maybe make it possible to log this in any stream?
Console.ForegroundColor = logColor;
Console.Write(line);
Console.ResetColor();
ffmpegLog(logLevel, logColor, message);
};

ffmpeg.av_log_set_callback(logCallback);