SHA256
133 lines
6.3 KiB
C#
133 lines
6.3 KiB
C#
using System;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.IO;
|
|
|
|
namespace ADOFAIRenderer.API;
|
|
|
|
/// <summary>
|
|
/// Represents the result and metadata of a completed or canceled render session.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Passed to the completion callback registered with <see cref="RenderSession.OnComplete"/>. Immutable.
|
|
/// </remarks>
|
|
[SuppressMessage("ReSharper", "UnusedType.Global")]
|
|
[SuppressMessage("ReSharper", "MemberCanBePrivate.Global")]
|
|
public class RenderResult
|
|
{
|
|
/// <summary>
|
|
/// Indicates whether the rendering session completed successfully.
|
|
/// </summary>
|
|
public bool Success { get; }
|
|
|
|
/// <summary>
|
|
/// The output path of the rendered video file: the path given to <see cref="RenderSession.WithOutputPath"/> as passed
|
|
/// (relative if it was relative), or the path of the time-stamped file in the output directory chosen in the mod
|
|
/// settings (by default <game root>/Render).
|
|
/// Empty string if rendering failed or was cancelled (the unfinished file is deleted).
|
|
/// </summary>
|
|
public string OutputPath { get; }
|
|
|
|
/// <summary>
|
|
/// Total number of video frames sent to the encoder.
|
|
/// </summary>
|
|
public long TotalFrames { get; }
|
|
|
|
/// <summary>
|
|
/// The calculated video duration in seconds: <see cref="TotalFrames"/> divided by the effective video frame rate
|
|
/// (min of the configured VideoFPS and RenderFPS); 0 when the frame rate is not positive.
|
|
/// </summary>
|
|
public double VideoDuration { get; }
|
|
|
|
/// <summary>
|
|
/// Total wall-clock time spent rendering, from the end of the countdown (start of capture) to the end of the render.
|
|
/// </summary>
|
|
public TimeSpan RenderDuration { get; }
|
|
|
|
/// <summary>
|
|
/// File size of the output video in bytes (0 if failed or file does not exist).
|
|
/// </summary>
|
|
public long FileSizeBytes { get; }
|
|
|
|
/// <summary>
|
|
/// Error message or reason if rendering failed or was canceled; <c>null</c> on success.
|
|
/// A cancelled render has "Rendering was cancelled by user."; a failed render has "Rendering failed: " followed by
|
|
/// the reason. Use <see cref="Success"/> to test the outcome; the texts are meant for display.
|
|
/// </summary>
|
|
public string? ErrorMessage { get; }
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance of the <see cref="RenderResult"/> class.
|
|
/// </summary>
|
|
/// <param name="success">Whether the render session completed successfully.</param>
|
|
/// <param name="outputPath">The absolute output path of the rendered video file.</param>
|
|
/// <param name="totalFrames">Total number of video frames sent to the encoder.</param>
|
|
/// <param name="videoDuration">Calculated video duration in seconds.</param>
|
|
/// <param name="renderDuration">Total wall-clock time spent rendering.</param>
|
|
/// <param name="fileSizeBytes">File size of the output video in bytes.</param>
|
|
/// <param name="errorMessage">Error message or reason if failed or canceled; otherwise, <c>null</c>.</param>
|
|
public RenderResult(
|
|
bool success,
|
|
string outputPath,
|
|
long totalFrames,
|
|
double videoDuration,
|
|
TimeSpan renderDuration,
|
|
long fileSizeBytes = 0,
|
|
string? errorMessage = null)
|
|
{
|
|
Success = success;
|
|
OutputPath = outputPath;
|
|
TotalFrames = totalFrames;
|
|
VideoDuration = videoDuration;
|
|
RenderDuration = renderDuration;
|
|
FileSizeBytes = fileSizeBytes;
|
|
ErrorMessage = errorMessage;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a successful <see cref="RenderResult"/> instance from the specified render metrics.
|
|
/// </summary>
|
|
/// <param name="outputPath">The path to the rendered video file.</param>
|
|
/// <param name="totalFrames">Total number of video frames sent to the encoder.</param>
|
|
/// <param name="fps">The effective frames per second used to compute video duration.</param>
|
|
/// <param name="renderDuration">Total wall-clock time spent rendering.</param>
|
|
/// <returns>A new <see cref="RenderResult"/> representing a successful render session.</returns>
|
|
/// <remarks>The file size is read from disk; it is 0 when the file does not exist or cannot be read.</remarks>
|
|
internal static RenderResult CreateSuccess(string outputPath, long totalFrames, double fps, TimeSpan renderDuration)
|
|
{
|
|
var fileSizeBytes = 0L;
|
|
if (!string.IsNullOrEmpty(outputPath) && File.Exists(outputPath))
|
|
{
|
|
try { fileSizeBytes = new FileInfo(outputPath).Length; }
|
|
catch { /* ignored */ }
|
|
}
|
|
|
|
var videoDuration = fps > 0 ? totalFrames / fps : 0.0;
|
|
return new RenderResult(true, outputPath, totalFrames, videoDuration, renderDuration, fileSizeBytes);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a failed or cancelled <see cref="RenderResult"/> instance.
|
|
/// </summary>
|
|
/// <param name="errorMessage">Error message or reason for failure/cancellation.</param>
|
|
/// <param name="totalFrames">Total number of video frames sent to the encoder prior to termination.</param>
|
|
/// <param name="fps">The effective frames per second used to compute video duration.</param>
|
|
/// <param name="renderDuration">Total wall-clock time spent rendering prior to termination.</param>
|
|
/// <returns>A new <see cref="RenderResult"/> representing a failed or canceled render session.</returns>
|
|
/// <remarks>OutputPath is empty and FileSizeBytes is 0. A null message is replaced by a generic one.</remarks>
|
|
internal static RenderResult CreateFailure(string? errorMessage, long totalFrames, double fps, TimeSpan renderDuration)
|
|
{
|
|
var videoDuration = fps > 0 ? totalFrames / fps : 0.0;
|
|
return new RenderResult(false, string.Empty, totalFrames, videoDuration, renderDuration, 0, errorMessage ?? "Rendering failed or was cancelled.");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a string summarizing the render result metrics or failure reason.
|
|
/// </summary>
|
|
/// <returns>A string representation of the <see cref="RenderResult"/>.</returns>
|
|
public override string ToString()
|
|
{
|
|
return Success
|
|
? $"[RenderResult: Success, Output={OutputPath}, Frames={TotalFrames}, VideoDuration={VideoDuration:F2}s, Time={RenderDuration.TotalSeconds:F1}s, Size={FileSizeBytes / 1024.0 / 1024.0:F2}MB]"
|
|
: $"[RenderResult: Failed/Cancelled, Error={ErrorMessage ?? "Unknown"}]";
|
|
}
|
|
} |