This commit is contained in:
xiang 2025-01-13 23:15:37 +08:00
parent ec0ac61133
commit baf1592fc5
3 changed files with 92 additions and 17 deletions

View File

@ -22,9 +22,22 @@ namespace VideoConcat.Models
private string _folderPath = ""; private string _folderPath = "";
private string _auditImagePath = ""; private string _auditImagePath = "";
private bool _canStart = false; private bool _canStart = false;
private bool _isStart = false;
private ObservableCollection<FolderInfo> _FolderInfos = []; private ObservableCollection<FolderInfo> _FolderInfos = [];
private ObservableCollection<ConcatVideo> _concatVideos = [];
public bool IsStart
{
get => _isStart;
set
{
_isStart = value;
OnPropertyChanged();
SetCanStart();
}
}
public int Num public int Num
{ {
get => _num; get => _num;
@ -63,6 +76,17 @@ namespace VideoConcat.Models
public List<string> VideoPaths { set; get; } public List<string> VideoPaths { set; get; }
} }
public struct ConcatVideo
{
public string FileName { set; get; }
public int Size { set; get; }
public int Seconds { set; get; }
public int Status { set; get; }
public int Progress { set; get; }
}
public ObservableCollection<FolderInfo> FolderInfos public ObservableCollection<FolderInfo> FolderInfos
{ {
get { return _FolderInfos; } get { return _FolderInfos; }
@ -82,6 +106,17 @@ namespace VideoConcat.Models
} }
} }
public ObservableCollection<ConcatVideo> ConcatVideos
{
get { return _concatVideos; }
set
{
_concatVideos = value;
OnPropertyChanged();
}
}
public string FolderPath public string FolderPath
{ {
get { return _folderPath; } get { return _folderPath; }
@ -143,7 +178,7 @@ namespace VideoConcat.Models
public void SetCanStart() public void SetCanStart()
{ {
if (Num > 0 && Num <= MaxNum) if (Num > 0 && Num <= MaxNum && IsStart == false)
{ {
CanStart = true; CanStart = true;
} }

View File

@ -5,7 +5,6 @@ using VideoConcat.Common.Tools;
using System.IO; using System.IO;
using Microsoft.Expression.Drawing.Core; using Microsoft.Expression.Drawing.Core;
using FFMpegCore; using FFMpegCore;
using FFMpegCore.Arguments;
namespace VideoConcat.ViewModels namespace VideoConcat.ViewModels
{ {
@ -28,6 +27,7 @@ namespace VideoConcat.ViewModels
VideoModel = new VideoModel VideoModel = new VideoModel
{ {
FolderInfos = [], FolderInfos = [],
ConcatVideos = [],
MaxNum = 0, MaxNum = 0,
CanStart = false, CanStart = false,
BtnOpenFolderCommand = new Command() BtnOpenFolderCommand = new Command()
@ -77,6 +77,8 @@ namespace VideoConcat.ViewModels
{ {
Task.Run(action: () => Task.Run(action: () =>
{ {
MessageBox.Show("开始合并视频");
VideoModel.IsStart = true;
//开始时间 //开始时间
DateTime startTime = DateTime.Now; DateTime startTime = DateTime.Now;
@ -116,17 +118,20 @@ namespace VideoConcat.ViewModels
{ {
taskList.Add(Task.Run(() => taskList.Add(Task.Run(() =>
{ {
try try
{ {
if (Directory.Exists($"{VideoModel.FolderPath}/output") == false) if (Directory.Exists($"{VideoModel.FolderPath}\\output") == false)
{ {
Directory.CreateDirectory($"{VideoModel.FolderPath}/output"); Directory.CreateDirectory($"{VideoModel.FolderPath}\\output");
} }
string _outPutName = $"{VideoModel.FolderPath}/output/{random.Next(100000, 999999)}.mp4"; string _outPutName = $"{VideoModel.FolderPath}\\output\\{DateTime.Now:yyyyMMddHHmmss}{random.Next(100000, 999999)}.mp4";
string _outPutNameImg = $"{VideoModel.FolderPath}\\output\\{DateTime.Now:yyyyMMddHHmmss}{random.Next(100000, 999999)}.mp4";
bool _isSuccess = FFMpeg.Join(_outPutName, [.. combination]); bool _isSuccess = FFMpeg.Join(_outPutName, [.. combination]);
if (_isSuccess && VideoModel.AuditImagePath != "") if (_isSuccess && VideoModel.AuditImagePath != "")
{ {
// 使用 FFMpegCore 执行添加图片到视频的操作 // 使用 FFMpegCore 执行添加图片到视频的操作
@ -134,9 +139,9 @@ namespace VideoConcat.ViewModels
{ {
// 配置 FFmpeg 二进制文件位置(如果 FFmpeg 不在系统路径中) // 配置 FFmpeg 二进制文件位置(如果 FFmpeg 不在系统路径中)
// GlobalFFOptions.Configure(new FFOptions { BinaryFolder = "path/to/ffmpeg/bin" }); // GlobalFFOptions.Configure(new FFOptions { BinaryFolder = "path/to/ffmpeg/bin" });
string _outPutNameImg = $"{VideoModel.FolderPath}/output/{random.Next(100000, 999999)}.mp4";
string _customArg = "-filter_complex \"[0:v][1:v] overlay=0:H-h\" ";
// 使用 FFMpegArguments 构建命令 // 使用 FFMpegArguments 构建命令
bool _isCoverSuccess = FFMpegArguments bool _isCoverSuccess = FFMpegArguments
.FromFileInput(_outPutName) .FromFileInput(_outPutName)
@ -144,7 +149,7 @@ namespace VideoConcat.ViewModels
.OutputToFile( .OutputToFile(
_outPutNameImg, _outPutNameImg,
true, true,
options => options.WithCustomArgument("-filter_complex \"[0:v][1:v] overlay=0:0\" ") options => options.WithCustomArgument(_customArg)
) )
.ProcessSynchronously(); .ProcessSynchronously();
@ -175,6 +180,8 @@ namespace VideoConcat.ViewModels
//结束时间 //结束时间
DateTime endTime = DateTime.Now; DateTime endTime = DateTime.Now;
LogUtils.Info($"所有视频拼接完成,用时{(endTime - startTime).TotalSeconds}秒"); LogUtils.Info($"所有视频拼接完成,用时{(endTime - startTime).TotalSeconds}秒");
VideoModel.IsStart = false;
MessageBox.Show("所有视频拼接完成");
}); });
}); });
} }

View File

@ -40,7 +40,7 @@
<TextBox Grid.Column="1" Width="500" Name="FoldPath" Text="{Binding VideoModel.FolderPath,Mode=TwoWay}" IsReadOnly="True" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" FontSize="16" VerticalContentAlignment="Center" materialDesign:HintAssist.Hint="选择视频主文件夹"/> <TextBox Grid.Column="1" Width="500" Name="FoldPath" Text="{Binding VideoModel.FolderPath,Mode=TwoWay}" IsReadOnly="True" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" FontSize="16" VerticalContentAlignment="Center" materialDesign:HintAssist.Hint="选择视频主文件夹"/>
<Button Grid.Column="2" Width="100" Content="选 择" FontSize="16" Command="{Binding VideoModel.BtnOpenFolderCommand}" Background="#40568D" BorderBrush="#7F7F7F" BorderThickness="2" ToolTip="选择含有视频的主文件夹" Style="{StaticResource MaterialDesignRaisedButton}" Margin="5,2" /> <Button Grid.Column="2" Width="100" Content="选 择" FontSize="16" Command="{Binding VideoModel.BtnOpenFolderCommand}" Background="#40568D" BorderBrush="#7F7F7F" BorderThickness="2" ToolTip="选择含有视频的主文件夹" Style="{StaticResource MaterialDesignRaisedButton}" Margin="5,2" />
<Label Grid.Row="1" Width="100" VerticalAlignment="Center" FontSize="16" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" Style="{StaticResource MaterialDesignLabel}" VerticalContentAlignment="Stretch">选择广审:</Label> <Label Grid.Row="1" Width="100" VerticalAlignment="Center" FontSize="16" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" Style="{StaticResource MaterialDesignLabel}" VerticalContentAlignment="Stretch">选择广审:</Label>
<TextBox Grid.Row="1" Width="500" Grid.Column="1" Text="{Binding VideoModel.AuditImagePath,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" FontSize="16" VerticalContentAlignment="Center" ToolTip="请选择" materialDesign:HintAssist.Hint="请选择"/> <TextBox Grid.Row="1" Width="500" Grid.Column="1" Text="{Binding VideoModel.AuditImagePath,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" FontSize="16" VerticalContentAlignment="Center" ToolTip="请选择" materialDesign:HintAssist.Hint="请选择"/>
<Button Grid.Row="1" Width="100" Grid.Column="2" Content="选择文件" FontSize="16" Command="{Binding VideoModel.BtnChooseAuditImageCommand}" Background="#E54858" BorderBrush="#7F7F7F" BorderThickness="2" ToolTip="选择广审" Style="{StaticResource MaterialDesignRaisedButton}" Margin="5,2"/> <Button Grid.Row="1" Width="100" Grid.Column="2" Content="选择文件" FontSize="16" Command="{Binding VideoModel.BtnChooseAuditImageCommand}" Background="#E54858" BorderBrush="#7F7F7F" BorderThickness="2" ToolTip="选择广审" Style="{StaticResource MaterialDesignRaisedButton}" Margin="5,2"/>
<Label Grid.Row="1" Width="100" VerticalAlignment="Center" FontSize="16" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" Style="{StaticResource MaterialDesignLabel}" VerticalContentAlignment="Stretch">视频个数:</Label> <Label Grid.Row="1" Width="100" VerticalAlignment="Center" FontSize="16" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" Style="{StaticResource MaterialDesignLabel}" VerticalContentAlignment="Stretch">视频个数:</Label>
<TextBox Grid.Row="1" Width="500" Grid.Column="1" Text="{Binding VideoModel.Num,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" FontSize="16" VerticalContentAlignment="Center" ToolTip="请输入合成视频个数" materialDesign:HintAssist.Hint="请输入拼接视频数目"/> <TextBox Grid.Row="1" Width="500" Grid.Column="1" Text="{Binding VideoModel.Num,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" FontSize="16" VerticalContentAlignment="Center" ToolTip="请输入合成视频个数" materialDesign:HintAssist.Hint="请输入拼接视频数目"/>
@ -49,16 +49,49 @@
<!--</Grid>--> <!--</Grid>-->
</WrapPanel> </WrapPanel>
</StackPanel> </StackPanel>
<StackPanel > <StackPanel Margin="0,5,0,0">
<DataGrid ItemsSource="{Binding VideoModel.FolderInfos}" AutoGenerateColumns="False"> <Label>文件信息:</Label>
<DataGrid.Columns >
<DataGridTextColumn Header="子文件夹" Binding="{Binding DirectoryInfo.Name,Mode=OneWay}" IsReadOnly="True" CanUserSort="False" CanUserReorder="False"/>
<DataGridTextColumn Header="视频个数" Binding="{Binding Num}" IsReadOnly="True" CanUserReorder="False" CanUserSort="False"/>
</DataGrid.Columns>
</DataGrid>
</StackPanel> </StackPanel>
<StackPanel> <StackPanel MinHeight="100">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0">
</DockPanel>
<DataGrid Grid.Row="1" ItemsSource="{Binding VideoModel.FolderInfos}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" >
<DataGrid.Columns>
<DataGridTextColumn Header="文件夹" Binding="{Binding DirectoryInfo.Name,Mode=OneWay}" Width="*"></DataGridTextColumn>
<DataGridTextColumn Header="视频数量" Binding="{Binding Num,Mode=OneWay}" Width="*"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</StackPanel>
<StackPanel Margin="0,20,0,0">
<Label>视频合成进度:</Label>
</StackPanel>
<StackPanel MinHeight="200">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0">
</DockPanel>
<DataGrid Grid.Row="1" ItemsSource="{Binding VideoModel.ConcatVideos}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" >
<DataGrid.Columns>
<DataGridTextColumn Header="文件名" Binding="{Binding FileName}" Width="*"></DataGridTextColumn>
<DataGridTextColumn Header="大小" Binding="{Binding Size}" Width="*"></DataGridTextColumn>
<DataGridTextColumn Header="时长" Binding="{Binding Seconds}" Width="*"></DataGridTextColumn>
<DataGridTextColumn Header="进度" Binding="{Binding Progress}" Width="*"></DataGridTextColumn>
<DataGridTextColumn Header="状态" Binding="{Binding Status}" Width="*"></DataGridTextColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</StackPanel> </StackPanel>
</StackPanel> </StackPanel>
</Grid> </Grid>