Пример #1
0
        private void DownloadVideo(string id)
        {
            try
            {
                lock (this.commandLockObject)
                {
                    if (!string.IsNullOrWhiteSpace(id))
                    {
                        TwitchVideo video = this.Videos.Where(v => v.Id == id).FirstOrDefault();

                        if (video != null)
                        {
                            Preferences currentPrefs = this.preferencesService.CurrentPreferences.Clone();

                            TwitchVideoResolution resolution = video.Resolutions.Where(r => r.VideoQuality == currentPrefs.DownloadVideoQuality).FirstOrDefault();

                            if (resolution == null)
                            {
                                resolution = video.Resolutions.First();
                            }

                            string filename = this.filenameService.SubstituteWildcards(currentPrefs.DownloadFileName, video);

                            DownloadParameters downloadParams = new DownloadParameters(video, resolution, currentPrefs.DownloadFolder, filename);

                            this.guiService.ShowDownloadDialog(downloadParams, this.DownloadCallback);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                this.guiService.ShowAndLogException(ex);
            }
        }
        public string SubstituteWildcards(string filename, TwitchVideo video)
        {
            if (video == null)
            {
                throw new ArgumentNullException(nameof(video));
            }

            if (string.IsNullOrWhiteSpace(filename))
            {
                return(filename);
            }

            string result = filename;

            DateTime recorded = video.RecordedDate;

            TwitchVideoResolution resolution = video.Resolutions.First();

            result = result.Replace(FilenameWildcards.GAME, video.Game);
            result = result.Replace(FilenameWildcards.DATE, recorded.ToString("yyyyMMdd"));
            result = result.Replace(FilenameWildcards.TIME, recorded.ToString("hhmmsstt", CultureInfo.InvariantCulture));
            result = result.Replace(FilenameWildcards.ID, video.IdTrimmed);
            result = result.Replace(FilenameWildcards.TITLE, video.Title);
            result = result.Replace(FilenameWildcards.RES, resolution.Resolution);
            result = result.Replace(FilenameWildcards.FPS, resolution.Fps);

            result = this.SubstituteInvalidChars(result, "_");

            return(result);
        }
        public void ShowDownloadDialog(TwitchVideo video, TwitchVideoResolution resolution, string folder, string filename, Action <bool, DownloadParameters> dialogCompleteCallback)
        {
            if (video == null)
            {
                throw new ArgumentNullException(nameof(video));
            }

            if (resolution == null)
            {
                throw new ArgumentNullException(nameof(resolution));
            }

            if (string.IsNullOrWhiteSpace(folder))
            {
                throw new ArgumentNullException(nameof(folder));
            }

            if (string.IsNullOrWhiteSpace(filename))
            {
                throw new ArgumentNullException(nameof(filename));
            }

            if (dialogCompleteCallback == null)
            {
                throw new ArgumentNullException(nameof(dialogCompleteCallback));
            }

            DownloadWindowVM vm = this.kernel.Get <DownloadWindowVM>();

            vm.Video      = video;
            vm.Resolution = resolution;
            vm.Folder     = folder;
            vm.Filename   = filename;

            DownloadWindow window = this.kernel.Get <DownloadWindow>();

            window.DataContext = vm;

            bool?result = window.ShowDialog();

            DownloadParameters resultObject = vm.ResultObject;

            dialogCompleteCallback(result != true, resultObject);
        }
Пример #4
0
        private void DownloadVideo(string id)
        {
            try
            {
                lock (this.commandLockObject)
                {
                    if (!string.IsNullOrWhiteSpace(id))
                    {
                        if (this.twitchService.Downloads.Where(d => d.Video.Id == id).Any())
                        {
                            this.guiService.ShowMessageBox("This video is already being downloaded!", "Download Video", MessageBoxButton.OK, MessageBoxImage.Information);
                            return;
                        }

                        TwitchVideo video = this.Videos.Where(v => v.Id == id).FirstOrDefault();

                        if (video != null)
                        {
                            Preferences currentPrefs = this.preferencesService.CurrentPreferences.Clone();

                            TwitchVideoResolution resolution = video.Resolutions.Where(r => r.VideoQuality == currentPrefs.DownloadVideoQuality).FirstOrDefault();

                            if (resolution == null)
                            {
                                resolution = video.Resolutions.First();
                            }

                            string filename = this.filenameService.SubstituteWildcards(currentPrefs.DownloadFileName, video);

                            this.guiService.ShowDownloadDialog(video, resolution, currentPrefs.DownloadFolder, filename, this.DownloadCallback);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                this.guiService.ShowAndLogException(ex);
            }
        }
Пример #5
0
        private string RetrievePlaylistUrlForQuality(Action <string> log, WebClient webClient, TwitchVideoResolution resolution, string urlIdTrimmed, AuthInfo authInfo)
        {
            log(Environment.NewLine + Environment.NewLine + "Retrieving m3u8 playlist urls for all VOD qualities...");
            string allPlaylistsStr = webClient.DownloadString(string.Format(allPlaylistsUrl, urlIdTrimmed, authInfo.Signature, authInfo.Token));

            log(" done!");

            List <string> allPlaylistsList = allPlaylistsStr.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries).Where(s => !s.StartsWith("#")).ToList();

            allPlaylistsList.ForEach(url =>
            {
                log(Environment.NewLine + url);
            });

            string playlistUrl = allPlaylistsList.Where(s => s.ToLowerInvariant().Contains(resolution.VideoQuality.ToTwitchQuality())).First();

            log(Environment.NewLine + Environment.NewLine + "Playlist url for selected quality " + resolution.ResolutionFps + " is " + playlistUrl);

            return(playlistUrl);
        }
Пример #6
0
        private void StartQueuedDownloadIfExists()
        {
            if (this.paused)
            {
                return;
            }

            if (Monitor.TryEnter(this.changeDownloadLockObject))
            {
                try
                {
                    if (!this.downloads.Where(d => d.DownloadStatus == DownloadStatus.Active).Any())
                    {
                        TwitchVideoDownload download = this.downloads.Where(d => d.DownloadStatus == DownloadStatus.Queued).FirstOrDefault();

                        if (download == null)
                        {
                            return;
                        }

                        DownloadParameters downloadParams = download.DownloadParams;

                        CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
                        CancellationToken       cancellationToken       = cancellationTokenSource.Token;

                        string downloadId   = download.Id;
                        string urlIdTrimmed = downloadParams.Video.IdTrimmed;
                        string tempDir      = Path.Combine(downloadParams.Folder, TEMP_PREFIX + downloadId);
                        string playlistFile = Path.Combine(tempDir, PLAYLIST_NAME);
                        string ffmpegFile   = Path.Combine(appDir, Environment.Is64BitOperatingSystem ? FFMPEG_EXE_X64 : FFMPEG_EXE_X86);
                        string outputFile   = downloadParams.FullPath;

                        bool cropStart = downloadParams.CropStart;
                        bool cropEnd   = downloadParams.CropEnd;

                        TimeSpan cropStartTime = downloadParams.CropStartTime;
                        TimeSpan cropEndTime   = downloadParams.CropEndTime;

                        TwitchVideoResolution resolution = downloadParams.Resolution;

                        Action <DownloadStatus> setDownloadStatus = download.SetDownloadStatus;
                        Action <string>         log           = download.AppendLog;
                        Action <string>         setStatus     = download.SetStatus;
                        Action <int>            setProgress   = download.SetProgress;
                        Action <bool>           setIsEncoding = download.SetIsEncoding;

                        Task downloadVideoTask = new Task(() =>
                        {
                            setStatus("Initializing");

                            log("Download task has been started!");

                            this.WriteDownloadInfo(log, downloadParams, ffmpegFile, tempDir);

                            this.CheckTempDirectory(log, tempDir);

                            using (WebClient webClient = new WebClient())
                            {
                                AuthInfo authInfo = this.RetrieveAuthInfo(log, webClient, urlIdTrimmed);

                                cancellationToken.ThrowIfCancellationRequested();

                                string playlistUrl = this.RetrievePlaylistUrlForQuality(log, webClient, resolution, urlIdTrimmed, authInfo);

                                cancellationToken.ThrowIfCancellationRequested();

                                WebChunkList webChunkList = this.RetrieveWebChunkList(log, webClient, tempDir, playlistUrl);

                                cancellationToken.ThrowIfCancellationRequested();

                                CropInfo cropInfo = this.CropWebChunkList(webChunkList, cropStart, cropEnd, cropStartTime, cropEndTime);

                                cancellationToken.ThrowIfCancellationRequested();

                                this.DownloadChunks(log, setStatus, setProgress, webChunkList, cancellationToken);

                                cancellationToken.ThrowIfCancellationRequested();

                                this.WriteNewPlaylist(log, webChunkList, playlistFile);

                                cancellationToken.ThrowIfCancellationRequested();

                                this.EncodeVideo(log, setStatus, setProgress, setIsEncoding, ffmpegFile, playlistFile, outputFile, cropInfo);
                            }
                        }, cancellationToken);

                        Task continueTask = downloadVideoTask.ContinueWith(task =>
                        {
                            log(Environment.NewLine + Environment.NewLine + "Starting temporary download folder cleanup!");
                            this.CleanUp(tempDir, log);

                            setProgress(100);
                            setIsEncoding(false);

                            bool success = false;

                            if (task.IsFaulted)
                            {
                                setDownloadStatus(DownloadStatus.Error);
                                log(Environment.NewLine + Environment.NewLine + "Download task ended with an error!");

                                if (task.Exception != null)
                                {
                                    log(Environment.NewLine + Environment.NewLine + task.Exception.ToString());
                                }
                            }
                            else if (task.IsCanceled)
                            {
                                setDownloadStatus(DownloadStatus.Canceled);
                                log(Environment.NewLine + Environment.NewLine + "Download task was canceled!");
                            }
                            else
                            {
                                success = true;
                                setDownloadStatus(DownloadStatus.Finished);
                                log(Environment.NewLine + Environment.NewLine + "Download task ended successfully!");
                            }

                            DownloadTask downloadTask;

                            if (!this.downloadTasks.TryRemove(downloadId, out downloadTask))
                            {
                                throw new ApplicationException("Could not remove download task with ID '" + downloadId + "' from download task collection!");
                            }

                            if (success && this.preferencesService.CurrentPreferences.DownloadRemoveCompleted)
                            {
                                this.eventAggregator.GetEvent <DownloadCompletedEvent>().Publish(downloadId);
                            }
                        });

                        if (this.downloadTasks.TryAdd(downloadId, new DownloadTask(downloadVideoTask, continueTask, cancellationTokenSource)))
                        {
                            downloadVideoTask.Start();
                            setDownloadStatus(DownloadStatus.Active);
                        }
                    }
                }
                finally
                {
                    Monitor.Exit(this.changeDownloadLockObject);
                }
            }
        }