Skip to content

Commit 6f1a8d7

Browse files
authored
Merge pull request #563 from rosenbjerg/main
V.5.2.0
2 parents f7d54d3 + 37973c3 commit 6f1a8d7

37 files changed

+574
-96
lines changed

.github/workflows/ci.yml

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,52 @@
11
name: CI
22

33
on:
4-
push:
5-
branches:
6-
- master
7-
paths:
8-
- .github/workflows/ci.yml
9-
- FFMpegCore/**
10-
- FFMpegCore.Test/**
114
pull_request:
125
branches:
136
- main
147
- release
158
paths:
16-
- .github/workflows/ci.yml
17-
- FFMpegCore/**
18-
- FFMpegCore.Test/**
9+
- .github/workflows/ci.yml
10+
- Directory.Build.props
11+
- FFMpegCore/**
12+
- FFMpegCore.Test/**
13+
- FFMpegCore.Extensions.SkiaSharp/**
14+
- FFMpegCore.Extensions.System.Drawing.Common/**
1915

2016
jobs:
2117
ci:
2218
runs-on: ${{ matrix.os }}
2319
strategy:
2420
matrix:
25-
os: [windows-latest, ubuntu-latest, macos-latest]
21+
os: [windows-latest, ubuntu-latest, macos-13]
2622
timeout-minutes: 7
2723
steps:
2824

2925
- name: Checkout
30-
uses: actions/checkout@v3
26+
uses: actions/checkout@v4
3127

3228
- name: Prepare .NET
33-
uses: actions/setup-dotnet@v3
29+
uses: actions/setup-dotnet@v4
3430
with:
35-
dotnet-version: '7.0.x'
31+
dotnet-version: '8.0.x'
3632

3733
- name: Lint with dotnet
3834
run: dotnet format FFMpegCore.sln --severity warn --verify-no-changes
3935

4036
- name: Prepare FFMpeg
41-
uses: FedericoCarboni/setup-ffmpeg@v2
37+
uses: FedericoCarboni/setup-ffmpeg@v3
4238
with:
43-
token: ${{ secrets.GITHUB_TOKEN }}
39+
ffmpeg-version: 6.0.1
40+
github-token: ${{ secrets.GITHUB_TOKEN }}
4441

4542
- name: Test with dotnet
4643
run: dotnet test FFMpegCore.sln --collect "XPlat Code Coverage" --logger GitHubActions
4744

4845
- if: matrix.os == 'windows-latest'
4946
name: Upload coverage reports to Codecov
50-
uses: codecov/codecov-action@v3
47+
uses: codecov/codecov-action@v4
5148
with:
49+
fail_ci_if_error: true
5250
directory: FFMpegCore.Test/TestResults
53-
fail_ci_if_error: true
51+
token: ${{ secrets.CODECOV_TOKEN }}
52+
os: windows

.github/workflows/release.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ jobs:
88
runs-on: ubuntu-latest
99
steps:
1010
- name: Checkout
11-
uses: actions/checkout@v3
11+
uses: actions/checkout@v4
1212

1313
- name: Prepare .NET
14-
uses: actions/setup-dotnet@v3
14+
uses: actions/setup-dotnet@v4
1515
with:
16-
dotnet-version: '7.0.x'
16+
dotnet-version: '8.0.x'
1717

1818
- name: Build solution
1919
run: dotnet pack FFMpegCore.sln -c Release

Directory.Build.props

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,14 @@
1313
<PackageProjectUrl>https://github.com/rosenbjerg/FFMpegCore</PackageProjectUrl>
1414
<PackageLicenseExpression>MIT</PackageLicenseExpression>
1515
<NeutralLanguage>en</NeutralLanguage>
16+
17+
<PublishRepositoryUrl>true</PublishRepositoryUrl>
18+
<IncludeSymbols>true</IncludeSymbols>
19+
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
20+
<EmbedUntrackedSources>true</EmbedUntrackedSources>
1621
</PropertyGroup>
22+
23+
<PropertyGroup Condition="'$(GITHUB_ACTIONS)' == 'true'">
24+
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
25+
</PropertyGroup>
1726
</Project>

FFMpegCore.Examples/FFMpegCore.Examples.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFramework>net6.0</TargetFramework>
5+
<TargetFramework>net8.0</TargetFramework>
66
<IsPackable>false</IsPackable>
77
</PropertyGroup>
88

FFMpegCore.Extensions.SkiaSharp/FFMpegCore.Extensions.SkiaSharp.csproj

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
<PropertyGroup>
44
<IsPackable>true</IsPackable>
55
<Description>Image extension for FFMpegCore using SkiaSharp</Description>
6-
<PackageVersion>5.0.0</PackageVersion>
6+
<PackageVersion>5.0.2</PackageVersion>
77
<PackageOutputPath>../nupkg</PackageOutputPath>
8-
<PackageReleaseNotes>
9-
</PackageReleaseNotes>
8+
<PackageReleaseNotes>Bump dependencies</PackageReleaseNotes>
109
<PackageTags>ffmpeg ffprobe convert video audio mediafile resize analyze muxing skiasharp</PackageTags>
1110
<Authors>Malte Rosenbjerg, Vlad Jerca, Max Bagryantsev, Dimitri Vranken</Authors>
11+
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
1212
</PropertyGroup>
1313

1414
<ItemGroup>
15-
<PackageReference Include="SkiaSharp" Version="2.88.3" />
16-
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="2.88.3" />
15+
<PackageReference Include="SkiaSharp" Version="3.116.1" />
16+
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="3.116.1" />
1717
</ItemGroup>
1818

1919
<ItemGroup>

FFMpegCore.Extensions.System.Drawing.Common/FFMpegCore.Extensions.System.Drawing.Common.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,16 @@
33
<PropertyGroup>
44
<IsPackable>true</IsPackable>
55
<Description>Image extension for FFMpegCore using System.Common.Drawing</Description>
6-
<PackageVersion>5.0.0</PackageVersion>
6+
<PackageVersion>5.0.2</PackageVersion>
77
<PackageOutputPath>../nupkg</PackageOutputPath>
8-
<PackageReleaseNotes>
9-
</PackageReleaseNotes>
8+
<PackageReleaseNotes>Bump dependencies</PackageReleaseNotes>
109
<PackageTags>ffmpeg ffprobe convert video audio mediafile resize analyze muxing</PackageTags>
1110
<Authors>Malte Rosenbjerg, Vlad Jerca, Max Bagryantsev</Authors>
11+
<ProduceReferenceAssembly>true</ProduceReferenceAssembly>
1212
</PropertyGroup>
1313

1414
<ItemGroup>
15-
<PackageReference Include="System.Drawing.Common" Version="7.0.0"/>
15+
<PackageReference Include="System.Drawing.Common" Version="9.0.2" />
1616
</ItemGroup>
1717

1818
<ItemGroup>

FFMpegCore.Test/ArgumentBuilderTest.cs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ namespace FFMpegCore.Test
99
public class ArgumentBuilderTest
1010
{
1111
private readonly string[] _concatFiles = { "1.mp4", "2.mp4", "3.mp4", "4.mp4" };
12+
private readonly string[] _multiFiles = { "1.mp3", "2.mp3", "3.mp3", "4.mp3" };
1213

1314
[TestMethod]
1415
public void Builder_BuildString_IO_1()
@@ -571,5 +572,126 @@ public void Builder_BuildString_GifPalette_NullSize_FpsSupplied()
571572
-i "input.mp4" -filter_complex "[{streamIndex}:v] fps=10,split [a][b];[a] palettegen=max_colors=32 [p];[b][p] paletteuse=dither=bayer" "output.gif"
572573
""", str);
573574
}
575+
576+
[TestMethod]
577+
public void Builder_BuildString_MultiOutput()
578+
{
579+
var str = FFMpegArguments.FromFileInput("input.mp4")
580+
.MultiOutput(args => args
581+
.OutputToFile("output.mp4", overwrite: true, args => args.CopyChannel())
582+
.OutputToFile("output.ts", overwrite: false, args => args.CopyChannel().ForceFormat("mpegts"))
583+
.OutputToUrl("http://server/path", options => options.ForceFormat("webm")))
584+
.Arguments;
585+
Assert.AreEqual($"""
586+
-i "input.mp4" -c:a copy -c:v copy "output.mp4" -y -c:a copy -c:v copy -f mpegts "output.ts" -f webm http://server/path
587+
""", str);
588+
}
589+
590+
[TestMethod]
591+
public void Builder_BuildString_MBROutput()
592+
{
593+
var str = FFMpegArguments.FromFileInput("input.mp4")
594+
.MultiOutput(args => args
595+
.OutputToFile("sd.mp4", overwrite: true, args => args.Resize(1200, 720))
596+
.OutputToFile("hd.mp4", overwrite: false, args => args.Resize(1920, 1080)))
597+
.Arguments;
598+
Assert.AreEqual($"""
599+
-i "input.mp4" -s 1200x720 "sd.mp4" -y -s 1920x1080 "hd.mp4"
600+
""", str);
601+
}
602+
603+
[TestMethod]
604+
public void Builder_BuildString_TeeOutput()
605+
{
606+
var str = FFMpegArguments.FromFileInput("input.mp4")
607+
.OutputToTee(args => args
608+
.OutputToFile("output.mp4", overwrite: false, args => args.WithFastStart())
609+
.OutputToUrl("http://server/path", options => options.ForceFormat("mpegts").SelectStream(0, channel: Channel.Video)))
610+
.Arguments;
611+
Assert.AreEqual($"""
612+
-i "input.mp4" -f tee "[movflags=faststart]output.mp4|[f=mpegts:select=\'0:v:0\']http://server/path"
613+
""", str);
614+
}
615+
[TestMethod]
616+
public void Builder_BuildString_MultiInput()
617+
{
618+
var audioStreams = string.Join("", _multiFiles.Select((item, index) => $"[{index}:0]"));
619+
var mixFilter = $"{audioStreams}amix=inputs={_multiFiles.Length}:duration=longest:dropout_transition=1:normalize=0[final]";
620+
var ffmpegArgs = $"-filter_complex \"{mixFilter}\" -map \"[final]\"";
621+
var str = FFMpegArguments
622+
.FromFileInput(_multiFiles)
623+
.OutputToFile("output.mp3", overwrite: true, options => options
624+
.WithCustomArgument(ffmpegArgs)
625+
.WithAudioCodec(AudioCodec.LibMp3Lame) // Set the audio codec to MP3
626+
.WithAudioBitrate(128) // Set the bitrate to 128kbps
627+
.WithAudioSamplingRate(48000) // Set the sample rate to 48kHz
628+
.WithoutMetadata() // Remove metadata
629+
.WithCustomArgument("-ac 2 -write_xing 0 -id3v2_version 0")) // Force 2 Channels
630+
.Arguments;
631+
Assert.AreEqual($"-i \"1.mp3\" -i \"2.mp3\" -i \"3.mp3\" -i \"4.mp3\" -filter_complex \"[0:0][1:0][2:0][3:0]amix=inputs=4:duration=longest:dropout_transition=1:normalize=0[final]\" -map \"[final]\" -c:a libmp3lame -b:a 128k -ar 48000 -map_metadata -1 -ac 2 -write_xing 0 -id3v2_version 0 \"output.mp3\" -y", str);
632+
}
633+
[TestMethod]
634+
public void Pre_VerifyExists_AllFilesExist()
635+
{
636+
// Arrange
637+
var filePaths = new List<string>
638+
{
639+
Path.GetTempFileName(),
640+
Path.GetTempFileName(),
641+
Path.GetTempFileName()
642+
};
643+
var argument = new MultiInputArgument(true, filePaths);
644+
try
645+
{
646+
// Act & Assert
647+
argument.Pre(); // No exception should be thrown
648+
}
649+
finally
650+
{
651+
// Cleanup
652+
foreach (var filePath in filePaths)
653+
{
654+
File.Delete(filePath);
655+
}
656+
}
657+
}
658+
659+
[TestMethod]
660+
public void Pre_VerifyExists_SomeFilesNotExist()
661+
{
662+
// Arrange
663+
var filePaths = new List<string>
664+
{
665+
Path.GetTempFileName(),
666+
"file2.mp4",
667+
"file3.mp4"
668+
};
669+
var argument = new MultiInputArgument(true, filePaths);
670+
try
671+
{
672+
// Act & Assert
673+
Assert.ThrowsException<FileNotFoundException>(() => argument.Pre());
674+
}
675+
finally
676+
{
677+
// Cleanup
678+
File.Delete(filePaths[0]);
679+
}
680+
}
681+
682+
[TestMethod]
683+
public void Pre_VerifyExists_NoFilesExist()
684+
{
685+
// Arrange
686+
var filePaths = new List<string>
687+
{
688+
"file1.mp4",
689+
"file2.mp4",
690+
"file3.mp4"
691+
};
692+
var argument = new MultiInputArgument(true, filePaths);
693+
// Act & Assert
694+
Assert.ThrowsException<FileNotFoundException>(() => argument.Pre());
695+
}
574696
}
575697
}

FFMpegCore.Test/FFMpegCore.Test.csproj

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net6.0</TargetFramework>
4+
<TargetFramework>net8.0</TargetFramework>
55
<IsPackable>false</IsPackable>
66
<Nullable>disable</Nullable>
77
<LangVersion>default</LangVersion>
88
</PropertyGroup>
99

1010
<ItemGroup>
11-
<PackageReference Include="coverlet.collector" Version="3.2.0">
11+
<PackageReference Include="coverlet.collector" Version="6.0.4">
1212
<PrivateAssets>all</PrivateAssets>
1313
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1414
</PackageReference>
15-
<PackageReference Include="FluentAssertions" Version="6.10.0" />
16-
<PackageReference Include="GitHubActionsTestLogger" Version="2.0.1">
15+
<PackageReference Include="FluentAssertions" Version="8.0.1" />
16+
<PackageReference Include="GitHubActionsTestLogger" Version="2.4.1">
1717
<PrivateAssets>all</PrivateAssets>
1818
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1919
</PackageReference>
20-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
21-
<PackageReference Include="MSTest.TestAdapter" Version="3.0.2" />
22-
<PackageReference Include="MSTest.TestFramework" Version="3.0.2" />
23-
<PackageReference Include="SkiaSharp" Version="2.88.3" />
20+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
21+
<PackageReference Include="MSTest.TestAdapter" Version="3.8.0" />
22+
<PackageReference Include="MSTest.TestFramework" Version="3.8.0" />
23+
<PackageReference Include="SkiaSharp" Version="3.116.1" />
2424
</ItemGroup>
2525

2626
<ItemGroup>
@@ -51,9 +51,15 @@
5151
<None Update="Resources\input_3sec_rotation_90deg.mp4">
5252
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
5353
</None>
54+
<None Update="Resources\input_3sec_rotation_negative_90deg.mp4">
55+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
56+
</None>
5457
<None Update="Resources\input_audio_only_10sec.mp4">
5558
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
5659
</None>
60+
<None Update="Resources\input_hdr.mov">
61+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
62+
</None>
5763
<None Update="Resources\input_video_only_3sec.mp4">
5864
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
5965
</None>

0 commit comments

Comments
 (0)