コード例 #1
0
        private void DownloadVideo(string id)
        {
            try
            {
                lock (_commandLockObject)
                {
                    if (!string.IsNullOrWhiteSpace(id))
                    {
                        TwitchVideo video = Videos.Where(v => v.Id == id).FirstOrDefault();

                        if (video != null)
                        {
                            TwitchVideoAuthInfo vodAuthInfo = _apiService.GetVodAuthInfo(video.Id);

                            if (!vodAuthInfo.Privileged && vodAuthInfo.SubOnly)
                            {
                                if (_isAuthenticatedSubOnly)
                                {
                                    _dialogService.ShowMessageBox("This video is sub-only but you are not subscribed to the channel!", "Download", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                                }
                                else
                                {
                                    _dialogService.ShowMessageBox("This video is sub-only! You need to enable sub-only video download support first!", "Download", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                                }

                                return;
                            }

                            Dictionary <TwitchVideoQuality, string> playlistInfo = _apiService.GetPlaylistInfo(id, vodAuthInfo);
                            List <TwitchVideoQuality> qualities = playlistInfo.Keys.OrderBy(q => q).ToList();

                            Preferences currentPrefs = _preferencesService.CurrentPreferences.Clone();

                            TwitchVideoQuality selectedQuality = GetSelectedQuality(qualities, currentPrefs.DownloadDefaultQuality);

                            string folder = currentPrefs.DownloadSubfoldersForFav && _preferencesService.IsChannelInFavourites(video.Channel)
                                ? Path.Combine(currentPrefs.DownloadFolder, video.Channel)
                                : currentPrefs.DownloadFolder;

                            string filename = _filenameService.SubstituteWildcards(currentPrefs.DownloadFileName, video, selectedQuality);
                            filename = _filenameService.EnsureExtension(filename, currentPrefs.DownloadDisableConversion);

                            DownloadParameters downloadParams = new DownloadParameters(video, qualities, selectedQuality, folder, filename, currentPrefs.DownloadDisableConversion);

                            if (video.StartTime.HasValue)
                            {
                                downloadParams.CropStartTime = video.StartTime.Value;
                            }

                            _navigationService.ShowDownload(downloadParams);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                _dialogService.ShowAndLogException(ex);
            }
        }
コード例 #2
0
 private void WriteVodAuthInfo(Action <string> log, TwitchVideoAuthInfo vodAuthInfo)
 {
     log(Environment.NewLine + Environment.NewLine + "ACCESS INFO");
     log(Environment.NewLine + "--------------------------------------------------------------------------------------------");
     log(Environment.NewLine + "Token: " + vodAuthInfo.Token);
     log(Environment.NewLine + "Signature: " + vodAuthInfo.Signature);
     log(Environment.NewLine + "Sub-Only: " + (vodAuthInfo.SubOnly ? "Yes" : "No"));
     log(Environment.NewLine + "Privileged: " + (vodAuthInfo.Privileged ? "Yes" : "No"));
 }
コード例 #3
0
        public Dictionary <TwitchVideoQuality, string> GetPlaylistInfo(string vodId, TwitchVideoAuthInfo vodAuthInfo)
        {
            using (WebClient webClient = CreateWebClientWithEncoding())
            {
                webClient.Headers.Add("Accept", "*/*");

                webClient.QueryString.Add("allow_source", "true");
                webClient.QueryString.Add("allow_audio_only", "true");
                webClient.QueryString.Add("token", vodAuthInfo.Token);
                webClient.QueryString.Add("sig", vodAuthInfo.Signature);

                string playlist = webClient.DownloadString(string.Format(PLAYLISTS_URL, vodId));

                List <string> lines = playlist.Split(new string[] { "\n" }, StringSplitOptions.RemoveEmptyEntries).ToList();

                Dictionary <TwitchVideoQuality, string> playlistInfo = new Dictionary <TwitchVideoQuality, string>();

                for (int i = 0; i < lines.Count; i++)
                {
                    string line = lines[i];

                    if (!line.StartsWith("#"))
                    {
                        string mediaInfo  = lines[i - 2];
                        string streamInfo = lines[i - 1];

                        Match  groupMatch = _rxGroup.Match(mediaInfo);
                        string id         = groupMatch.Groups["group"].Value;

                        Match  nameMatch = _rxName.Match(mediaInfo);
                        string name      = nameMatch.Groups["name"].Value;

                        string resolution = null;

                        Match resolutionMatch = _rxResolution.Match(streamInfo);

                        if (resolutionMatch.Success)
                        {
                            resolution = resolutionMatch.Groups["resolution"].Value;
                        }

                        TwitchVideoQuality quality = new TwitchVideoQuality(id, name, resolution);

                        playlistInfo.Add(quality, line);
                    }
                }

                return(playlistInfo);
            }
        }
コード例 #4
0
        private void StartQueuedDownloadIfExists()
        {
            if (_paused)
            {
                return;
            }

            if (Monitor.TryEnter(_changeDownloadLockObject))
            {
                try
                {
                    if (!_downloads.Where(d => d.DownloadState == DownloadState.Downloading).Any())
                    {
                        TwitchVideoDownload download = _downloads.Where(d => d.DownloadState == DownloadState.Queued).FirstOrDefault();

                        if (download == null)
                        {
                            return;
                        }

                        DownloadParameters downloadParams = download.DownloadParams;

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

                        string downloadId = download.Id;
                        string vodId      = downloadParams.Video.Id;
                        string tempDir    = Path.Combine(_preferencesService.CurrentPreferences.DownloadTempFolder, downloadId);
                        string ffmpegFile = _processingService.FFMPEGExe;
                        string concatFile = Path.Combine(tempDir, Path.GetFileNameWithoutExtension(downloadParams.FullPath) + ".ts");
                        string outputFile = downloadParams.FullPath;

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

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

                        TwitchVideoQuality quality = downloadParams.SelectedQuality;

                        Action <DownloadState> setDownloadState = download.SetDownloadState;
                        Action <string>        log                = download.AppendLog;
                        Action <string>        setStatus          = download.SetStatus;
                        Action <double>        setProgress        = download.SetProgress;
                        Action <bool>          setIsIndeterminate = download.SetIsIndeterminate;

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

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

                            WriteDownloadInfo(log, downloadParams, ffmpegFile, tempDir);

                            cancellationToken.ThrowIfCancellationRequested();

                            log(Environment.NewLine + Environment.NewLine + "Retrieving VOD access information...");
                            TwitchVideoAuthInfo vodAuthInfo = _apiService.GetVodAuthInfo(vodId);
                            log(" done!");

                            cancellationToken.ThrowIfCancellationRequested();

                            WriteVodAuthInfo(log, vodAuthInfo);

                            cancellationToken.ThrowIfCancellationRequested();

                            CheckTempDirectory(log, tempDir);

                            cancellationToken.ThrowIfCancellationRequested();

                            log(Environment.NewLine + Environment.NewLine + "Retrieving playlist information for all VOD qualities...");
                            Dictionary <TwitchVideoQuality, string> playlistInfo = _apiService.GetPlaylistInfo(vodId, vodAuthInfo);
                            log(" done!");

                            cancellationToken.ThrowIfCancellationRequested();

                            WritePlaylistInfo(log, playlistInfo);

                            cancellationToken.ThrowIfCancellationRequested();

                            TwitchPlaylist vodPlaylist = GetVodPlaylist(log, tempDir, playlistInfo, quality);

                            cancellationToken.ThrowIfCancellationRequested();

                            CropInfo cropInfo = CropVodPlaylist(vodPlaylist, cropStart, cropEnd, cropStartTime, cropEndTime);

                            cancellationToken.ThrowIfCancellationRequested();

                            DownloadParts(log, setStatus, setProgress, vodPlaylist, cancellationToken);

                            cancellationToken.ThrowIfCancellationRequested();

                            _processingService.ConcatParts(log, setStatus, setProgress, vodPlaylist, disableConversion ? outputFile : concatFile);

                            if (!disableConversion)
                            {
                                cancellationToken.ThrowIfCancellationRequested();
                                _processingService.ConvertVideo(log, setStatus, setProgress, setIsIndeterminate, concatFile, outputFile, cropInfo);
                            }
                        }, cancellationToken);

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

                            setProgress(100);
                            setIsIndeterminate(false);

                            bool success = false;

                            if (task.IsFaulted)
                            {
                                setDownloadState(DownloadState.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)
                            {
                                setDownloadState(DownloadState.Canceled);
                                log(Environment.NewLine + Environment.NewLine + "Download task was canceled!");
                            }
                            else
                            {
                                success = true;
                                setDownloadState(DownloadState.Done);
                                log(Environment.NewLine + Environment.NewLine + "Download task ended successfully!");
                            }

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

                            if (success && _preferencesService.CurrentPreferences.DownloadRemoveCompleted)
                            {
                                _eventAggregator.GetEvent <RemoveDownloadEvent>().Publish(downloadId);
                            }
                        });

                        if (_downloadTasks.TryAdd(downloadId, new DownloadTask(downloadVideoTask, continueTask, cancellationTokenSource)))
                        {
                            downloadVideoTask.Start();
                            setDownloadState(DownloadState.Downloading);
                        }
                    }
                }
                finally
                {
                    Monitor.Exit(_changeDownloadLockObject);
                }
            }
        }