Skip to content

Commit

Permalink
Moving to Xabe.Ffmpeg as ffmpeg wrapper.
Browse files Browse the repository at this point in the history
  • Loading branch information
dasatomic committed Jun 30, 2021
1 parent e9d3438 commit a540710
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 58 deletions.
69 changes: 12 additions & 57 deletions VideoProcessing/FfmpegVideoChunker.cs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
using PageManager;
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Xabe.FFmpeg;

namespace VideoProcessing
{
public class FfmpegVideoChunker
{
private const string ffArgsFormat = "-hide_banner -i {0} -c copy -map 0 -segment_time {1} -f segment {2}";
private readonly string tempDestination;
private readonly IVideoProcessingInstrumentationInterface logger;

Expand All @@ -19,38 +18,6 @@ public FfmpegVideoChunker(string tempDestination, IVideoProcessingInstrumentatio
this.logger = logger;
}

private ProcessStartInfo CreateProcessStartInfo(string ffmpegArgs)
{
ProcessStartInfo pci = new ProcessStartInfo();
if (OperatingSystem.IsWindows())
{
FileInfo dataRoot = new FileInfo(typeof(FfmpegProbeWrapper).Assembly.Location);
string assemblyFolderPath = dataRoot.Directory.FullName;
pci.FileName = Path.Combine(assemblyFolderPath, "ffmpeg/ffmpeg.exe");
pci.Arguments = ffmpegArgs;

}
else if (OperatingSystem.IsLinux())
{
// use bash + ffmpeg.
// This means that ffmpeg needs to be installed.
// TODO: Error handling if ffmpeg isn't installed/bash is not used etc.
// For now this is only to pass basic test on Ubuntu when everything is correctly preinstalled.
pci.FileName = "/bin/bash";
pci.Arguments = $"-c \"ffmpeg {ffmpegArgs}\"";
}
else
{
throw new NotImplementedException("Os currently not supported");
}

pci.UseShellExecute = false;
pci.RedirectStandardOutput = true;
pci.RedirectStandardError = true;

return pci;
}

public async Task<string[]> Execute(string fileName, TimeSpan span, ITransaction tran, CancellationToken token)
{
FileInfo fi = new FileInfo(fileName);
Expand All @@ -61,29 +28,17 @@ public async Task<string[]> Execute(string fileName, TimeSpan span, ITransaction
tran.RegisterTempFolder(tempDir);
string outputDestination = Path.Combine(destinationDir, outputFileName);

string arguments = string.Format(ffArgsFormat, fileName, span, outputDestination);

ProcessStartInfo pci = CreateProcessStartInfo(arguments);
using (Process proc = Process.Start(pci))
{
this.logger.LogDebug($"Running Process name {proc.ProcessName} with id {proc.Id}.");
await proc.WaitForExitAsync(token);
this.logger.LogDebug($"Process Id {proc.Id} exited with exit code {proc.ExitCode}.");

if (!proc.StandardOutput.EndOfStream)
{
string output = await proc.StandardOutput.ReadToEndAsync();
output = $"Process id {proc.Id} standard output: " + Environment.NewLine + output;
this.logger.LogDebug(output);
}

if (!proc.StandardError.EndOfStream)
{
string output = await proc.StandardError.ReadToEndAsync();
output = $"Process id {proc.Id} standard output: " + Environment.NewLine + output;
this.logger.LogDebug(output);
}
}
FFmpeg.SetExecutablesPath(OperatingSystem.GetFfmpegExecPath());
var conversionResult = await FFmpeg.Conversions.New()
.AddParameter($"-i {fileName}")
.AddParameter($"-c copy")
.AddParameter("-map 0")
.AddParameter($"-segment_time {span.TotalSeconds.ToString()}")
.AddParameter("-f segment")
.SetOutput(outputDestination)
.Start();

this.logger.LogDebug($"Video chunker took {conversionResult.Duration.TotalSeconds}s");

return Directory.GetFiles(destinationDir);
}
Expand Down
63 changes: 62 additions & 1 deletion VideoProcessing/ProcessRunnerExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Diagnostics;
using System;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -36,5 +38,64 @@ public static class OperatingSystem
public static bool IsMacOS() => RuntimeInformation.IsOSPlatform(OSPlatform.OSX);

public static bool IsLinux() => RuntimeInformation.IsOSPlatform(OSPlatform.Linux);

public static string GetFfmpegExecPath()
{
if (IsWindows())
{
FileInfo dataRoot = new FileInfo(typeof(FfmpegProbeWrapper).Assembly.Location);
string assemblyFolderPath = dataRoot.Directory.FullName;
return Path.Combine(assemblyFolderPath, "ffmpeg");
}
else if (IsLinux() || IsMacOS())
{
return "/usr/bin/";
}
else
{
throw new NotImplementedException("Os currently not supported");
}
}

public static string GetFfmpegPath()
{
if (IsWindows())
{
FileInfo dataRoot = new FileInfo(typeof(FfmpegProbeWrapper).Assembly.Location);
string assemblyFolderPath = dataRoot.Directory.FullName;
return Path.Combine(assemblyFolderPath, "ffmpeg/ffmpeg.exe");

}
else if (IsLinux() || IsMacOS())
{
// This means that ffmpeg needs to be installed.
// TODO: Error handling if ffmpeg isn't installed/bash is not used etc.
// For now this is only to pass basic test on Ubuntu when everything is correctly preinstalled.
return "/usr/bin/ffmpeg";
}
else
{
throw new NotImplementedException("Os currently not supported");
}
}

public static string GetFfProbePath()
{
if (IsWindows())
{
FileInfo dataRoot = new FileInfo(typeof(FfmpegProbeWrapper).Assembly.Location);
string assemblyFolderPath = dataRoot.Directory.FullName;
return Path.Combine(assemblyFolderPath, "ffmpeg/ffprobe.exe");

}
else if (IsLinux() || IsMacOS())
{
return "/usr/bin/ffprobe";
}
else
{
throw new NotImplementedException("Os currently not supported");
}
}
}
}
1 change: 1 addition & 0 deletions VideoProcessing/VideoProcessing.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Xabe.FFmpeg" Version="5.0.2" />
</ItemGroup>

<ItemGroup>
Expand Down

0 comments on commit a540710

Please sign in to comment.