|
|
@ -14,11 +14,11 @@ namespace SparkClient.Views.UserControl.ViewportData.Helper; |
|
|
|
|
|
|
|
|
|
|
|
public class VideoHelper |
|
|
|
public class VideoHelper |
|
|
|
{ |
|
|
|
{ |
|
|
|
public static async Task CreateVideoFromPngList(List<PngBitmapEncoder> pngEncoders, string outputPath) |
|
|
|
public static void CreateVideoFromPngList(List<PngBitmapEncoder> pngEncoders, string outputPath) |
|
|
|
{ |
|
|
|
{ |
|
|
|
string tempDirectory = Path.Combine(System.Environment.CurrentDirectory, "PngFrames"); |
|
|
|
string tempDirectory = Path.Combine(System.Environment.CurrentDirectory, "PngFrames"); |
|
|
|
Directory.CreateDirectory(tempDirectory); |
|
|
|
Directory.CreateDirectory(tempDirectory); |
|
|
|
await Task.Delay(1); |
|
|
|
|
|
|
|
try |
|
|
|
try |
|
|
|
{ |
|
|
|
{ |
|
|
|
// Save each PNG frame to a temporary directory |
|
|
|
// Save each PNG frame to a temporary directory |
|
|
@ -73,6 +73,73 @@ public class VideoHelper |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static async Task CreateVideoFromPngListAsync(List<PngBitmapEncoder> pngEncoders, string outputPath) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
string tempDirectory = Path.Combine(Environment.CurrentDirectory, "PngFrames"); |
|
|
|
|
|
|
|
Directory.CreateDirectory(tempDirectory); |
|
|
|
|
|
|
|
await Task.Delay(1).ConfigureAwait(false); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// Save each PNG frame to a temporary directory |
|
|
|
|
|
|
|
for (int i = 0; i < pngEncoders.Count; i++) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
string framePath = Path.Combine(tempDirectory, $"frame_{i:D5}.png"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
await Task.Run(() => |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
Application.Current.Dispatcher.Invoke(() => |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
using (FileStream fs = new FileStream(framePath, FileMode.Create)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
pngEncoders[i].Save(fs); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}).ConfigureAwait(false); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Use FFmpeg to create a video from the PNG frames |
|
|
|
|
|
|
|
string ffmpegPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ffmpeg.exe"); // Assuming ffmpeg.exe is in the same directory as the application |
|
|
|
|
|
|
|
if (!File.Exists(ffmpegPath)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
throw new FileNotFoundException("FFmpeg executable not found.", ffmpegPath); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
string framePattern = Path.Combine(tempDirectory, "frame_%05d.png").Replace("\\", "/"); // Replace backslashes with forward slashes for FFmpeg compatibility |
|
|
|
|
|
|
|
string arguments = $"-framerate 30 -i \"{framePattern}\" -vf \"scale=640:480\" -c:v libx264 -pix_fmt yuv420p \"{outputPath}\""; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var processInfo = new System.Diagnostics.ProcessStartInfo |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
FileName = ffmpegPath, |
|
|
|
|
|
|
|
Arguments = arguments, |
|
|
|
|
|
|
|
RedirectStandardOutput = true, |
|
|
|
|
|
|
|
RedirectStandardError = true, |
|
|
|
|
|
|
|
UseShellExecute = false, |
|
|
|
|
|
|
|
CreateNoWindow = true |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using (var process = System.Diagnostics.Process.Start(processInfo)) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
string error = await process.StandardError.ReadToEndAsync().ConfigureAwait(false); |
|
|
|
|
|
|
|
process.WaitForExit(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (process.ExitCode != 0) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
throw new Exception($"FFmpeg error: {error}"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var dicName = Path.GetDirectoryName(outputPath); |
|
|
|
|
|
|
|
var fileName = Path.GetFileNameWithoutExtension(outputPath); |
|
|
|
|
|
|
|
Microsoft.VisualBasic.FileIO.FileSystem.RenameFile(outputPath, fileName + ".dat"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
finally |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
// Clean up temporary frames |
|
|
|
|
|
|
|
Directory.Delete(tempDirectory, true); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public static void ConvertMp4ToDat(string inputFilePath, string outputFilePath) |
|
|
|
public static void ConvertMp4ToDat(string inputFilePath, string outputFilePath) |
|
|
|
{ |
|
|
|
{ |
|
|
|
string ffmpegPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ffmpeg.exe"); // Assuming ffmpeg.exe is in the same directory as the application |
|
|
|
string ffmpegPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "ffmpeg.exe"); // Assuming ffmpeg.exe is in the same directory as the application |
|
|
|