Parse Format from FFProbe show_format

This commit is contained in:
Malte Rosenbjerg 2020-06-20 14:50:46 +02:00
parent f0b83a8941
commit b7b15079eb
6 changed files with 84 additions and 13 deletions

View file

@ -119,7 +119,7 @@ internal void Post()
public TArgument Find<TArgument>() where TArgument : class, IArgument
{
return _arguments.FirstOrDefault(arg => arg is TArgument) as TArgument;
return _arguments.OfType<TArgument>().FirstOrDefault();
}
}
}

View file

@ -9,12 +9,9 @@
<Version>1.0.12</Version>
<AssemblyVersion>1.1.0.0</AssemblyVersion>
<FileVersion>1.1.0.0</FileVersion>
<PackageReleaseNotes>- Support for .NET Standard 2.0
- Minor fixes
- DemuxConcatArgument
- Fix error in static Convert</PackageReleaseNotes>
<PackageReleaseNotes>- Format property on MediaAnalysis with information from show_format</PackageReleaseNotes>
<LangVersion>8</LangVersion>
<PackageVersion>2.1.1</PackageVersion>
<PackageVersion>2.2.0</PackageVersion>
<Authors>Vlad Jerca, Malte Rosenbjerg</Authors>
<PackageTags>ffmpeg ffprobe convert video audio mediafile resize analyze muxing</PackageTags>
<RepositoryType>GitHub</RepositoryType>

View file

@ -88,7 +88,7 @@ private static Instance PrepareInstance(string filePath, int outputCapacity)
{
FFProbeHelper.RootExceptionCheck(FFMpegOptions.Options.RootDirectory);
var ffprobe = FFMpegOptions.Options.FFProbeBinary();
var arguments = $"-print_format json -show_streams \"{filePath}\"";
var arguments = $"-print_format json -show_format -sexagesimal -show_streams \"{filePath}\"";
var instance = new Instance(ffprobe, arguments) {DataBufferCapacity = outputCapacity};
return instance;
}

View file

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace FFMpegCore
@ -7,6 +8,9 @@ public class FFProbeAnalysis
{
[JsonPropertyName("streams")]
public List<FFProbeStream> Streams { get; set; } = null!;
[JsonPropertyName("format")]
public Format Format { get; set; } = null!;
}
public class FFProbeStream
@ -73,5 +77,43 @@ public class Tags
[JsonPropertyName("language")]
public string Language { get; set; } = null!;
[JsonPropertyName("encoder")]
public string Encoder { get; set; } = null!;
}
public class Format
{
[JsonPropertyName("filename")]
public string Filename { get; set; }
[JsonPropertyName("nb_streams")]
public int NbStreams { get; set; }
[JsonPropertyName("nb_programs")]
public int NbPrograms { get; set; }
[JsonPropertyName("format_name")]
public string FormatName { get; set; }
[JsonPropertyName("format_long_name")]
public string FormatLongName { get; set; }
[JsonPropertyName("start_time")]
public string StartTime { get; set; }
[JsonPropertyName("duration")]
public string Duration { get; set; }
[JsonPropertyName("size")]
public string Size { get; set; }
[JsonPropertyName("bit_rate")]
public string BitRate { get; set; }
[JsonPropertyName("probe_score")]
public int ProbeScore { get; set; }
[JsonPropertyName("tags")]
public Tags Tags { get; set; }
}
}

View file

@ -10,6 +10,7 @@ public class MediaAnalysis
private static readonly Regex DurationRegex = new Regex("^(\\d{1,2}:\\d{1,2}:\\d{1,2}(.\\d{1,7})?)", RegexOptions.Compiled);
internal MediaAnalysis(string path, FFProbeAnalysis analysis)
{
Format = ParseFormat(analysis.Format);
VideoStreams = analysis.Streams.Where(stream => stream.CodecType == "video").Select(ParseVideoStream).ToList();
AudioStreams = analysis.Streams.Where(stream => stream.CodecType == "audio").Select(ParseAudioStream).ToList();
PrimaryVideoStream = VideoStreams.OrderBy(stream => stream.Index).FirstOrDefault();
@ -17,13 +18,30 @@ internal MediaAnalysis(string path, FFProbeAnalysis analysis)
Path = path;
}
private MediaFormat ParseFormat(Format analysisFormat)
{
return new MediaFormat
{
Duration = TimeSpan.Parse(analysisFormat.Duration),
FormatName = analysisFormat.FormatName,
FormatLongName = analysisFormat.FormatLongName,
StreamCount = analysisFormat.NbStreams,
ProbeScore = analysisFormat.ProbeScore,
BitRate = long.Parse(analysisFormat.BitRate ?? "0")
};
}
public string Path { get; }
public string Extension => System.IO.Path.GetExtension(Path);
public TimeSpan Duration => TimeSpan.FromSeconds(Math.Max(
PrimaryVideoStream?.Duration.TotalSeconds ?? 0,
PrimaryAudioStream?.Duration.TotalSeconds ?? 0));
public TimeSpan Duration => new []
{
Format.Duration,
PrimaryVideoStream?.Duration ?? TimeSpan.Zero,
PrimaryAudioStream?.Duration ?? TimeSpan.Zero
}.Max();
public MediaFormat Format { get; }
public AudioStream PrimaryAudioStream { get; }
public VideoStream PrimaryVideoStream { get; }
@ -54,8 +72,8 @@ private VideoStream ParseVideoStream(FFProbeStream stream)
private static TimeSpan ParseDuration(FFProbeStream ffProbeStream)
{
return ffProbeStream.Duration != null
? TimeSpan.FromSeconds(ParseDoubleInvariant(ffProbeStream.Duration))
return !string.IsNullOrEmpty(ffProbeStream.Duration)
? TimeSpan.Parse(ffProbeStream.Duration)
: TimeSpan.Parse(TrimTimeSpan(ffProbeStream.Tags?.Duration) ?? "0");
}
private static string? TrimTimeSpan(string? durationTag)

View file

@ -0,0 +1,14 @@
using System;
namespace FFMpegCore
{
public class MediaFormat
{
public TimeSpan Duration { get; set; }
public string FormatName { get; set; }
public string FormatLongName { get; set; }
public int StreamCount { get; set; }
public double ProbeScore { get; set; }
public double BitRate { get; set; }
}
}