TASK 21 slice 2a: native-FPS probe seam (ffprobe parse + derive sibling)
- FfmpegFrameRateParser (pure): prefers avg_frame_rate= then r_frame_rate=, rational N/N/M, unknown/0 -> null. - IFrameRateProbe + FfmpegFrameRateProbe: derives sibling ffprobe.exe from the located ffmpeg dir, reuses the IDecodeProcess seam for the ffprobe subprocess text; null if ffprobe absent. - FfmpegLocator now also extracts ffprobe.exe (ProbeFileName) from the pinned archive, conditional so old caches without it degrade to no pacing. - Tests: 6 pure parser units + 1 probe integration via fake locator/process; FfmpegLocatorTests still green. 15/15, 0 warnings. Pacing (probe->delay) is slice 2b. Derivative reference: standard ffprobe avg_frame_rate probing used across OBS/media tooling.
This commit is contained in:
@@ -20,6 +20,11 @@ public sealed class FfmpegLocator : IFfmpegLocator
|
||||
{
|
||||
public const string FileName = "ffmpeg.exe";
|
||||
|
||||
/// <summary>Sibling probe binary — extracted alongside ffmpeg so the media
|
||||
/// frame-rate probe (<see cref="ytLive.Services.FfmpegFrameRateProbe"/>) can
|
||||
/// derive its path from the located ffmpeg directory.</summary>
|
||||
public const string ProbeFileName = "ffprobe.exe";
|
||||
|
||||
/// <summary>Pinned BtbN LGPL-shared win64 build (immutable autobuild tag; see TASKS.md).</summary>
|
||||
public const string PinnedUrl =
|
||||
"https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2026-08-09-13-03/ffmpeg-master-latest-win64-lgpl-shared.zip";
|
||||
@@ -85,6 +90,10 @@ public sealed class FfmpegLocator : IFfmpegLocator
|
||||
e => e.FullName.EndsWith("/" + FileName, StringComparison.OrdinalIgnoreCase))
|
||||
?? throw new InvalidDataException($"The pinned FFmpeg archive does not contain {FileName}.");
|
||||
ExtractOne(exe, Path.Combine(staging, FileName));
|
||||
var probe = archive.Entries.FirstOrDefault(
|
||||
e => e.FullName.EndsWith("/" + ProbeFileName, StringComparison.OrdinalIgnoreCase));
|
||||
if (probe != null)
|
||||
ExtractOne(probe, Path.Combine(staging, ProbeFileName));
|
||||
foreach (var entry in archive.Entries)
|
||||
{
|
||||
if (entry.FullName.EndsWith(".dll", StringComparison.OrdinalIgnoreCase))
|
||||
|
||||
Reference in New Issue
Block a user