/// <summary> /// Download a movie asynchronously /// </summary> /// <param name="movie">The movie to download</param> /// <param name="downloadProgress">Report download progress</param> /// <param name="downloadRate">Report download rate</param> /// <param name="ct">Cancellation token</param> private async Task DownloadMovieAsync(MovieFull movie, IProgress<double> downloadProgress, IProgress<double> downloadRate, CancellationTokenSource ct) { await Task.Run(async () => { using (var session = new session()) { Logger.Info( $"Start downloading movie : {movie.Title}"); IsDownloadingMovie = true; downloadProgress?.Report(0d); downloadRate?.Report(0d); session.listen_on(6881, 6889); var torrentUrl = movie.WatchInFullHdQuality ? movie.Torrents?.FirstOrDefault(torrent => torrent.Quality == "1080p")?.Url : movie.Torrents?.FirstOrDefault(torrent => torrent.Quality == "720p")?.Url; var result = await DownloadFileHelper.DownloadFileTaskAsync(torrentUrl, Constants.TorrentDownloads + movie.ImdbCode + ".torrent", ct: ct); var torrentPath = string.Empty; if (result.Item3 == null && !string.IsNullOrEmpty(result.Item2)) torrentPath = result.Item2; var addParams = new add_torrent_params { save_path = Constants.MovieDownloads, ti = new torrent_info(torrentPath) }; var handle = session.add_torrent(addParams); handle.set_upload_limit(_settingsViewModel.DownloadLimit*1024); handle.set_download_limit(_settingsViewModel.UploadLimit*1024); // We have to download sequentially, so that we're able to play the movie without waiting handle.set_sequential_download(true); var alreadyBuffered = false; while (IsDownloadingMovie) { var status = handle.status(); var progress = status.progress*100d; downloadProgress?.Report(progress); downloadRate?.Report(Math.Round(status.download_rate/1024d, 0)); handle.flush_cache(); if (handle.need_save_resume_data()) handle.save_resume_data(1); if (progress >= Constants.MinimumBufferingBeforeMoviePlaying && !alreadyBuffered) { // Get movie file foreach ( var filePath in Directory.GetFiles(status.save_path + handle.torrent_file().name(), "*" + Constants.VideoFileExtension) ) { alreadyBuffered = true; movie.FilePath = new Uri(filePath); Messenger.Default.Send(new PlayMovieMessage(movie)); } } try { await Task.Delay(1000, ct.Token); } catch (TaskCanceledException) { return; } } } }, ct.Token); }
/// <summary> /// Download a movie asynchronously /// </summary> /// <param name="movie">The movie to download</param> /// <param name="downloadProgress">Report download progress</param> /// <param name="downloadRate">Report download rate</param> /// <param name="ct">Cancellation token</param> private async Task DownloadMovieAsync(MovieFull movie, IProgress <double> downloadProgress, IProgress <double> downloadRate, CancellationTokenSource ct) { await Task.Run(async() => { using (var session = new session()) { Logger.Info( $"Start downloading movie : {movie.Title}"); IsDownloadingMovie = true; downloadProgress?.Report(0d); downloadRate?.Report(0d); session.listen_on(6881, 6889); var torrentUrl = movie.WatchInFullHdQuality ? movie.Torrents?.FirstOrDefault(torrent => torrent.Quality == "1080p")?.Url : movie.Torrents?.FirstOrDefault(torrent => torrent.Quality == "720p")?.Url; var result = await DownloadFileHelper.DownloadFileTaskAsync(torrentUrl, Constants.TorrentDownloads + movie.ImdbCode + ".torrent", ct: ct); var torrentPath = string.Empty; if (result.Item3 == null && !string.IsNullOrEmpty(result.Item2)) { torrentPath = result.Item2; } var addParams = new add_torrent_params { save_path = Constants.MovieDownloads, ti = new torrent_info(torrentPath) }; var handle = session.add_torrent(addParams); handle.set_upload_limit(_settingsViewModel.DownloadLimit * 1024); handle.set_download_limit(_settingsViewModel.UploadLimit * 1024); // We have to download sequentially, so that we're able to play the movie without waiting handle.set_sequential_download(true); var alreadyBuffered = false; while (IsDownloadingMovie) { var status = handle.status(); var progress = status.progress * 100d; downloadProgress?.Report(progress); downloadRate?.Report(Math.Round(status.download_rate / 1024d, 0)); handle.flush_cache(); if (handle.need_save_resume_data()) { handle.save_resume_data(1); } if (progress >= Constants.MinimumBufferingBeforeMoviePlaying && !alreadyBuffered) { // Get movie file foreach ( var filePath in Directory.GetFiles(status.save_path + handle.torrent_file().name(), "*" + Constants.VideoFileExtension) ) { alreadyBuffered = true; movie.FilePath = new Uri(filePath); Messenger.Default.Send(new PlayMovieMessage(movie)); } } try { await Task.Delay(1000, ct.Token); } catch (TaskCanceledException) { return; } } } }, ct.Token); }
/// <summary> /// Download a torrent /// </summary> /// <returns><see cref="Task"/></returns> public async Task Download(T media, TorrentType torrentType, MediaType mediaType, string torrentPath, int uploadLimit, int downloadLimit, IProgress <double> downloadProgress, IProgress <BandwidthRate> bandwidthRate, IProgress <int> nbSeeds, IProgress <int> nbPeers, Action buffered, Action cancelled, CancellationTokenSource cts) { _logger.Info( $"Start downloading : {torrentPath}"); await Task.Run(async() => { using (var session = new session()) { var settings = session.settings(); settings.anonymous_mode = true; downloadProgress.Report(0d); bandwidthRate.Report(new BandwidthRate { DownloadRate = 0d, UploadRate = 0d }); nbSeeds.Report(0); nbPeers.Report(0); session.listen_on(Constants.TorrentMinPort, Constants.TorrentMaxPort); string savePath = string.Empty; switch (mediaType) { case MediaType.Movie: savePath = Constants.MovieDownloads; break; case MediaType.Show: savePath = Constants.ShowDownloads; break; case MediaType.Unkown: savePath = Constants.DropFilesDownloads; break; } if (torrentType == TorrentType.File) { using (var addParams = new add_torrent_params { save_path = savePath, ti = new torrent_info(torrentPath) }) using (var handle = session.add_torrent(addParams)) { await HandleDownload(media, mediaType, uploadLimit, downloadLimit, downloadProgress, bandwidthRate, nbSeeds, nbPeers, handle, session, buffered, cancelled, cts); } } else { var magnet = new magnet_uri(); using (var error = new error_code()) { var addParams = new add_torrent_params { save_path = savePath, }; magnet.parse_magnet_uri(torrentPath, addParams, error); using (var handle = session.add_torrent(addParams)) { await HandleDownload(media, mediaType, uploadLimit, downloadLimit, downloadProgress, bandwidthRate, nbSeeds, nbPeers, handle, session, buffered, cancelled, cts); } } } } }); }