129 lines
2.7 KiB
C#
129 lines
2.7 KiB
C#
|
|
#if TOOLS
|
||
|
|
using Godot;
|
||
|
|
using Rokojori;
|
||
|
|
using System.Diagnostics;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.Threading.Tasks;
|
||
|
|
using System;
|
||
|
|
|
||
|
|
namespace Rokojori.Tools;
|
||
|
|
|
||
|
|
|
||
|
|
public class FFmpegResponse
|
||
|
|
{
|
||
|
|
public int exitCode;
|
||
|
|
public string rawResponse;
|
||
|
|
}
|
||
|
|
|
||
|
|
public class FFmpeg
|
||
|
|
{
|
||
|
|
public static async Task<FFmpegResponse> Run( List<string> arguments, string workingDirectory = null, string ffmpegPath = "ffmpeg" )
|
||
|
|
{
|
||
|
|
var response = new FFmpegResponse();
|
||
|
|
|
||
|
|
var joinedArgs = arguments.Join( " ");
|
||
|
|
|
||
|
|
RJLog.Log( "FFmpeg at", ffmpegPath, ">>", joinedArgs );
|
||
|
|
|
||
|
|
var process = new Process
|
||
|
|
{
|
||
|
|
StartInfo = new ProcessStartInfo
|
||
|
|
{
|
||
|
|
FileName = ffmpegPath,
|
||
|
|
Arguments = joinedArgs,
|
||
|
|
RedirectStandardOutput = true,
|
||
|
|
RedirectStandardError = true,
|
||
|
|
UseShellExecute = false,
|
||
|
|
CreateNoWindow = true
|
||
|
|
}
|
||
|
|
|
||
|
|
};
|
||
|
|
|
||
|
|
if ( workingDirectory != null )
|
||
|
|
{
|
||
|
|
process.StartInfo.WorkingDirectory = workingDirectory;
|
||
|
|
}
|
||
|
|
|
||
|
|
process.Start();
|
||
|
|
|
||
|
|
var outputResult = new List<string>();
|
||
|
|
var errorResult = new List<string>();
|
||
|
|
|
||
|
|
process.OutputDataReceived += (sender, e) =>
|
||
|
|
{
|
||
|
|
if ( e.Data == null )
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
RJLog.Log( e.Data );
|
||
|
|
outputResult.Add( e.Data );
|
||
|
|
};
|
||
|
|
|
||
|
|
process.ErrorDataReceived += (sender, e) =>
|
||
|
|
{
|
||
|
|
if ( e.Data == null )
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
RJLog.Error( e.Data );
|
||
|
|
errorResult.Add( e.Data );
|
||
|
|
};
|
||
|
|
|
||
|
|
process.BeginOutputReadLine();
|
||
|
|
process.BeginErrorReadLine();
|
||
|
|
|
||
|
|
|
||
|
|
await process.WaitForExitAsync();
|
||
|
|
|
||
|
|
|
||
|
|
response.exitCode = process.ExitCode;
|
||
|
|
|
||
|
|
if ( process.ExitCode == 0 )
|
||
|
|
{
|
||
|
|
response.rawResponse = outputResult.Join( "" );
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
response.rawResponse = errorResult.Join( "" );
|
||
|
|
}
|
||
|
|
|
||
|
|
return response;
|
||
|
|
}
|
||
|
|
|
||
|
|
public static Task<FFmpegResponse> Convert_MP4_to_OGV(
|
||
|
|
string path, string ffmpegPath = "ffmpeg",
|
||
|
|
FFmpegQuality videoQuality = FFmpegQuality._8_Good,
|
||
|
|
FFmpegQuality audioQuality = FFmpegQuality._8_Good,
|
||
|
|
int keyFrames = 64,
|
||
|
|
int w = -1, int h = -1
|
||
|
|
)
|
||
|
|
{
|
||
|
|
// ffmpeg -i input.mp4 -vf "scale=-1:720" -q:v 6 -q:a 6 -g:v 64 output.ogv
|
||
|
|
|
||
|
|
var args = new List<string>();
|
||
|
|
|
||
|
|
args.Add( "-i " + path );
|
||
|
|
|
||
|
|
if ( ! ( w == -1 && h == -1 ) )
|
||
|
|
{
|
||
|
|
args.Add( "-vf " + "\"scale=" + w + ":" + h + "\"" );
|
||
|
|
}
|
||
|
|
|
||
|
|
args.Add( "-q:v " + FFmpegQualityTool.ToInt( videoQuality ) );
|
||
|
|
args.Add( "-q:a " + FFmpegQualityTool.ToInt( audioQuality ) );
|
||
|
|
args.Add( "-g:v " + keyFrames );
|
||
|
|
|
||
|
|
var filePath = FilePath.Absolute( path );
|
||
|
|
var outputPath = filePath.WithExtension( ".ogv" );
|
||
|
|
args.Add( outputPath.absolutePath );
|
||
|
|
|
||
|
|
|
||
|
|
return Run( args, null, ffmpegPath );
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
|
||
|
|
#endif
|