diff --git a/Models/ExtractWindowModel.cs b/Models/ExtractWindowModel.cs
index 756114f..9d42ec3 100644
--- a/Models/ExtractWindowModel.cs
+++ b/Models/ExtractWindowModel.cs
@@ -26,7 +26,8 @@ namespace VideoConcat.Models
private string _folderPath = "";
private string _helpInfo = "";
- private bool _canStart = false;
+ private bool _canExtractFrame = false;
+ private bool _canModify = false;
private bool _isCanOperate = false;
private bool _isStart = false;
private string[] _videos = [];
@@ -102,18 +103,28 @@ namespace VideoConcat.Models
}
}
- public bool CanStart
+ public bool CanExtractFrame
{
- get { return _canStart; }
+ get { return _canExtractFrame; }
set
{
- _canStart = value;
- OnPropertyChanged(nameof(CanStart));
+ _canExtractFrame = value;
+ OnPropertyChanged(nameof(CanExtractFrame));
+ }
+ }
+ public bool CanModify
+ {
+ get { return _canModify; }
+ set
+ {
+ _canModify = value;
+ OnPropertyChanged(nameof(CanModify));
}
}
public ICommand? BtnOpenFolderCommand { get; set; }
public ICommand? BtnStartVideoConcatCommand { get; set; }
+ public ICommand? BtnStartVideoModifyCommand { get; set; }
public ICommand? BtnChooseAuditImageCommand { get; set; }
public event PropertyChangedEventHandler? PropertyChanged;
@@ -132,13 +143,14 @@ namespace VideoConcat.Models
public void SetCanStart()
{
+ CanExtractFrame = false;
if (videos.Length > 0)
{
- CanStart = true;
+ CanModify = true;
}
else
{
- CanStart = false;
+ CanModify = false;
}
}
}
diff --git a/Services/Video/VideoProcess.cs b/Services/Video/VideoProcess.cs
index 29a1c50..5cf42d8 100644
--- a/Services/Video/VideoProcess.cs
+++ b/Services/Video/VideoProcess.cs
@@ -75,14 +75,14 @@ namespace VideoConcat.Services.Video
int totalFram = (int)(totalDuration * frameRate);
var random = new Random();
- var randomFrame = random.Next(1, (int)totalDuration);
-
+ var randomFrame = random.Next(20, (int)totalDuration);
+ //return RemoveVideoFrame(inputPath, outputPath, randomFrame);
string videoPart1 = Path.Combine(tempDir, $"{Guid.NewGuid()}.mp4");
string videoPart2 = Path.Combine(tempDir, $"{Guid.NewGuid()}.mp4");
- bool hasSubVideo1 = SubVideo(inputPath, videoPart1, 0, randomFrame-0.016);
+ bool hasSubVideo1 = SubVideo(inputPath, videoPart1, 0, randomFrame - 0.016);
bool hasSubVideo2 = SubVideo(inputPath, videoPart2, randomFrame, totalDuration);
if (!hasSubVideo1 || !hasSubVideo2)
{
@@ -116,6 +116,27 @@ namespace VideoConcat.Services.Video
}
}
+
+
+
+ ///
+ /// 通过修改视频元数据(添加注释)改变MD5
+ ///
+ public static bool ModifyByMetadata(string inputPath, string outputPath, string comment = "JSY")
+ {
+ // 添加或修改视频元数据中的注释信息
+ return FFMpegArguments
+ .FromFileInput(inputPath)
+ .OutputToFile(outputPath, true, options => options
+ //.WithVideoCodec("copy") // 直接复制视频流,不重新编码
+ //.WithAudioCodec("copy") // 直接复制音频流
+ .CopyChannel()
+ .WithCustomArgument($"-metadata comment=\"{comment}_{Guid.NewGuid()}\"") // 添加唯一注释
+ )
+ .ProcessSynchronously();
+ }
+
+
public static bool SubVideo(string inputPath, string outputPath, Double startSec, Double endSec)
{
return FFMpegArguments
@@ -138,7 +159,7 @@ namespace VideoConcat.Services.Video
return FFMpeg.Join(outPutPath, videoParts);
}
- public async Task ProcessVideo(string inputPath,string outputPath, string tempDir)
+ public async Task ProcessVideo(string inputPath, string outputPath, string tempDir)
{
// 1. 获取视频信息
IMediaAnalysis mediaInfo = await FFProbe.AnalyseAsync(inputPath);
@@ -220,5 +241,23 @@ namespace VideoConcat.Services.Video
opt.WithCustomArgument("-c copy -shortest -y"))
.ProcessAsynchronously();
}
+
+
+ public static bool RemoveVideoFrame(string inputPath, string outputPath, int frameToRemove)
+ {
+ // 使用FFMpegArguments构建转换流程
+ return FFMpegArguments
+ .FromFileInput(inputPath)
+ .OutputToFile(outputPath, true, options => options
+ // 使用select过滤器排除指定帧(帧序号从0开始)
+ .WithCustomArgument($"select=not(eq(n\\,{frameToRemove}))")
+
+ // $"not(eq(n\\,{frameToRemove}))"); // 注意:在C#中需要转义反斜杠
+ //// 保持其他编码参数
+ .WithVideoCodec("libx264")
+ .WithAudioCodec("copy") // 如果不需要处理音频,直接复制
+ )
+ .ProcessSynchronously();
+ }
}
}
diff --git a/ViewModels/ExtractWindowViewModel.cs b/ViewModels/ExtractWindowViewModel.cs
index e44fac8..3563e88 100644
--- a/ViewModels/ExtractWindowViewModel.cs
+++ b/ViewModels/ExtractWindowViewModel.cs
@@ -35,7 +35,8 @@ namespace VideoConcat.ViewModels
{
ExtractWindowModel = new ExtractWindowModel
{
- CanStart = false,
+ CanExtractFrame = false,
+ CanModify = false,
IsStart = false,
IsCanOperate = true,
@@ -76,7 +77,7 @@ namespace VideoConcat.ViewModels
var remover = new VideoProcess();
// 删除4秒处的帧(需根据实际帧位置调整)
string _tmpPath = Path.GetDirectoryName(video) ?? "";
- string _tmpFileName = $"{(new Random()).Next(10000,99999)}{Path.GetFileName(video)}";
+ string _tmpFileName = $"{(new Random()).Next(10000, 99999)}{Path.GetFileName(video)}";
string outPath = Path.Combine(_tmpPath, "out");
if (!Path.Exists(outPath))
@@ -94,6 +95,53 @@ namespace VideoConcat.ViewModels
_tasks.Add(_task);
});
+ Task.WhenAll(_tasks).ContinueWith((task) =>
+ {
+ ExtractWindowModel.HelpInfo = "全部完成!";
+ });
+ }
+ },
+
+ BtnStartVideoModifyCommand = new Command()
+ {
+ DoExcue = obj =>
+ {
+ ExtractWindowModel.HelpInfo = "";
+
+
+ SemaphoreSlim semaphore = new(10); // Limit to 3 threads
+
+ List _tasks = [];
+
+ ExtractWindowModel.videos.ForEach(async (video) =>
+ {
+ await semaphore.WaitAsync(); // Wait when more than 3 threads are running
+ var _task = Task.Run(async () =>
+ {
+ try
+ {
+ // 实例化并调用
+ var remover = new VideoProcess();
+ // 删除4秒处的帧(需根据实际帧位置调整)
+ string _tmpPath = Path.GetDirectoryName(video) ?? "";
+ string _tmpFileName = $"{(new Random()).Next(10000, 99999)}{Path.GetFileName(video)}";
+
+ string outPath = Path.Combine(_tmpPath, "out");
+ if (!Path.Exists(outPath))
+ {
+ Directory.CreateDirectory(outPath);
+ }
+
+ VideoProcess.ModifyByMetadata(video, $"{_tmpPath}\\out\\modify{_tmpFileName}");
+ }
+ finally
+ {
+ semaphore.Release(); // Work is done, signal to semaphore that more work is possible
+ }
+ });
+ _tasks.Add(_task);
+ });
+
Task.WhenAll(_tasks).ContinueWith((task) =>
{
ExtractWindowModel.HelpInfo = "全部完成!";
diff --git a/Views/ExtractWindow.xaml b/Views/ExtractWindow.xaml
index 484b64d..0c48535 100644
--- a/Views/ExtractWindow.xaml
+++ b/Views/ExtractWindow.xaml
@@ -29,9 +29,10 @@
-
-
-
+
+
+
+
diff --git a/Views/MainWindow.xaml b/Views/MainWindow.xaml
index 25c926c..e38fd26 100644
--- a/Views/MainWindow.xaml
+++ b/Views/MainWindow.xaml
@@ -11,7 +11,7 @@
mc:Ignorable="d"
Width="1100" Height="800" WindowStartupLocation="CenterScreen"
- ResizeMode="NoResize"
+ ResizeMode="CanMinimize"
Title="工具">