public SpaceRecordingViewModel(Space space, Project project) { InitCommands(); _setDurationBasedOnWpm = false; _description = null; Space = space; Project = project; ResetElapsedTime(); SetTimeLeft(); RecordDuration = Space.Duration; MaxWordsPerMinute = DefaultMaxWordsPerMinute; MinWordsPerMinute = DefaultMinWordsPerMinute; _recorder = new DescriptionRecorder(); _recorder.DescriptionRecorded += (sender, args) => Description = args.Value; _player = new DescriptionPlayer(); _player.DescriptionFinishedPlaying += (sender, args) => CommandManager.InvalidateRequerySuggested(); _recordingTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(CountdownTimerIntervalMsec) }; _recordingTimer.Tick += RecordingTimerOnTick; _stopwatch = new Stopwatch(); CountdownViewModel = new CountdownViewModel(); CountdownViewModel.CountdownFinished += (sender, args) => StartRecording(); SetWpmValuesBasedOnSpaceText(); }
/// <summary> /// Creates a ExportWindowView and attaches an instance of ExportViewModel to it. /// </summary> /// <returns>The ViewModel of the Window.</returns> public static ExportViewModel SpawnExportWindowView(Project project, string videoPath, double durationSeconds, List<Description> descriptionList, LoadingViewModel loadingViewModel) { var viewModel = new ExportViewModel(project, videoPath, durationSeconds, descriptionList, loadingViewModel); var view = new ExportWindow(viewModel); viewModel.DialogResult = view.ShowDialog(); return viewModel; }
/// <summary> /// Creates a SpaceRecordingWindow and attaches an instance of SpaceRecordingViewModel to it. /// </summary> /// <param name="selectedSpace">Space to record in.</param> /// <param name="project">The current LiveDescribe Project.</param> /// <returns>The ViewModel of the Window.</returns> public static SpaceRecordingViewModel SpawnSpaceRecordingView(Space selectedSpace, Project project) { var viewModel = new SpaceRecordingViewModel(selectedSpace, project); var view = new SpaceRecordingWindow(viewModel); viewModel.DialogResult = view.ShowDialog(); return viewModel; }
public static void WriteSpacesFile(Project project, ObservableCollection<Space> spaces) { Log.Info("Saving spaces file to " + project.Files.Spaces); var json = new JsonSerializer { Formatting = Formatting.Indented }; using (var sw = new StreamWriter(project.Files.Spaces)) { json.Serialize(sw, spaces.ToList()); } Log.Info("Spaces file saved successfully"); }
/// <summary> /// Writes a Project object to a file. The path is determined by the project's ProjectFile.AbsolutePath. /// </summary> /// <param name="project"></param> public static void WriteProjectFile(Project project) { Log.Info("Saving project file to " + project.Files.Project); var serializer = new JsonSerializer { Formatting = Formatting.Indented }; using (var sw = new StreamWriter(project.Files.Project, false)) { serializer.Serialize(sw, project, typeof(Project)); } Log.Info("Project file saved successfully"); }
public static List<Space> ReadSpacesFile(Project project) { List<Space> spaces; Log.Info("Reading spaces from " + project.Files.Spaces); using (var r = new StreamReader(project.Files.Spaces)) { spaces = JsonConvert.DeserializeObject<List<Space>>(r.ReadToEnd()); } Log.Info("Spaces successfully read from " + project.Files.Spaces); return spaces; }
public ExportViewModel(Project project, string videoPath, double durationSeconds, List<Description> descriptionList, LoadingViewModel loadingViewModel) { ChoosePathCommand = new RelayCommand(ChoosePath); ExportCommand = new RelayCommand(ExportProject, CanExport); _project = project; _videoPath = videoPath; _durationSeconds = durationSeconds; _descriptionList = descriptionList; _loadingViewModel = loadingViewModel; }
public static Header ReadWaveFormHeader(Project project) { Log.Info("Reading waveform header from " + project.Files.WaveFormHeader); Header header; using (var file = File.Open(project.Files.WaveFormHeader, FileMode.Open, FileAccess.Read)) { var bin = new BinaryFormatter(); header = (Header)bin.Deserialize(file); } Log.Info("Waveform header successfully read from " + project.Files.WaveFormHeader); return header; }
public static List<short> ReadWaveFormFile(Project project) { List<short> waveFormData; Log.Info("Reading waveform data from " + project.Files.WaveForm); using (var file = File.Open(project.Files.WaveForm, FileMode.Open, FileAccess.Read)) { var bin = new BinaryFormatter(); waveFormData = (List<short>)bin.Deserialize(file); } Log.Info("Waveform data successfully read from " + project.Files.WaveForm); return waveFormData; }
/// <summary> /// Attempts to create the project file and folder /// </summary> /// <param name="project">The instance of project to initialize.</param> /// <returns>Whether or not initialization was successful.</returns> public static void InitializeProjectDirectory(Project project) { //Ensure that path is absolute if (!Path.IsPathRooted(project.Folders.Project)) { MessageBoxFactory.ShowError("Project location must be a root path."); Log.Warn("Given project path is not rooted"); throw new ArgumentException("Given project path is not rooted"); } if (Directory.Exists(project.Folders.Project)) { var result = MessageBoxFactory.ShowWarningQuestion( string.Format(UiStrings.MessageBox_Format_OverwriteProjectWarning, project.Folders.Project)); Log.Warn("Project folder already exists"); //Return if user doesn't agree to overwrite files. if (result != MessageBoxResult.Yes) throw new OperationCanceledException("User decided not to overwrite already existing project"); Log.Info("User has decided to overwrite an existing project directory"); FileDeleter.DeleteProject(project); } //Attempt to create files try { Log.Info("Creating project folder"); Directory.CreateDirectory(project.Folders.Project); Log.Info("Creating project file"); FileWriter.WriteProjectFile(project); /* Create empty description and space files here, so if they are missing when * opening a project, it can be noted as so. */ Log.Info("Creating descriptions file"); FileWriter.WriteDescriptionsFile(project, new ObservableCollection<Description>()); Log.Info("Creating spaces file"); FileWriter.WriteSpacesFile(project, new ObservableCollection<Space>()); } catch (Exception e) { MessageBoxFactory.ShowError(UiStrings.MessageBox_ProjectCreationError); Log.Error("An error occured when attempting to create files", e); throw; } }
public static List<Description> ReadDescriptionsFile(Project project) { List<Description> descriptions; Log.Info("Reading descriptions from " + project.Files.Descriptions); using (var r = new StreamReader(project.Files.Descriptions)) { descriptions = JsonConvert.DeserializeObject<List<Description>>(r.ReadToEnd()); } foreach (var description in descriptions) { description.AudioFile.MakeAbsoluteWith(project.Folders.Project); } Log.Info("Descriptions successfully read from " + project.Files.Descriptions); return descriptions; }
public static void DeleteUnusedDescriptionFiles(Project project) { if (project == null) return; string[] descriptionPaths = Directory.GetFiles(project.Folders.Descriptions.AbsolutePath, "*.wav"); var descriptions = FileReader.ReadDescriptionsFile(project); foreach (var path in descriptionPaths) { if (!PathExistsInDescriptionList(path, descriptions)) { File.Delete(path); } } }
public DescriptionExportUtility(BackgroundWorker progressWorker, Project project, string videoFile, double videoDurationSeconds, List<Description> descriptionList) { _project = project; _videoFile = videoFile; _videoDurationSeconds = videoDurationSeconds; _descriptionList = descriptionList; _progressWorker = progressWorker; //gets the path of the ffmpeg.exe file within the LiveDescribe solution var appDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); _ffmpegPath = Path.Combine(appDirectory, "Utilities/ffmpeg.exe"); if (!File.Exists(_ffmpegPath)) { Log.Error("ffmpeg.exe can not be found at " + _ffmpegPath); //need to do error handling } }
/// <summary> /// Deletes all the files in a project folder defined by a project object, if they exist in /// the file system. /// </summary> /// <param name="project">The project to delete.</param> public static void DeleteProject(Project project) { //Get a list of all the file properties PropertyInfo[] fileProperties = typeof(Project.ProjectFiles).GetProperties(); //Iterate through the list of file properties foreach (var propertyInfo in fileProperties) { //Get the actual value of the property from project var f = propertyInfo.GetValue(project.Files) as ProjectFile; //If f was a projectFile and the file exists, delete it if (f != null && File.Exists(f)) { File.Delete(f); Log.Info("Deleting project file " + f.RelativePath); } } //Do the same for all the folders PropertyInfo[] folderProperties = typeof(Project.ProjectFolders).GetProperties(); foreach (var propertyInfo in folderProperties) { var f = propertyInfo.GetValue(project.Folders) as ProjectFile; if (f != null && Directory.Exists(f)) { //Delete folders only if empty var files = Directory.GetFiles(f); if (files.Length == 0) { Directory.Delete(f, false); Log.Info("Deleting project folder " + f.RelativePath); } } //TODO delete .wav description files. } }
/// <summary> /// Writes audio data to the file path specified by project.Files.WaveForm.AbsolutePath. /// </summary> /// <param name="project"></param> /// <param name="waveFormData"></param> public static void WriteWaveFormFile(Project project, List<short> waveFormData) { Log.Info("Saving waveform data file to " + project.Files.WaveForm); using (var file = File.Open(project.Files.WaveForm, FileMode.Create, FileAccess.Write)) { var bin = new BinaryFormatter(); bin.Serialize(file, waveFormData); } Log.Info("Waveform data file saved successfully"); }
/// <summary> /// Initializes and sets up the progam for a given project file. /// </summary> /// <param name="p">The project to initialize</param> public void SetProject(Project p) { CloseProject.ExecuteIfCan(); _projectManager.LoadProject(p); Settings.Default.RecentProjects.AddFirst(new NamedFilePath { Name = p.ProjectName, Path = p.Files.Project, }); Settings.Default.Save(); }
private void CopyVideoAndSetProject(string source, Project project) { LoadingViewModel.Visible = true; //Copy video file in background while updating the LoadingBorder var copyVideoWorker = new BackgroundWorker { WorkerReportsProgress = true, }; var copier = new ProgressFileCopier(); copyVideoWorker.DoWork += (sender, args) => { copier.ProgressChanged += (o, eventArgs) => copyVideoWorker.ReportProgress(eventArgs.ProgressPercentage); copier.CopyFile(source, project.Files.Video); }; copyVideoWorker.ProgressChanged += (sender, args) => LoadingViewModel.SetProgress("Copying Video File", args.ProgressPercentage); copyVideoWorker.RunWorkerCompleted += (sender, args) => SetProject(project); copyVideoWorker.RunWorkerAsync(); }
private void OnProjectLoaded(Project project) { var handler = ProjectLoaded; if (handler != null) handler(this, new EventArgs<Project>(project)); }
private void LoadSpaces(Project project) { var spaces = FileReader.ReadSpacesFile(project); OnSpacesLoaded(spaces); Log.InfoFormat("Spaces loaded from {0}", project.ProjectName); }
public MainWindowViewModel(ILiveDescribePlayer mediaVideo) { DispatcherHelper.Initialize(); _undoRedoManager = new UndoRedoManager(); _loadingViewModel = new LoadingViewModel(100, null, 0, false); _projectManager = new ProjectManager(_loadingViewModel, _undoRedoManager); _descriptionRecordingControlViewModel = new DescriptionRecordingControlViewModel(mediaVideo, _projectManager); _mediaControlViewModel = new MediaControlViewModel(mediaVideo, _projectManager); _preferences = new PreferencesViewModel(); _descriptionInfoTabViewModel = new DescriptionInfoTabViewModel(_projectManager, _descriptionRecordingControlViewModel); _markingSpacesControlViewModel = new MarkingSpacesControlViewModel(_descriptionInfoTabViewModel, mediaVideo, _undoRedoManager); _audioCanvasViewModel = new AudioCanvasViewModel(mediaVideo, _projectManager); _descriptionCanvasViewModel = new DescriptionCanvasViewModel(mediaVideo, _projectManager); _mediaVideo = mediaVideo; DescriptionPlayer = new DescriptionPlayer(); DescriptionPlayer.DescriptionFinishedPlaying += (sender, e) => { try { DispatcherHelper.UIDispatcher.Invoke(() => _mediaControlViewModel.ResumeFromDescription(e.Value)); } catch (TaskCanceledException exception) { Log.Warn("Task Canceled Exception", exception); } }; #region Commands //Commands CloseProject = new RelayCommand( canExecute: () => _projectManager.HasProjectLoaded, execute: () => { if (_projectManager.IsProjectModified) { var result = MessageBoxFactory.ShowWarningQuestion( string.Format(UiStrings.MessageBox_Format_SaveProjectWarning, _project.ProjectName)); if (result == MessageBoxResult.Yes) SaveProject.Execute(); else if (result == MessageBoxResult.Cancel) return; } _projectManager.CloseProject(); }); NewProject = new RelayCommand(() => { var viewModel = DialogShower.SpawnNewProjectView(); if (viewModel.DialogResult != true) return; if (viewModel.CopyVideo) CopyVideoAndSetProject(viewModel.VideoPath, viewModel.Project); else SetProject(viewModel.Project); }); OpenProject = new RelayCommand(() => { var projectChooser = new OpenFileDialog { Filter = string.Format(UiStrings.OpenFileDialog_Format_OpenProject, Project.Names.ProjectExtension) }; bool? dialogSuccess = projectChooser.ShowDialog(); if (dialogSuccess != true) return; OpenProjectPath.Execute(projectChooser.FileName); }); OpenProjectPath = new RelayCommand<string>(path => { //Attempt to read project. If object fields are missing, an error window pops up. try { Project p = FileReader.ReadProjectFile(path); SetProject(p); } catch (JsonSerializationException) { MessageBoxFactory.ShowError(UiStrings.MessageBox_OpenProjectFileMissingError); } catch (DirectoryNotFoundException e) { Log.Warn("Directory not found while trying to open project", e); MessageBoxFactory.ShowError(UiStrings.MessageBox_DirectoryNotFoundError); } catch (FileNotFoundException e) { Log.Warn("FileNotFound while trying to open project", e); MessageBoxFactory.ShowError(string.Format(UiStrings.MessageBox_Format_FileNotFoundError, e.FileName)); } }); ClearRecentProjects = new RelayCommand(() => { Settings.Default.RecentProjects.Clear(); Settings.Default.Save(); }); ShowImportAudioDescription = new RelayCommand( canExecute: () => _projectManager.HasProjectLoaded, execute: () => { var viewModel = DialogShower.SpawnImportAudioDescriptionView(_projectManager, _mediaVideo.DurationMilliseconds); } ); SaveProject = new RelayCommand( canExecute: () => _projectManager.IsProjectModified, execute: () => _projectManager.SaveProject() ); ExportWithDescriptions = new RelayCommand( canExecute: () => _projectManager.HasProjectLoaded, execute: () => { var viewModel = DialogShower.SpawnExportWindowView(_project, _mediaVideo.Path, _mediaVideo.DurationSeconds, _projectManager.AllDescriptions.ToList(), _loadingViewModel); if (viewModel.DialogResult != true) return; }); ClearCache = new RelayCommand( canExecute: () => _projectManager.HasProjectLoaded, execute: () => { var p = _project; CloseProject.Execute(); Directory.Delete(p.Folders.Cache, true); SetProject(p); }); ShowPreferences = new RelayCommand(() => { _preferences.RetrieveApplicationSettings(); var preferencesWindow = new PreferencesWindow(_preferences); preferencesWindow.ShowDialog(); }); FindSpaces = new RelayCommand( canExecute: () => _projectManager.HasProjectLoaded, execute: () => { var spaces = AudioAnalyzer.FindSpaces(_mediaControlViewModel.Waveform); _projectManager.Spaces.AddRange(spaces); } ); ExportDescriptionsTextToSrt = new RelayCommand( canExecute: () => _projectManager.HasProjectLoaded, execute: () => { var saveFileDialog = new SaveFileDialog { FileName = Path.GetFileNameWithoutExtension(_mediaControlViewModel.Path), Filter = UiStrings.SaveFileDialog_ExportToSrt }; saveFileDialog.ShowDialog(); FileWriter.WriteDescriptionsTextToSrtFile(saveFileDialog.FileName, _projectManager.AllDescriptions); } ); ExportSpacesTextToSrt = new RelayCommand( canExecute: () => _projectManager.HasProjectLoaded, execute: () => { var saveFileDialog = new SaveFileDialog { FileName = Path.GetFileNameWithoutExtension(_mediaControlViewModel.Path), Filter = UiStrings.SaveFileDialog_ExportToSrt }; saveFileDialog.ShowDialog(); FileWriter.WriteSpacesTextToSrtFile(saveFileDialog.FileName, _projectManager.Spaces); } ); ShowDescriptionFolder = new RelayCommand( canExecute: () => _projectManager.HasProjectLoaded, execute: () => { var pfi = new ProcessStartInfo("Explorer.exe", _project.Folders.Descriptions.AbsolutePath); Process.Start(pfi); } ); ShowAboutInfo = new RelayCommand(DialogShower.SpawnAboutInfoView); #endregion //If apply requested happens in the preferences use the new saved microphone in the settings _descriptiontimer = new Timer(10); _descriptiontimer.Elapsed += Play_Tick; _descriptiontimer.AutoReset = true; #region MediaControlViewModel Events _mediaControlViewModel.PlayRequested += (sender, e) => { _mediaVideo.Play(); _descriptiontimer.Start(); //this Handler should be attached to the view to update the graphics OnPlayRequested(sender, e); }; _mediaControlViewModel.PauseRequested += (sender, e) => { _mediaVideo.Pause(); _descriptiontimer.Stop(); if (_lastRegularDescriptionPlayed != null && _lastRegularDescriptionPlayed.IsPlaying) DescriptionPlayer.Stop(); //this Handler should be attached to the view to update the graphics OnPauseRequested(sender, e); }; _mediaControlViewModel.OnPausedForExtendedDescription += (sender, e) => { _mediaVideo.Pause(); _descriptiontimer.Stop(); CommandManager.InvalidateRequerySuggested(); }; _mediaControlViewModel.MuteRequested += OnMuteRequested; _mediaControlViewModel.MediaEndedEvent += (sender, e) => { _descriptiontimer.Stop(); _mediaVideo.Stop(); OnMediaEnded(sender, e); }; #endregion #region Property Changed Events _mediaControlViewModel.PropertyChanged += PropertyChangedHandler; //Update window title based on project name PropertyChanged += (sender, args) => { if (args.PropertyName == "IsProjectModified") SetWindowTitle(); }; #endregion #region ProjectManager Events _projectManager.ProjectLoaded += (sender, args) => { _project = args.Value; _mediaControlViewModel.LoadVideo(_project.Files.Video); SetWindowTitle(); }; _projectManager.ProjectModifiedStateChanged += (sender, args) => SetWindowTitle(); _projectManager.ProjectClosed += (sender, args) => { TryToCleanUpUnusedDescriptionAudioFiles(); _project = null; SetWindowTitle(); }; #endregion SetWindowTitle(); }
public void StartLoadingProject(Project project) { InitializeDirectories(project); LoadDescriptions(project); LoadSpaces(project); if (!File.Exists(project.Files.WaveForm)) StripAudioAnContinueLoadingProject(project); else { LoadWaveForm(project); ContinueLoadingProject(project); } }
private void ContinueLoadingProject(Project project) { Settings.Default.WorkingDirectory = project.Folders.Project + "\\"; OnProjectLoaded(project); Log.InfoFormat("Project \"{0}\" loaded successfully", project.ProjectName); _loadingViewModel.Visible = false; }
private void InitializeDirectories(Project project) { CreateDirectoryIfNotExists(project.Folders.Descriptions); CreateDirectoryIfNotExists(project.Folders.Cache); }
private void LoadWaveForm(Project project) { var header = FileReader.ReadWaveFormHeader(project); var audioData = FileReader.ReadWaveFormFile(project); project.Waveform = new Waveform(header, audioData); Log.InfoFormat("Waveform loaded from {0}", project.Files.WaveForm); }
/// <summary> /// Writes the header for the WAV file that the waveform data was sampled from. /// </summary> /// <param name="project"></param> /// <param name="header"></param> public static void WriteWaveFormHeader(Project project, Header header) { Log.Info("Saving waveform header file to " + project.Files.WaveFormHeader); using (var file = File.Open(project.Files.WaveFormHeader, FileMode.Create, FileAccess.Write)) { var bin = new BinaryFormatter(); bin.Serialize(file, header); } Log.Info("Waveform header file saved successfully"); }
public void LoadProject(Project project) { _projectLoader.StartLoadingProject(project); }
private void OnSpacesAudioAnalysisCompleted(Project project, List<Space> spaces) { EventHandler<TwoTupleEventArgs<Project, List<Space>>> handler = SpacesAudioAnalysisCompleted; if (handler != null) handler(this, new TwoTupleEventArgs<Project, List<Space>>(project, spaces)); }
private void LoadDescriptions(Project project) { var descriptions = FileReader.ReadDescriptionsFile(project); OnDescriptionsLoaded(descriptions); Log.InfoFormat("Descriptions loaded from {0}", project.ProjectName); }
/// <summary> /// Attempts to create a project using forminfo. If the given folder structure exists, the /// user will be asked for confirmation to overwrite it. On an error, the project creation /// will be cancelled and the method will return. On success, the ProjectCreated event is invoked. /// </summary> private void CreateProject() { Log.Info(CopyVideo ? "Attempting to create a project with a copied video" : "Attempting to create a project with a video located outside of project"); var project = new Project(ProjectName, ProjectPath, VideoPath, CopyVideo); try { ProjectLoader.InitializeProjectDirectory(project); } catch { return; } Project = project; Log.Info("Project Created"); OnProjectCreated(); }
private void StripAudioAnContinueLoadingProject(Project project) { var worker = new BackgroundWorker { WorkerReportsProgress = true, }; Waveform waveform = null; //Strip the audio from the given project video worker.DoWork += (sender, args) => { Log.Info("Beginning to strip audio"); var audioOperator = new AudioUtility(project); audioOperator.StripAudio(worker); var waveFormData = audioOperator.ReadWavData(worker); var audioHeader = audioOperator.Header; waveform = new Waveform(audioHeader, waveFormData); Log.Info("Audio stripped"); }; worker.RunWorkerCompleted += (sender, args) => { project.Waveform = waveform; if (Settings.Default.AutoGenerateSpaces) { List<Space> spaceData = AudioAnalyzer.FindSpaces(waveform); OnSpacesAudioAnalysisCompleted(project, spaceData); Log.Info("Spaces found"); } else Log.Info("Spaces not auto-generated"); FileWriter.WriteWaveFormHeader(project, waveform.Header); FileWriter.WriteWaveFormFile(project, waveform.Data); ContinueLoadingProject(project); }; worker.ProgressChanged += (sender, args) => _loadingViewModel.SetProgress("Importing Video", args.ProgressPercentage); _loadingViewModel.SetProgress("Importing Video", 0); _loadingViewModel.Visible = true; worker.RunWorkerAsync(); }