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();
        }