This commit is contained in:
xiangbing 2025-01-18 23:44:06 +08:00
parent 6fa231b010
commit 637e5b2969
3 changed files with 74 additions and 20 deletions

View File

@ -10,6 +10,7 @@ using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Threading;
using System.Xml.Linq; using System.Xml.Linq;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Header; using static System.Windows.Forms.VisualStyles.VisualStyleElement.Header;
@ -25,7 +26,9 @@ namespace VideoConcat.Models
private bool _isStart = false; private bool _isStart = false;
private ObservableCollection<FolderInfo> _FolderInfos = []; private ObservableCollection<FolderInfo> _FolderInfos = [];
private ObservableCollection<ConcatVideo> _concatVideos = []; private ObservableCollection<ConcatVideo> _concatVideos = [];
private Dispatcher _dispatcher;
public static int Index= 0;
public bool IsStart public bool IsStart
{ {
@ -38,6 +41,15 @@ namespace VideoConcat.Models
} }
} }
public Dispatcher Dispatcher
{
get => _dispatcher;
set
{
_dispatcher = value;
}
}
public int Num public int Num
{ {
get => _num; get => _num;
@ -77,14 +89,14 @@ namespace VideoConcat.Models
} }
public struct ConcatVideo public class ConcatVideo
{ {
public string FileName { set; get; } public int Index { set; get; }
public string FileName { set; get; } = "";
public int Size { set; get; } public int Size { set; get; }
public int Seconds { set; get; } public double Seconds { set; get; }
public int Status { set; get; } public int Status { set; get; }
public int Progress { set; get; } public int Progress { set; get; }
} }
public ObservableCollection<FolderInfo> FolderInfos public ObservableCollection<FolderInfo> FolderInfos
@ -112,7 +124,16 @@ namespace VideoConcat.Models
get { return _concatVideos; } get { return _concatVideos; }
set set
{ {
if (_concatVideos != null)
{
_concatVideos.CollectionChanged -= ItemList_CollectionChanged;
}
_concatVideos = value; _concatVideos = value;
if (_concatVideos != null)
{
_concatVideos.CollectionChanged += ItemList_CollectionChanged;
}
OnPropertyChanged(); OnPropertyChanged();
} }
} }
@ -187,5 +208,11 @@ namespace VideoConcat.Models
CanStart = false; CanStart = false;
} }
} }
public VideoModel()
{
ConcatVideos = [];
_dispatcher = Dispatcher.CurrentDispatcher;
}
} }
} }

View File

@ -6,12 +6,17 @@ using System.IO;
using Microsoft.Expression.Drawing.Core; using Microsoft.Expression.Drawing.Core;
using FFMpegCore; using FFMpegCore;
using FFMpegCore.Enums; using FFMpegCore.Enums;
using static VideoConcat.Models.VideoModel;
using System.Windows.Threading;
namespace VideoConcat.ViewModels namespace VideoConcat.ViewModels
{ {
public class VideoViewModel public class VideoViewModel
{ {
private VideoModel _videoModel; private VideoModel _videoModel;
public List<ConcatVideo> ConcatVideos { get; set; } = [];
public VideoModel VideoModel public VideoModel VideoModel
{ {
get { return _videoModel; } get { return _videoModel; }
@ -31,6 +36,7 @@ namespace VideoConcat.ViewModels
ConcatVideos = [], ConcatVideos = [],
MaxNum = 0, MaxNum = 0,
CanStart = false, CanStart = false,
BtnOpenFolderCommand = new Command() BtnOpenFolderCommand = new Command()
{ {
DoExcue = obj => DoExcue = obj =>
@ -78,6 +84,10 @@ namespace VideoConcat.ViewModels
{ {
Task.Run(action: async () => Task.Run(action: async () =>
{ {
VideoModel.Dispatcher.Invoke(() =>
{
VideoModel.ConcatVideos.Clear();
});
MessageBox.Show("开始合并视频"); MessageBox.Show("开始合并视频");
if (Directory.Exists($"{VideoModel.FolderPath}\\output") == false) if (Directory.Exists($"{VideoModel.FolderPath}\\output") == false)
{ {
@ -93,7 +103,7 @@ namespace VideoConcat.ViewModels
List<List<string>> videoLists = []; List<List<string>> videoLists = [];
VideoModel.FolderInfos.ForEach(folderInfo => VideoModel.FolderInfos.ForEach(folderInfo =>
{ {
videoLists.Add(folderInfo.VideoPaths); videoLists.Add(folderInfo.VideoPaths);
@ -161,18 +171,40 @@ namespace VideoConcat.ViewModels
{ {
try try
{ {
string _outPutName = $"{VideoModel.FolderPath}\\output\\{DateTime.Now:yyyyMMddHHmmss}{random.Next(100000, 999999)}.mp4"; string _tempFileName = $"{DateTime.Now:yyyyMMddHHmmss}{random.Next(100000, 999999)}.mp4";
string _outPutName = Path.Combine($"{VideoModel.FolderPath}", "output", _tempFileName); ;
var temporaryVideoParts = combination.Select(_ => { //int _size = 0;
double _duration = 0;
var temporaryVideoParts = combination.Select(_ =>
{
string _tempPath = Path.GetDirectoryName(_) ?? ""; string _tempPath = Path.GetDirectoryName(_) ?? "";
IMediaAnalysis _mediaInfo =FFProbe.Analyse(_);
_duration += _mediaInfo.Duration.TotalSeconds;
//GlobalFFOptions.Current.TemporaryFilesFolder //GlobalFFOptions.Current.TemporaryFilesFolder
return Path.Combine(_tempPath, $"{Path.GetFileNameWithoutExtension(_)}{FileExtension.Ts}"); return Path.Combine(_tempPath, $"{Path.GetFileNameWithoutExtension(_)}{FileExtension.Ts}");
}).ToArray(); }).ToArray();
bool _isSuccess = false; bool _isSuccess = false;
VideoModel.Dispatcher.Invoke(() =>
{
VideoModel.ConcatVideos.Add(new ConcatVideo()
{
Index = VideoModel.ConcatVideos.Count + 1,
FileName = _tempFileName,
Size = 100,
Seconds = _duration,
Status = 1,
Progress = 100,
});
});
try try
{ {
_isSuccess= FFMpegArguments _isSuccess = FFMpegArguments
.FromConcatInput(temporaryVideoParts) .FromConcatInput(temporaryVideoParts)
.OutputToFile(_outPutName, true, options => options .OutputToFile(_outPutName, true, options => options
.CopyChannel() .CopyChannel()
@ -221,11 +253,11 @@ namespace VideoConcat.ViewModels
} }
LogUtils.Info($"当前视频{string.Join("", combination)}合并成功"); LogUtils.Info($"当前视频 {string.Join("", combination)} 合并成功");
} }
catch (Exception ex) catch (Exception ex)
{ {
LogUtils.Error($"视频{string.Join("", combination)}合并失败", ex); LogUtils.Error($"视频{string.Join("", combination)} 合并失败", ex);
} }
finally finally
{ {
@ -242,9 +274,10 @@ namespace VideoConcat.ViewModels
//结束时间 //结束时间
DateTime endTime = DateTime.Now; DateTime endTime = DateTime.Now;
LogUtils.Info($"所有视频拼接完成,用时{(endTime - startTime).TotalSeconds}秒"); LogUtils.Info($"所有视频拼接完成,用时{(endTime - startTime).TotalSeconds}秒");
VideoModel.IsStart = false; VideoModel.IsStart = false;
MessageBox.Show("所有视频拼接完成");
VideoCombine.Cleanup(_clearPath); VideoCombine.Cleanup(_clearPath);
MessageBox.Show("所有视频拼接完成");
}); });
}); });
} }

View File

@ -50,7 +50,7 @@
</WrapPanel> </WrapPanel>
</StackPanel> </StackPanel>
<StackPanel Margin="0,5,0,0"> <StackPanel Margin="0,5,0,0">
<Label>文件信息:</Label> <Label FontWeight="ExtraBold" FontSize="16">文件信息:</Label>
</StackPanel> </StackPanel>
<StackPanel MinHeight="100"> <StackPanel MinHeight="100">
<Grid> <Grid>
@ -70,20 +70,14 @@
</Grid> </Grid>
</StackPanel> </StackPanel>
<StackPanel Margin="0,20,0,0"> <StackPanel Margin="0,20,0,0">
<Label>视频合成进度:</Label> <Label FontWeight="ExtraBold" FontSize="16">视频合成进度:</Label>
</StackPanel> </StackPanel>
<StackPanel MinHeight="200"> <StackPanel MinHeight="200">
<Grid> <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 Grid.Row="1" ItemsSource="{Binding VideoModel.ConcatVideos}" AutoGenerateColumns="False" CanUserAddRows="False" CanUserDeleteRows="False" >
<DataGrid.Columns> <DataGrid.Columns>
<DataGridTextColumn Header="序号" Binding="{Binding Index}" Width="*"></DataGridTextColumn>
<DataGridTextColumn Header="文件名" Binding="{Binding FileName}" Width="*"></DataGridTextColumn> <DataGridTextColumn Header="文件名" Binding="{Binding FileName}" Width="*"></DataGridTextColumn>
<DataGridTextColumn Header="大小" Binding="{Binding Size}" Width="*"></DataGridTextColumn> <DataGridTextColumn Header="大小" Binding="{Binding Size}" Width="*"></DataGridTextColumn>
<DataGridTextColumn Header="时长" Binding="{Binding Seconds}" Width="*"></DataGridTextColumn> <DataGridTextColumn Header="时长" Binding="{Binding Seconds}" Width="*"></DataGridTextColumn>