From d755c1d5264520fa3ac95c054de738264ed7a0a1 Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Thu, 5 Aug 2021 13:21:57 +0200 Subject: [PATCH 1/9] Fix PcmAudioSampleWrapper namespace Former-commit-id: fc23456eb10b1d82e3e6eef6f0713beb627c23c4 --- FFMpegCore.Test/AudioTest.cs | 1 + FFMpegCore/Extend/PcmAudioSampleWrapper.cs | 39 ++++++++++++---------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/FFMpegCore.Test/AudioTest.cs b/FFMpegCore.Test/AudioTest.cs index f1abb72..b6fde77 100644 --- a/FFMpegCore.Test/AudioTest.cs +++ b/FFMpegCore.Test/AudioTest.cs @@ -8,6 +8,7 @@ using System.IO; using System.Linq; using System.Threading.Tasks; +using FFMpegCore.Extend; namespace FFMpegCore.Test { diff --git a/FFMpegCore/Extend/PcmAudioSampleWrapper.cs b/FFMpegCore/Extend/PcmAudioSampleWrapper.cs index d67038b..503a23f 100644 --- a/FFMpegCore/Extend/PcmAudioSampleWrapper.cs +++ b/FFMpegCore/Extend/PcmAudioSampleWrapper.cs @@ -1,27 +1,30 @@ -using FFMpegCore.Pipes; -using System.IO; +using System.IO; using System.Threading; using System.Threading.Tasks; +using FFMpegCore.Pipes; -public class PcmAudioSampleWrapper : IAudioSample +namespace FFMpegCore.Extend { - //This could actually be short or int, but copies would be inefficient. - //Handling bytes lets the user decide on the conversion, and abstract the library - //from handling shorts, unsigned shorts, integers, unsigned integers and floats. - private readonly byte[] _sample; - - public PcmAudioSampleWrapper(byte[] sample) + public class PcmAudioSampleWrapper : IAudioSample { - _sample = sample; - } + //This could actually be short or int, but copies would be inefficient. + //Handling bytes lets the user decide on the conversion, and abstract the library + //from handling shorts, unsigned shorts, integers, unsigned integers and floats. + private readonly byte[] _sample; - public void Serialize(Stream stream) - { - stream.Write(_sample, 0, _sample.Length); - } + public PcmAudioSampleWrapper(byte[] sample) + { + _sample = sample; + } - public async Task SerializeAsync(Stream stream, CancellationToken token) - { - await stream.WriteAsync(_sample, 0, _sample.Length, token); + public void Serialize(Stream stream) + { + stream.Write(_sample, 0, _sample.Length); + } + + public async Task SerializeAsync(Stream stream, CancellationToken token) + { + await stream.WriteAsync(_sample, 0, _sample.Length, token); + } } } From 8c67ddb769da0b92fe2d1e2571624eb86c6e1cf8 Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Fri, 6 Aug 2021 12:13:35 +0200 Subject: [PATCH 2/9] Replace contributors block with image from contributors-img Former-commit-id: e13376f17531f2fcb920119aa2e31794f518585b --- README.md | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 298489e..1eb08a3 100644 --- a/README.md +++ b/README.md @@ -212,16 +212,9 @@ The root and temp directory for the ffmpeg binaries can be configured via the `f ## Contributors - - - - - - - - - - + + + ### License From 1f3d1ec429235fa20f29ce4f49b3536b3f1205c1 Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Sat, 7 Aug 2021 14:40:58 +0200 Subject: [PATCH 3/9] Move Loop(1) to image FileInput. Fix for #206 Former-commit-id: 914003ee3252869d3f2846d2e0427f65fca68ff2 --- FFMpegCore/FFMpeg/FFMpeg.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/FFMpegCore/FFMpeg/FFMpeg.cs b/FFMpegCore/FFMpeg/FFMpeg.cs index 42c344b..2928e29 100644 --- a/FFMpegCore/FFMpeg/FFMpeg.cs +++ b/FFMpegCore/FFMpeg/FFMpeg.cs @@ -231,10 +231,10 @@ public static bool PosterWithAudio(string image, string audio, string output) FFMpegHelper.ConversionSizeExceptionCheck(Image.FromFile(image)); return FFMpegArguments - .FromFileInput(image) + .FromFileInput(image, false, options => options + .Loop(1)) .AddFileInput(audio) .OutputToFile(output, true, options => options - .Loop(1) .WithVideoCodec(VideoCodec.LibX264) .WithConstantRateFactor(21) .WithAudioBitrate(AudioQuality.Normal) From 3516440ca1e2cab5b38ba15e2c72e75ccc491455 Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Sat, 7 Aug 2021 14:54:48 +0200 Subject: [PATCH 4/9] Specify README.md as nuget readme Former-commit-id: 0efaf686f36d08850f4e1a6bb7020048093e779a --- FFMpegCore/FFMpegCore.csproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/FFMpegCore/FFMpegCore.csproj b/FFMpegCore/FFMpegCore.csproj index dd96a3d..5f7b969 100644 --- a/FFMpegCore/FFMpegCore.csproj +++ b/FFMpegCore/FFMpegCore.csproj @@ -6,9 +6,8 @@ https://github.com/rosenbjerg/FFMpegCore A .NET Standard FFMpeg/FFProbe wrapper for easily integrating media analysis and conversion into your .NET applications - 3.0.0.0 - 3.0.0.0 - 3.0.0.0 + 4.0.0.0 + README.md - Cancellation token support (thanks patagonaa) - Support for setting stdout and stderr encoding for ffprobe (thanks CepheiSigma) - Improved ffprobe exceptions @@ -27,6 +26,7 @@ Always + From 1c8d0fcd4f86b6fb6a0eab924a9669f6e1c05167 Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Sat, 7 Aug 2021 15:34:40 +0200 Subject: [PATCH 5/9] Update README.md Former-commit-id: 78c749c748e980fb3f0d53c98ea934b3e7f4a55a --- README.md | 121 +++++++++++++++++++++++++++--------------------------- 1 file changed, 60 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 1eb08a3..3d19fa8 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,29 @@ -# FFMpegCore -[![CI](https://github.com/rosenbjerg/FFMpegCore/workflows/CI/badge.svg)](https://github.com/rosenbjerg/FFMpegCore/actions?query=workflow%3ACI) +# [FFMpegCore](https://www.nuget.org/packages/FFMpegCore/) [![NuGet Badge](https://buildstats.info/nuget/FFMpegCore)](https://www.nuget.org/packages/FFMpegCore/) [![GitHub issues](https://img.shields.io/github/issues/rosenbjerg/FFMpegCore)](https://github.com/rosenbjerg/FFMpegCore/issues) [![GitHub stars](https://img.shields.io/github/stars/rosenbjerg/FFMpegCore)](https://github.com/rosenbjerg/FFMpegCore/stargazers) [![GitHub](https://img.shields.io/github/license/rosenbjerg/FFMpegCore)](https://github.com/rosenbjerg/FFMpegCore/blob/master/LICENSE) +[![CI](https://github.com/rosenbjerg/FFMpegCore/workflows/CI/badge.svg)](https://github.com/rosenbjerg/FFMpegCore/actions?query=workflow%3ACI) -# Setup - -#### NuGet: - -``` -Install-Package FFMpegCore -``` - -A .NET Standard FFMpeg/FFProbe wrapper for easily integrating media analysis and conversion into your C# applications. Support both synchronous and asynchronous use +A .NET Standard FFMpeg/FFProbe wrapper for easily integrating media analysis and conversion into your .NET applications. Supports both synchronous and asynchronous calls # API ## FFProbe -FFProbe is used to gather media information: +Use FFProbe to analyze media files: ```csharp -var mediaInfo = FFProbe.Analyse(inputPath); +var mediaInfo = await FFProbe.AnalyseAsync(inputPath); ``` or ```csharp -var mediaInfo = await FFProbe.AnalyseAsync(inputPath); +var mediaInfo = FFProbe.Analyse(inputPath); ``` ## FFMpeg -FFMpeg is used for converting your media files to web ready formats. +Use FFMpeg to convert your media files. Easily build your FFMpeg arguments using the fluent argument builder: Convert input file to h264/aac scaled to 720p w/ faststart, for web playback @@ -49,15 +41,6 @@ FFMpegArguments .ProcessSynchronously(); ``` -Easily capture screens from your videos: -```csharp -// process the snapshot in-memory and use the Bitmap directly -var bitmap = FFMpeg.Snapshot(inputPath, new Size(200, 400), TimeSpan.FromMinutes(1)); - -// or persists the image on the drive -FFMpeg.Snapshot(inputPath, outputPath, new Size(200, 400), TimeSpan.FromMinutes(1)); -``` - Convert to and/or from streams ```csharp await FFMpegArguments @@ -68,7 +51,19 @@ await FFMpegArguments .ProcessAsynchronously(); ``` -Join video parts into one single file: +## Helper methods +The provided helper methods makes it simple to perform common operations. + +### Easily capture snapshots from a video file: +```csharp +// process the snapshot in-memory and use the Bitmap directly +var bitmap = FFMpeg.Snapshot(inputPath, new Size(200, 400), TimeSpan.FromMinutes(1)); + +// or persists the image on the drive +FFMpeg.Snapshot(inputPath, outputPath, new Size(200, 400), TimeSpan.FromMinutes(1)); +``` + +### Join video parts into one single file: ```csharp FFMpeg.Join(@"..\joined_video.mp4", @"..\part1.mp4", @@ -77,7 +72,7 @@ FFMpeg.Join(@"..\joined_video.mp4", ); ``` -Join images into a video: +### Join images into a video: ```csharp FFMpeg.JoinImageSequence(@"..\joined_video.mp4", frameRate: 1, ImageInfo.FromPath(@"..\1.png"), @@ -86,22 +81,22 @@ FFMpeg.JoinImageSequence(@"..\joined_video.mp4", frameRate: 1, ); ``` -Mute videos: +### Mute the audio of a video file: ```csharp FFMpeg.Mute(inputPath, outputPath); ``` -Save audio track from video: +### Extract the audio track from a video file: ```csharp FFMpeg.ExtractAudio(inputPath, outputPath); ``` -Add or replace audio track on video: +### Add or replace the audio track of a video file: ```csharp FFMpeg.ReplaceAudio(inputPath, inputAudioPath, outputPath); ``` -Add poster image to audio file (good for youtube videos): +### Combine an image with audio file, for youtube or similar platforms ```csharp FFMpeg.PosterWithAudio(inputPath, inputAudioPath, outputPath); // or @@ -111,26 +106,27 @@ image.AddAudio(inputAudioPath, outputPath); Other available arguments could be found in `FFMpegCore.Arguments` namespace. -### Input piping -With input piping it is possible to write video frames directly from program memory without saving them to jpeg or png and then passing path to input of ffmpeg. This feature also allows us to convert video on-the-fly while frames are being generated or received. +## Input piping +With input piping it is possible to write video frames directly from program memory without saving them to jpeg or png and then passing path to input of ffmpeg. This feature also allows for converting video on-the-fly while frames are being generated or received. -The `IPipeSource` interface is used as the source of data. It could be represented as encoded video stream or raw frames stream. Currently, the `IPipeSource` interface has single implementation, `RawVideoPipeSource` that is used for raw stream encoding. +An object implementing the `IPipeSource` interface is used as the source of data. Currently, the `IPipeSource` interface has two implementations; `StreamPipeSource` for streams, and `RawVideoPipeSource` for raw video frames. -For example: +### Working with raw video frames -Method that is generating bitmap frames: +Method for generating bitmap frames: ```csharp IEnumerable CreateFrames(int count) { for(int i = 0; i < count; i++) { - yield return GetNextFrame(); //method of generating new frames + yield return GetNextFrame(); //method that generates of receives the next frame } } ``` -Then create `ArgumentsContainer` with `InputPipeArgument` + +Then create a `RawVideoPipeSource` that utilises your video frame source ```csharp -var videoFramesSource = new RawVideoPipeSource(CreateFrames(64)) //pass IEnumerable or IEnumerator to constructor of RawVideoPipeSource +var videoFramesSource = new RawVideoPipeSource(CreateFrames(64)) { FrameRate = 30 //set source frame rate }; @@ -141,51 +137,43 @@ await FFMpegArguments .ProcessAsynchronously(); ``` -if you want to use `System.Drawing.Bitmap` as `IVideoFrame`, there is a `BitmapVideoFrameWrapper` wrapper class. +If you want to use `System.Drawing.Bitmap`s as `IVideoFrame`s, a `BitmapVideoFrameWrapper` wrapper class is provided. -## Binaries +# Binaries +## Installation If you prefer to manually download them, visit [ffbinaries](https://ffbinaries.com/downloads) or [zeranoe Windows builds](https://ffmpeg.zeranoe.com/builds/). -#### Windows - -command: `choco install ffmpeg -Y` +### Windows (using choco) +command: `choco install ffmpeg -y` location: `C:\ProgramData\chocolatey\lib\ffmpeg\tools\ffmpeg\bin` -#### Mac OSX - +### Mac OSX command: `brew install ffmpeg mono-libgdiplus` location: `/usr/local/bin` -#### Ubuntu - +### Ubuntu command: `sudo apt-get install -y ffmpeg libgdiplus` location: `/usr/bin` + ## Path Configuration -#### Behavior - -If you wish to support multiple client processor architectures, you can do so by creating a folder `x64` and `x86` in the `root` directory. -Both folders should contain the binaries (`ffmpeg.exe` and `ffprobe.exe`) for build for the respective architectures. - -By doing so, the library will attempt to use either `/root/{ARCH}/(ffmpeg|ffprobe).exe`. - -If these folders are not defined, it will try to find the binaries in `/root/(ffmpeg|ffprobe.exe)` - -#### Option 1 +### Option 1 The default value of an empty string (expecting ffmpeg to be found through PATH) can be overwritten via the `FFOptions` class: -```c# +```csharp // setting global options GlobalFFOptions.Configure(new FFOptions { BinaryFolder = "./bin", TemporaryFilesFolder = "/tmp" }); + // or GlobalFFOptions.Configure(options => options.BinaryFolder = "./bin"); + // on some systems the absolute path may be required, in which case GlobalFFOptions.Configure(new FFOptions { BinaryFolder = Server.MapPath("./bin"), TemporaryFilesFolder = Server.MapPath("/tmp") }); @@ -196,9 +184,9 @@ await FFMpegArguments .ProcessAsynchronously(true, new FFOptions { BinaryFolder = "./bin", TemporaryFilesFolder = "/tmp" }); ``` -#### Option 2 +### Option 2 -The root and temp directory for the ffmpeg binaries can be configured via the `ffmpeg.config.json` file. +The root and temp directory for the ffmpeg binaries can be configured via the `ffmpeg.config.json` file, which will be read on first use only. ```json { @@ -207,8 +195,19 @@ The root and temp directory for the ffmpeg binaries can be configured via the `f } ``` +### Supporting both 32 and 64 bit processes +If you wish to support multiple client processor architectures, you can do so by creating a folder `x64` and `x86` in the `root` directory. +Both folders should contain the binaries (`ffmpeg.exe` and `ffprobe.exe`) for build for the respective architectures. + +By doing so, the library will attempt to use either `/root/{ARCH}/(ffmpeg|ffprobe).exe`. + +If these folders are not defined, it will try to find the binaries in `/root/(ffmpeg|ffprobe.exe)`. + +(`.exe` is only appended on Windows) + + # Compatibility - Some versions of FFMPEG might not have the same argument schema. The lib has been tested with version `3.3` to `4.2` +Older versions of ffmpeg might not support all ffmpeg arguments available through this library. The library has been tested with version `3.3` to `4.2` ## Contributors From b466c1b649ff752eaf3674f8a1032ad9bc587f8a Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Sat, 7 Aug 2021 16:08:15 +0200 Subject: [PATCH 6/9] Add non-code contributors Former-commit-id: 2722431457baee63caadda56188e627cf7320dfe --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d19fa8..d58e3fe 100644 --- a/README.md +++ b/README.md @@ -210,11 +210,15 @@ If these folders are not defined, it will try to find the binaries in `/root/(ff Older versions of ffmpeg might not support all ffmpeg arguments available through this library. The library has been tested with version `3.3` to `4.2` -## Contributors +## Code contributors +## Non-code contributors + + + ### License Copyright © 2021 From d73d7fa30e2ff65cb4dea3343080e807430d4e8a Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Sat, 7 Aug 2021 16:39:10 +0200 Subject: [PATCH 7/9] Load config file, if found, on first use Former-commit-id: e363440118e3f92bcdd3a37e1c5aa239d93a2f63 --- FFMpegCore/FFMpegCore.csproj | 2 +- FFMpegCore/GlobalFFOptions.cs | 29 +++++++++++++++++------------ 2 files changed, 18 insertions(+), 13 deletions(-) diff --git a/FFMpegCore/FFMpegCore.csproj b/FFMpegCore/FFMpegCore.csproj index 5f7b969..daf7901 100644 --- a/FFMpegCore/FFMpegCore.csproj +++ b/FFMpegCore/FFMpegCore.csproj @@ -26,7 +26,7 @@ Always - + diff --git a/FFMpegCore/GlobalFFOptions.cs b/FFMpegCore/GlobalFFOptions.cs index 358787a..37340cc 100644 --- a/FFMpegCore/GlobalFFOptions.cs +++ b/FFMpegCore/GlobalFFOptions.cs @@ -8,27 +8,20 @@ namespace FFMpegCore public static class GlobalFFOptions { private static readonly string ConfigFile = "ffmpeg.config.json"; + private static FFOptions? _current; - public static FFOptions Current { get; private set; } - static GlobalFFOptions() + public static FFOptions Current { - if (File.Exists(ConfigFile)) - { - Current = JsonSerializer.Deserialize(File.ReadAllText(ConfigFile))!; - } - else - { - Current = new FFOptions(); - } + get { return _current ??= LoadFFOptions(); } } - + public static void Configure(Action optionsAction) { optionsAction?.Invoke(Current); } public static void Configure(FFOptions ffOptions) { - Current = ffOptions ?? throw new ArgumentNullException(nameof(ffOptions)); + _current = ffOptions ?? throw new ArgumentNullException(nameof(ffOptions)); } @@ -48,5 +41,17 @@ private static string GetFFBinaryPath(string name, FFOptions ffOptions) return Path.Combine(ffOptions.BinaryFolder, ffName); } + + private static FFOptions LoadFFOptions() + { + if (File.Exists(ConfigFile)) + { + return JsonSerializer.Deserialize(File.ReadAllText(ConfigFile))!; + } + else + { + return new FFOptions(); + } + } } } From cbd33fd553e14950538f1e34d3c87f609d0acbee Mon Sep 17 00:00:00 2001 From: Warrick Wilson Date: Mon, 9 Aug 2021 14:52:39 -0500 Subject: [PATCH 8/9] Added CodecTag and CodecTagString properties to info derived from an FFProbe.Analyse() call. This allows for specific codecs to be identified to check compatibility with hardware limitations. Former-commit-id: ac2b358fadcb727ca76851a8bfe396c26b795f22 --- FFMpegCore.Test/FFProbeTests.cs | 4 ++++ FFMpegCore/FFProbe/FFProbeAnalysis.cs | 6 ++++++ FFMpegCore/FFProbe/MediaAnalysis.cs | 4 ++++ FFMpegCore/FFProbe/MediaStream.cs | 2 ++ 4 files changed, 16 insertions(+) diff --git a/FFMpegCore.Test/FFProbeTests.cs b/FFMpegCore.Test/FFProbeTests.cs index 897848d..7af92cd 100644 --- a/FFMpegCore.Test/FFProbeTests.cs +++ b/FFMpegCore.Test/FFProbeTests.cs @@ -63,6 +63,8 @@ public void Probe_Success() Assert.AreEqual("LC", info.PrimaryAudioStream.Profile); Assert.AreEqual(377351, info.PrimaryAudioStream.BitRate); 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); @@ -76,6 +78,8 @@ public void Probe_Success() Assert.AreEqual("h264", info.PrimaryVideoStream.CodecName); Assert.AreEqual(8, info.PrimaryVideoStream.BitsPerRawSample); Assert.AreEqual("Main", info.PrimaryVideoStream.Profile); + Assert.AreEqual("avc1", info.PrimaryVideoStream.CodecTagString); + Assert.AreEqual("0x31637661", info.PrimaryVideoStream.CodecTag); } [TestMethod, Timeout(10000)] diff --git a/FFMpegCore/FFProbe/FFProbeAnalysis.cs b/FFMpegCore/FFProbe/FFProbeAnalysis.cs index a0f2d41..1997cc3 100644 --- a/FFMpegCore/FFProbe/FFProbeAnalysis.cs +++ b/FFMpegCore/FFProbe/FFProbeAnalysis.cs @@ -41,6 +41,12 @@ public class FFProbeStream : ITagsContainer [JsonPropertyName("codec_long_name")] public string CodecLongName { get; set; } = null!; + [JsonPropertyName("codec_tag")] + public string CodecTag { get; set; } = null!; + + [JsonPropertyName("codec_tag_string")] + public string CodecTagString { get; set; } = null!; + [JsonPropertyName("display_aspect_ratio")] public string DisplayAspectRatio { get; set; } = null!; diff --git a/FFMpegCore/FFProbe/MediaAnalysis.cs b/FFMpegCore/FFProbe/MediaAnalysis.cs index d021813..aea714c 100644 --- a/FFMpegCore/FFProbe/MediaAnalysis.cs +++ b/FFMpegCore/FFProbe/MediaAnalysis.cs @@ -56,6 +56,8 @@ private VideoStream ParseVideoStream(FFProbeStream stream) BitsPerRawSample = !string.IsNullOrEmpty(stream.BitsPerRawSample) ? MediaAnalysisUtils.ParseIntInvariant(stream.BitsPerRawSample) : default, CodecName = stream.CodecName, CodecLongName = stream.CodecLongName, + CodecTag = stream.CodecTag, + CodecTagString = stream.CodecTagString, DisplayAspectRatio = MediaAnalysisUtils.ParseRatioInt(stream.DisplayAspectRatio, ':'), Duration = MediaAnalysisUtils.ParseDuration(stream), FrameRate = MediaAnalysisUtils.DivideRatio(MediaAnalysisUtils.ParseRatioDouble(stream.FrameRate, '/')), @@ -77,6 +79,8 @@ private AudioStream ParseAudioStream(FFProbeStream stream) BitRate = !string.IsNullOrEmpty(stream.BitRate) ? MediaAnalysisUtils.ParseIntInvariant(stream.BitRate) : default, CodecName = stream.CodecName, CodecLongName = stream.CodecLongName, + CodecTag = stream.CodecTag, + CodecTagString = stream.CodecTagString, Channels = stream.Channels ?? default, ChannelLayout = stream.ChannelLayout, Duration = MediaAnalysisUtils.ParseDuration(stream), diff --git a/FFMpegCore/FFProbe/MediaStream.cs b/FFMpegCore/FFProbe/MediaStream.cs index 0780c8e..22186c5 100644 --- a/FFMpegCore/FFProbe/MediaStream.cs +++ b/FFMpegCore/FFProbe/MediaStream.cs @@ -10,6 +10,8 @@ public class MediaStream public int Index { get; internal set; } public string CodecName { get; internal set; } = null!; public string CodecLongName { get; internal set; } = null!; + public string CodecTagString { get; set; } = null!; + public string CodecTag { get; set; } = null!; public int BitRate { get; internal set; } public TimeSpan Duration { get; internal set; } public string? Language { get; internal set; } From bc00b6786a744260848f918dceffe1ce0eb2a38e Mon Sep 17 00:00:00 2001 From: Malte Rosenbjerg Date: Tue, 10 Aug 2021 10:38:56 +0200 Subject: [PATCH 9/9] Increase timeout on failing unit test Former-commit-id: 04ebdb1907b9569bc43f7dc9744eb05f760f4cc4 --- FFMpegCore.Test/VideoTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FFMpegCore.Test/VideoTest.cs b/FFMpegCore.Test/VideoTest.cs index 45853ea..27ec79e 100644 --- a/FFMpegCore.Test/VideoTest.cs +++ b/FFMpegCore.Test/VideoTest.cs @@ -655,7 +655,7 @@ public async Task Video_Cancel_CancellationToken_Async_With_Timeout() .WithAudioCodec(AudioCodec.Aac) .WithVideoCodec(VideoCodec.LibX264) .WithSpeedPreset(Speed.VeryFast)) - .CancellableThrough(cts.Token, 5000) + .CancellableThrough(cts.Token, 8000) .ProcessAsynchronously(false); await Task.Delay(300);