Merge pull request #351 from keg247/sample-aspect-ratio

Add SampleAspectRatio property to VideoStream

Former-commit-id: 9727ec5cfe
This commit is contained in:
Malte Rosenbjerg 2023-01-31 23:02:51 +01:00 committed by GitHub
commit b032af6405
4 changed files with 39 additions and 32 deletions

View file

@ -1,10 +1,10 @@
using System;
using FFMpegCore.Test.Resources;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using FFMpegCore.Test.Resources;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace FFMpegCore.Test
{
@ -24,7 +24,7 @@ public async Task Audio_FromStream_Duration()
public void FrameAnalysis_Sync()
{
var frameAnalysis = FFProbe.GetFrames(TestResources.WebmVideo);
Assert.AreEqual(90, frameAnalysis.Frames.Count);
Assert.IsTrue(frameAnalysis.Frames.All(f => f.PixelFormat == "yuv420p"));
Assert.IsTrue(frameAnalysis.Frames.All(f => f.Height == 360));
@ -36,7 +36,7 @@ public void FrameAnalysis_Sync()
public async Task FrameAnalysis_Async()
{
var frameAnalysis = await FFProbe.GetFramesAsync(TestResources.WebmVideo);
Assert.AreEqual(90, frameAnalysis.Frames.Count);
Assert.IsTrue(frameAnalysis.Frames.All(f => f.PixelFormat == "yuv420p"));
Assert.IsTrue(frameAnalysis.Frames.All(f => f.Height == 360));
@ -55,12 +55,12 @@ public async Task PacketAnalysis_Async()
Assert.AreEqual(1362, packets.Last().Size);
}
[TestMethod]
public void PacketAnalysis_Sync()
{
var packets = FFProbe.GetPackets(TestResources.WebmVideo).Packets;
Assert.AreEqual(96, packets.Count);
Assert.IsTrue(packets.All(f => f.CodecType == "video"));
Assert.AreEqual("K_", packets[0].Flags);
@ -74,9 +74,9 @@ public void PacketAnalysisAudioVideo_Sync()
Assert.AreEqual(216, packets.Count);
var actual = packets.Select(f => f.CodecType).Distinct().ToList();
var expected = new List<string> {"audio", "video"};
var expected = new List<string> { "audio", "video" };
CollectionAssert.AreEquivalent(expected, actual);
Assert.IsTrue(packets.Where(t=>t.CodecType == "audio").All(f => f.Flags == "K_"));
Assert.IsTrue(packets.Where(t => t.CodecType == "audio").All(f => f.Flags == "K_"));
Assert.AreEqual(75, packets.Count(t => t.CodecType == "video"));
Assert.AreEqual(141, packets.Count(t => t.CodecType == "audio"));
}
@ -105,13 +105,13 @@ public async Task Uri_Duration()
var fileAnalysis = await FFProbe.AnalyseAsync(new Uri("https://github.com/rosenbjerg/FFMpegCore/raw/master/FFMpegCore.Test/Resources/input_3sec.webm"));
Assert.IsNotNull(fileAnalysis);
}
[TestMethod]
public void Probe_Success()
{
var info = FFProbe.Analyse(TestResources.Mp4Video);
Assert.AreEqual(3, info.Duration.Seconds);
Assert.AreEqual("5.1", info.PrimaryAudioStream!.ChannelLayout);
Assert.AreEqual(6, info.PrimaryAudioStream.Channels);
Assert.AreEqual("AAC (Advanced Audio Coding)", info.PrimaryAudioStream.CodecLongName);
@ -121,10 +121,12 @@ public void Probe_Success()
Assert.AreEqual(48000, info.PrimaryAudioStream.SampleRateHz);
Assert.AreEqual("mp4a", info.PrimaryAudioStream.CodecTagString);
Assert.AreEqual("0x6134706d", info.PrimaryAudioStream.CodecTag);
Assert.AreEqual(1471810, info.PrimaryVideoStream!.BitRate);
Assert.AreEqual(16, info.PrimaryVideoStream.DisplayAspectRatio.Width);
Assert.AreEqual(9, info.PrimaryVideoStream.DisplayAspectRatio.Height);
Assert.AreEqual(1, info.PrimaryVideoStream.SampleAspectRatio.Width);
Assert.AreEqual(1, info.PrimaryVideoStream.SampleAspectRatio.Height);
Assert.AreEqual("yuv420p", info.PrimaryVideoStream.PixelFormat);
Assert.AreEqual(1280, info.PrimaryVideoStream.Width);
Assert.AreEqual(720, info.PrimaryVideoStream.Height);
@ -137,7 +139,7 @@ public void Probe_Success()
Assert.AreEqual("avc1", info.PrimaryVideoStream.CodecTagString);
Assert.AreEqual("0x31637661", info.PrimaryVideoStream.CodecTag);
}
[TestMethod, Timeout(10000)]
public async Task Probe_Async_Success()
{

View file

@ -7,40 +7,40 @@ public class FFProbeAnalysis
{
[JsonPropertyName("streams")]
public List<FFProbeStream> Streams { get; set; } = null!;
[JsonPropertyName("format")]
public Format Format { get; set; } = null!;
[JsonIgnore]
public IReadOnlyList<string> ErrorData { get; set; } = new List<string>();
}
public class FFProbeStream : ITagsContainer, IDispositionContainer
{
[JsonPropertyName("index")]
public int Index { get; set; }
[JsonPropertyName("avg_frame_rate")]
public string AvgFrameRate { get; set; } = null!;
[JsonPropertyName("bits_per_raw_sample")]
public string BitsPerRawSample { get; set; } = null!;
[JsonPropertyName("bit_rate")]
public string BitRate { get; set; } = null!;
[JsonPropertyName("channels")]
public int? Channels { get; set; }
[JsonPropertyName("channel_layout")]
public string ChannelLayout { get; set; } = null!;
[JsonPropertyName("codec_type")]
public string CodecType { get; set; } = null!;
[JsonPropertyName("codec_name")]
public string CodecName { get; set; } = null!;
[JsonPropertyName("codec_long_name")]
public string CodecLongName { get; set; } = null!;
@ -53,6 +53,9 @@ public class FFProbeStream : ITagsContainer, IDispositionContainer
[JsonPropertyName("display_aspect_ratio")]
public string DisplayAspectRatio { get; set; } = null!;
[JsonPropertyName("sample_aspect_ratio")]
public string SampleAspectRatio { get; set; } = null!;
[JsonPropertyName("duration")]
public string Duration { get; set; } = null!;
@ -67,10 +70,10 @@ public class FFProbeStream : ITagsContainer, IDispositionContainer
[JsonPropertyName("r_frame_rate")]
public string FrameRate { get; set; } = null!;
[JsonPropertyName("pix_fmt")]
public string PixelFormat { get; set; } = null!;
[JsonPropertyName("sample_rate")]
public string SampleRate { get; set; } = null!;
@ -135,7 +138,7 @@ public static class TagExtensions
return tagValue;
return null;
}
public static string? GetLanguage(this ITagsContainer tagsContainer) => TryGetTagValue(tagsContainer, "language");
public static string? GetCreationTime(this ITagsContainer tagsContainer) => TryGetTagValue(tagsContainer, "creation_time ");
public static string? GetRotate(this ITagsContainer tagsContainer) => TryGetTagValue(tagsContainer, "rotate");

View file

@ -15,7 +15,7 @@ internal MediaAnalysis(FFProbeAnalysis analysis)
SubtitleStreams = analysis.Streams.Where(stream => stream.CodecType == "subtitle").Select(ParseSubtitleStream).ToList();
ErrorData = analysis.ErrorData;
}
private MediaFormat ParseFormat(Format analysisFormat)
{
return new MediaFormat
@ -38,7 +38,7 @@ private MediaFormat ParseFormat(Format analysisFormat)
}.Max();
public MediaFormat Format { get; }
public AudioStream? PrimaryAudioStream => AudioStreams.OrderBy(stream => stream.Index).FirstOrDefault();
public VideoStream? PrimaryVideoStream => VideoStreams.OrderBy(stream => stream.Index).FirstOrDefault();
public SubtitleStream? PrimarySubtitleStream => SubtitleStreams.OrderBy(stream => stream.Index).FirstOrDefault();
@ -47,7 +47,7 @@ private MediaFormat ParseFormat(Format analysisFormat)
public List<AudioStream> AudioStreams { get; }
public List<SubtitleStream> SubtitleStreams { get; }
public IReadOnlyList<string> ErrorData { get; }
private VideoStream ParseVideoStream(FFProbeStream stream)
{
return new VideoStream
@ -61,6 +61,7 @@ private VideoStream ParseVideoStream(FFProbeStream stream)
CodecTag = stream.CodecTag,
CodecTagString = stream.CodecTagString,
DisplayAspectRatio = MediaAnalysisUtils.ParseRatioInt(stream.DisplayAspectRatio, ':'),
SampleAspectRatio = MediaAnalysisUtils.ParseRatioInt(stream.SampleAspectRatio, ':'),
Duration = MediaAnalysisUtils.ParseDuration(stream),
FrameRate = MediaAnalysisUtils.DivideRatio(MediaAnalysisUtils.ParseRatioDouble(stream.FrameRate, '/')),
Height = stream.Height ?? 0,
@ -141,11 +142,11 @@ public static double ParseDoubleInvariant(string line) =>
public static int ParseIntInvariant(string line) =>
int.Parse(line, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture);
public static long ParseLongInvariant(string line) =>
long.Parse(line, System.Globalization.NumberStyles.Any, System.Globalization.CultureInfo.InvariantCulture);
public static TimeSpan ParseDuration(string duration)
{
if (!string.IsNullOrEmpty(duration))

View file

@ -7,6 +7,7 @@ public class VideoStream : MediaStream
public double AvgFrameRate { get; set; }
public int BitsPerRawSample { get; set; }
public (int Width, int Height) DisplayAspectRatio { get; set; }
public (int Width, int Height) SampleAspectRatio { get; set; }
public string Profile { get; set; } = null!;
public int Width { get; set; }
public int Height { get; set; }