using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Windows.Controls; using System.Windows.Threading; using Correlator.Events; using Correlator.Model; using Correlator.Util; using HandyControl.Controls; using HandyControl.Data; using NAudio.Wave; using Prism.Commands; using Prism.Events; using Prism.Mvvm; using Prism.Services.Dialogs; namespace Correlator.ViewModels { public class AudioFileViewModel : BindableBase, IDialogAware { #region 属性绑定 public string Title { get; private set; } = string.Empty; public event Action<IDialogResult> RequestClose; private List<AudioFile> _totalFiles; private List<AudioFile> _audioFiles; public List<AudioFile> AudioFiles { get => _audioFiles; set { _audioFiles = value; RaisePropertyChanged(); } } private string _audioState = "未播放"; public string AudioState { get => _audioState; set { _audioState = value; RaisePropertyChanged(); } } private int _max = int.MaxValue; public int Max { get => _max; set { _max = value; RaisePropertyChanged(); } } private int _currentValue; public int CurrentValue { get => _currentValue; set { _currentValue = value; RaisePropertyChanged(); } } private int _pageIndex = 1; public int PageIndex { get => _pageIndex; set { _pageIndex = value; RaisePropertyChanged(); } } private int _maxPage; public int MaxPage { get => _maxPage; set { _maxPage = value; RaisePropertyChanged(); } } #endregion #region DelegateCommand public DelegateCommand GoBackCommand { get; set; } public DelegateCommand<DataGrid> ItemSelectedCommand { get; set; } public DelegateCommand PlayAudioCommand { get; set; } public DelegateCommand DeleteAudioCommand { get; set; } public DelegateCommand<FunctionEventArgs<int>> PageUpdatedCmd { get; set; } #endregion private AudioFile _selectedFile; private WaveOutEvent _waveOutEvent = new WaveOutEvent(); private AudioFileReader _audioFileReader; private readonly DispatcherTimer _audioTimer = new DispatcherTimer { Interval = new TimeSpan(0, 0, 0, 1) }; public AudioFileViewModel(IDialogService dialogService, IEventAggregator eventAggregator) { _audioTimer.Tick += delegate { if (_waveOutEvent.PlaybackState == PlaybackState.Stopped) { _audioTimer.Stop(); AudioState = "未播放"; } if (_audioFileReader == null) { return; } CurrentValue = _audioFileReader.CurrentTime.Seconds; var buffer = new float[1000]; var samplesRead = _audioFileReader.Read(buffer, 0, buffer.Length); var samples = buffer.Take(samplesRead).Select(x => (double)Math.Abs(x)); var array = samples.ToArray(); eventAggregator.GetEvent<AudioSampleEvent>().Publish(array); }; GoBackCommand = new DelegateCommand(delegate { _audioTimer.Stop(); if (_audioFileReader != null) { _audioFileReader.Dispose(); _audioFileReader = null; } if (_waveOutEvent != null) { _waveOutEvent.Dispose(); _waveOutEvent = null; } RequestClose?.Invoke(new DialogResult(ButtonResult.Cancel)); }); ItemSelectedCommand = new DelegateCommand<DataGrid>(delegate(DataGrid dataGrid) { _selectedFile = (AudioFile)dataGrid.SelectedItem; }); PlayAudioCommand = new DelegateCommand(delegate { if (_selectedFile == null) { dialogService.ShowDialog( "AlertMessageDialog", new DialogParameters { { "AlertType", AlertType.Error }, { "Title", "温馨提示" }, { "Message", "音频文件路径错误,无法播放" } }, delegate { } ); return; } if (_waveOutEvent.PlaybackState == PlaybackState.Playing) { _waveOutEvent.Dispose(); _audioFileReader.Dispose(); _audioTimer.Stop(); AudioState = "未播放"; } else { try { _audioTimer.Start(); _audioFileReader = new AudioFileReader(_selectedFile.FullPath); Max = (int)_audioFileReader.TotalTime.TotalSeconds; AudioState = $"时长:{_max}s"; _waveOutEvent.Init(_audioFileReader); _waveOutEvent.Play(); } catch (FormatException) { dialogService.ShowDialog( "AlertMessageDialog", new DialogParameters { { "AlertType", AlertType.Error }, { "Title", "温馨提示" }, { "Message", "音频文件已损坏,无法播放" } }, delegate { } ); // MessageBox.Show("音频文件损坏,无法播放", "温馨提示", MessageBoxButton.OK, MessageBoxImage.Error); } } }); DeleteAudioCommand = new DelegateCommand(() => { if (_selectedFile == null) { Growl.Error("删除失败"); return; } if (_waveOutEvent.PlaybackState == PlaybackState.Playing) { _waveOutEvent.Dispose(); _audioFileReader.Dispose(); } try { File.Delete(_selectedFile.FullPath); //刷新数据 _totalFiles = GetTotalAudioFiles(); MaxPage = _totalFiles.Count.GetPageSize(); AudioFiles = _totalFiles.Take(RuntimeCache.PerPageItemCount).ToList(); } catch (IOException) { Growl.Error("删除失败"); } }); PageUpdatedCmd = new DelegateCommand<FunctionEventArgs<int>>(args => { AudioFiles = _totalFiles .Skip((args.Info - 1) * RuntimeCache.PerPageItemCount) .Take(RuntimeCache.PerPageItemCount) .ToList(); }); } public bool CanCloseDialog() { return true; } public void OnDialogClosed() { } public void OnDialogOpened(IDialogParameters parameters) { _totalFiles = GetTotalAudioFiles(); MaxPage = _totalFiles.Count.GetPageSize(); AudioFiles = _totalFiles.Take(RuntimeCache.PerPageItemCount).ToList(); } private static List<AudioFile> GetTotalAudioFiles() { var audioFiles = new List<AudioFile>(); var i = 1; //筛选大于1K的音频文件 var files = new DirectoryInfo(DirectoryManager.GetAudioDir()).GetFiles("*", SearchOption.AllDirectories); foreach (var file in files) { if (file.Length < 1024) { RuntimeCache.SmallAudioFiles.Add(file.FullName); } else { var fileName = file.Name; var fileSource = fileName.Contains("听音") ? "听音" : ""; audioFiles.Add(new AudioFile { Order = i++, FileName = fileName, FileSource = fileSource, FullPath = DirectoryManager.GetAudioDir() + "\\" + fileName, FileSize = file.Length.FormatFileSize(), CreationTime = file.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") }); } } return audioFiles; } } }