From f80d1fa3a66b9779a5d4353a2f6a784cba117b7a Mon Sep 17 00:00:00 2001 From: alex6dj Date: Sat, 31 Jul 2021 15:34:47 -0400 Subject: [PATCH 1/2] Basic ffprobe subtitle support --- FFMpegCore/FFProbe/IMediaAnalysis.cs | 2 ++ FFMpegCore/FFProbe/MediaAnalysis.cs | 21 ++++++++++++++++++--- FFMpegCore/FFProbe/SubtitleStream.cs | 7 +++++++ 3 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 FFMpegCore/FFProbe/SubtitleStream.cs diff --git a/FFMpegCore/FFProbe/IMediaAnalysis.cs b/FFMpegCore/FFProbe/IMediaAnalysis.cs index 4e67d4f..7be3b20 100644 --- a/FFMpegCore/FFProbe/IMediaAnalysis.cs +++ b/FFMpegCore/FFProbe/IMediaAnalysis.cs @@ -9,7 +9,9 @@ public interface IMediaAnalysis MediaFormat Format { get; } AudioStream? PrimaryAudioStream { get; } VideoStream? PrimaryVideoStream { get; } + SubtitleStream? PrimarySubtitleStream { get; } List VideoStreams { get; } List AudioStreams { get; } + List SubtitleStreams { get; } } } diff --git a/FFMpegCore/FFProbe/MediaAnalysis.cs b/FFMpegCore/FFProbe/MediaAnalysis.cs index 2602f86..d021813 100644 --- a/FFMpegCore/FFProbe/MediaAnalysis.cs +++ b/FFMpegCore/FFProbe/MediaAnalysis.cs @@ -12,8 +12,9 @@ internal MediaAnalysis(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(); + SubtitleStreams = analysis.Streams.Where(stream => stream.CodecType == "subtitle").Select(ParseSubtitleStream).ToList(); } - + private MediaFormat ParseFormat(Format analysisFormat) { return new MediaFormat @@ -36,12 +37,14 @@ 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(); public List VideoStreams { get; } public List AudioStreams { get; } + public List SubtitleStreams { get; } private VideoStream ParseVideoStream(FFProbeStream stream) { @@ -84,7 +87,19 @@ private AudioStream ParseAudioStream(FFProbeStream stream) }; } - + private SubtitleStream ParseSubtitleStream(FFProbeStream stream) + { + return new SubtitleStream + { + Index = stream.Index, + BitRate = !string.IsNullOrEmpty(stream.BitRate) ? MediaAnalysisUtils.ParseIntInvariant(stream.BitRate) : default, + CodecName = stream.CodecName, + CodecLongName = stream.CodecLongName, + Duration = MediaAnalysisUtils.ParseDuration(stream), + Language = stream.GetLanguage(), + Tags = stream.Tags, + }; + } } public static class MediaAnalysisUtils diff --git a/FFMpegCore/FFProbe/SubtitleStream.cs b/FFMpegCore/FFProbe/SubtitleStream.cs new file mode 100644 index 0000000..80493f4 --- /dev/null +++ b/FFMpegCore/FFProbe/SubtitleStream.cs @@ -0,0 +1,7 @@ +namespace FFMpegCore +{ + public class SubtitleStream : MediaStream + { + + } +} \ No newline at end of file From 47916eac29fef9a7f86de79522e1eed0ae6d6a62 Mon Sep 17 00:00:00 2001 From: alex6dj Date: Sat, 31 Jul 2021 16:46:21 -0400 Subject: [PATCH 2/2] Basic ffprobe test --- FFMpegCore.Test/FFMpegCore.Test.csproj | 3 +++ FFMpegCore.Test/FFProbeTests.cs | 10 ++++++++++ FFMpegCore.Test/Resources/TestResources.cs | 1 + FFMpegCore.Test/Resources/sample.srt | 12 ++++++++++++ 4 files changed, 26 insertions(+) create mode 100644 FFMpegCore.Test/Resources/sample.srt diff --git a/FFMpegCore.Test/FFMpegCore.Test.csproj b/FFMpegCore.Test/FFMpegCore.Test.csproj index 98c9274..2505545 100644 --- a/FFMpegCore.Test/FFMpegCore.Test.csproj +++ b/FFMpegCore.Test/FFMpegCore.Test.csproj @@ -83,6 +83,9 @@ Always + + PreserveNewest + diff --git a/FFMpegCore.Test/FFProbeTests.cs b/FFMpegCore.Test/FFProbeTests.cs index 5cabc4e..897848d 100644 --- a/FFMpegCore.Test/FFProbeTests.cs +++ b/FFMpegCore.Test/FFProbeTests.cs @@ -100,5 +100,15 @@ public async Task Probe_Success_FromStream_Async() var info = await FFProbe.AnalyseAsync(stream); Assert.AreEqual(3, info.Duration.Seconds); } + + [TestMethod, Timeout(10000)] + public async Task Probe_Success_Subtitle_Async() + { + var info = await FFProbe.AnalyseAsync(TestResources.SrtSubtitle); + Assert.IsNotNull(info.PrimarySubtitleStream); + Assert.AreEqual(1, info.SubtitleStreams.Count); + Assert.AreEqual(0, info.AudioStreams.Count); + Assert.AreEqual(0, info.VideoStreams.Count); + } } } \ No newline at end of file diff --git a/FFMpegCore.Test/Resources/TestResources.cs b/FFMpegCore.Test/Resources/TestResources.cs index 6277dd3..14f8abe 100644 --- a/FFMpegCore.Test/Resources/TestResources.cs +++ b/FFMpegCore.Test/Resources/TestResources.cs @@ -20,5 +20,6 @@ public static class TestResources public static readonly string Mp3Audio = "./Resources/audio.mp3"; public static readonly string PngImage = "./Resources/cover.png"; public static readonly string ImageCollection = "./Resources/images"; + public static readonly string SrtSubtitle = "./Resources/sample.srt"; } } diff --git a/FFMpegCore.Test/Resources/sample.srt b/FFMpegCore.Test/Resources/sample.srt new file mode 100644 index 0000000..b08f594 --- /dev/null +++ b/FFMpegCore.Test/Resources/sample.srt @@ -0,0 +1,12 @@ +1 +00:00:00,000 --> 00:00:01,500 +For www.forom.com + +2 +00:00:01,500 --> 00:00:02,500 +Tonight's the night. + +3 +00:00:03,000 --> 00:00:15,000 +And it's going to happen +again and again -- \ No newline at end of file