aboutsummaryrefslogtreecommitdiff
path: root/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs
diff options
context:
space:
mode:
authorcvium <clausvium@gmail.com>2022-01-11 23:30:30 +0100
committercvium <clausvium@gmail.com>2022-01-11 23:30:30 +0100
commit6ffa9539bbfbfb1090b02cebc8a28283a8c69041 (patch)
tree13f4a1d968780f90cd7d0c99e422970117a380f0 /src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs
parentc658a883a2bc84b46ed73d209d2983e8a324cdce (diff)
Refactor and add scheduled task
Diffstat (limited to 'src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs')
-rw-r--r--src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs127
1 files changed, 63 insertions, 64 deletions
diff --git a/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs b/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs
index 351d880fe..320604e10 100644
--- a/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs
+++ b/src/Jellyfin.MediaEncoding.Keyframes/FfProbe/FfProbeKeyframeExtractor.cs
@@ -4,92 +4,91 @@ using System.Diagnostics;
using System.Globalization;
using System.IO;
-namespace Jellyfin.MediaEncoding.Keyframes.FfProbe
+namespace Jellyfin.MediaEncoding.Keyframes.FfProbe;
+
+/// <summary>
+/// FfProbe based keyframe extractor.
+/// </summary>
+public static class FfProbeKeyframeExtractor
{
+ private const string DefaultArguments = "-v error -skip_frame nokey -show_entries format=duration -show_entries stream=duration -show_entries packet=pts_time,flags -select_streams v -of csv \"{0}\"";
+
/// <summary>
- /// FfProbe based keyframe extractor.
+ /// Extracts the keyframes using the ffprobe executable at the specified path.
/// </summary>
- public static class FfProbeKeyframeExtractor
+ /// <param name="ffProbePath">The path to the ffprobe executable.</param>
+ /// <param name="filePath">The file path.</param>
+ /// <returns>An instance of <see cref="KeyframeData"/>.</returns>
+ public static KeyframeData GetKeyframeData(string ffProbePath, string filePath)
{
- private const string DefaultArguments = "-v error -skip_frame nokey -show_entries format=duration -show_entries stream=duration -show_entries packet=pts_time,flags -select_streams v -of csv \"{0}\"";
-
- /// <summary>
- /// Extracts the keyframes using the ffprobe executable at the specified path.
- /// </summary>
- /// <param name="ffProbePath">The path to the ffprobe executable.</param>
- /// <param name="filePath">The file path.</param>
- /// <returns>An instance of <see cref="KeyframeData"/>.</returns>
- public static KeyframeData GetKeyframeData(string ffProbePath, string filePath)
+ using var process = new Process
{
- using var process = new Process
+ StartInfo = new ProcessStartInfo
{
- StartInfo = new ProcessStartInfo
- {
- FileName = ffProbePath,
- Arguments = string.Format(CultureInfo.InvariantCulture, DefaultArguments, filePath),
+ FileName = ffProbePath,
+ Arguments = string.Format(CultureInfo.InvariantCulture, DefaultArguments, filePath),
- CreateNoWindow = true,
- UseShellExecute = false,
- RedirectStandardOutput = true,
+ CreateNoWindow = true,
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
- WindowStyle = ProcessWindowStyle.Hidden,
- ErrorDialog = false,
- },
- EnableRaisingEvents = true
- };
+ WindowStyle = ProcessWindowStyle.Hidden,
+ ErrorDialog = false,
+ },
+ EnableRaisingEvents = true
+ };
- process.Start();
+ process.Start();
- return ParseStream(process.StandardOutput);
- }
+ return ParseStream(process.StandardOutput);
+ }
- internal static KeyframeData ParseStream(StreamReader reader)
- {
- var keyframes = new List<long>();
- double streamDuration = 0;
- double formatDuration = 0;
+ internal static KeyframeData ParseStream(StreamReader reader)
+ {
+ var keyframes = new List<long>();
+ double streamDuration = 0;
+ double formatDuration = 0;
- while (!reader.EndOfStream)
+ while (!reader.EndOfStream)
+ {
+ var line = reader.ReadLine().AsSpan();
+ if (line.IsEmpty)
{
- var line = reader.ReadLine().AsSpan();
- if (line.IsEmpty)
- {
- continue;
- }
+ continue;
+ }
- var firstComma = line.IndexOf(',');
- var lineType = line[..firstComma];
- var rest = line[(firstComma + 1)..];
- if (lineType.Equals("packet", StringComparison.OrdinalIgnoreCase))
+ var firstComma = line.IndexOf(',');
+ var lineType = line[..firstComma];
+ var rest = line[(firstComma + 1)..];
+ if (lineType.Equals("packet", StringComparison.OrdinalIgnoreCase))
+ {
+ if (rest.EndsWith(",K_"))
{
- if (rest.EndsWith(",K_"))
- {
- // Trim the flags from the packet line. Example line: packet,7169.079000,K_
- var keyframe = double.Parse(rest[..^3], NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture);
- // Have to manually convert to ticks to avoid rounding errors as TimeSpan is only precise down to 1 ms when converting double.
- keyframes.Add(Convert.ToInt64(keyframe * TimeSpan.TicksPerSecond));
- }
+ // Trim the flags from the packet line. Example line: packet,7169.079000,K_
+ var keyframe = double.Parse(rest[..^3], NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture);
+ // Have to manually convert to ticks to avoid rounding errors as TimeSpan is only precise down to 1 ms when converting double.
+ keyframes.Add(Convert.ToInt64(keyframe * TimeSpan.TicksPerSecond));
}
- else if (lineType.Equals("stream", StringComparison.OrdinalIgnoreCase))
+ }
+ else if (lineType.Equals("stream", StringComparison.OrdinalIgnoreCase))
+ {
+ if (double.TryParse(rest, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var streamDurationResult))
{
- if (double.TryParse(rest, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var streamDurationResult))
- {
- streamDuration = streamDurationResult;
- }
+ streamDuration = streamDurationResult;
}
- else if (lineType.Equals("format", StringComparison.OrdinalIgnoreCase))
+ }
+ else if (lineType.Equals("format", StringComparison.OrdinalIgnoreCase))
+ {
+ if (double.TryParse(rest, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var formatDurationResult))
{
- if (double.TryParse(rest, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out var formatDurationResult))
- {
- formatDuration = formatDurationResult;
- }
+ formatDuration = formatDurationResult;
}
}
+ }
- // Prefer the stream duration as it should be more accurate
- var duration = streamDuration > 0 ? streamDuration : formatDuration;
+ // Prefer the stream duration as it should be more accurate
+ var duration = streamDuration > 0 ? streamDuration : formatDuration;
- return new KeyframeData(TimeSpan.FromSeconds(duration).Ticks, keyframes);
- }
+ return new KeyframeData(TimeSpan.FromSeconds(duration).Ticks, keyframes);
}
}