private async Task <NicoVideoCacheRequest> CancelDownload(string videoId, NicoVideoQuality quality) { NicoVideoCacheProgress progress = null; using (var releaser2 = await _CacheRequestProcessingLock.LockAsync()) { progress = _DownloadOperations.FirstOrDefault(x => x.RawVideoId == videoId && x.Quality == quality); } if (progress == null) { return(null); } await RemoveDownloadOperation(progress); VideoCacheStateChanged?.Invoke(this, new VideoCacheStateChangedEventArgs() { Request = progress, CacheState = NicoVideoCacheState.NotCacheRequested }); return(progress); }
private async Task RestoreDonloadOperation(NicoVideoCacheProgress progress, DownloadOperation operation) { await AddDownloadOperation(progress); var action = operation.AttachAsync(); action.Progress = OnDownloadProgress; var task = action.AsTask() .ContinueWith(OnDownloadCompleted) .ConfigureAwait(false); }
/// <summary> /// キャッシュダウンロードのタスクから /// ダウンロードの情報を復元します /// </summary> /// <returns></returns> private async Task RestoreBackgroundDownloadTask() { // TODO: ユーザーのログイン情報を更新してダウンロードを再開する必要がある? // ユーザー情報の有効期限が切れていた場合には最初からダウンロードし直す必要があるかもしれません var tasks = await BackgroundDownloader.GetCurrentDownloadsForTransferGroupAsync(_NicoCacheVideoBGTransferGroup); foreach (var task in tasks) { NicoVideoCacheProgress info = null; try { var _info = VideoCacheManager.CacheRequestInfoFromFileName(task.ResultFile); var nicoVideo = new NicoVideo(_info.RawVideoId, _HohoemaApp.ContentProvider, _HohoemaApp.NiconicoContext, _HohoemaApp.CacheManager); var session = await nicoVideo.CreateVideoStreamingSession(_info.Quality, forceDownload : true); if (session?.Quality == _info.Quality) { continue; } info = new NicoVideoCacheProgress(_info, task, session); await RestoreDonloadOperation(info, task); Debug.WriteLine($"実行中のキャッシュBGDLを補足: {info.RawVideoId} {info.Quality}"); } catch { Debug.WriteLine(task.ResultFile + "のキャッシュダウンロード操作を復元に失敗しました"); continue; } try { task.Resume(); } catch { if (task.Progress.Status != BackgroundTransferStatus.Running) { await RemoveDownloadOperation(info); // ダウンロード再開に失敗したらキャッシュリクエストに積み直します // 失敗の通知はここではなくバックグラウンドタスクの 後処理 として渡されるかもしれません DownloadProgress?.Invoke(this, info); } } } }
/// <summary> /// キャッシュダウンロードのタスクから /// ダウンロードの情報を復元します /// </summary> /// <returns></returns> private async Task RestoreBackgroundDownloadTask() { // TODO: ユーザーのログイン情報を更新してダウンロードを再開する必要がある? // ユーザー情報の有効期限が切れていた場合には最初からダウンロードし直す必要があるかもしれません var tasks = await BackgroundDownloader.GetCurrentDownloadsAsync(); foreach (var task in tasks) { NicoVideoCacheProgress info = null; try { var _info = NiconicoMediaManager.CacheRequestInfoFromFileName(task.ResultFile); info = new NicoVideoCacheProgress() { RawVideoId = _info.RawVideoId, Quality = _info.Quality, DownloadOperation = task }; await RestoreDonloadOperation(_info, task); Debug.WriteLine($"実行中のキャッシュBGDLを補足: {info.RawVideoId} {info.Quality}"); } catch { Debug.WriteLine(task.ResultFile + "のキャッシュダウンロード操作を復元に失敗しました"); continue; } try { task.Resume(); } catch { if (task.Progress.Status != BackgroundTransferStatus.Running) { await RemoveDownloadOperation(info); // ダウンロード再開に失敗したらキャッシュリクエストに積み直します // 失敗の通知はここではなくバックグラウンドタスクの 後処理 として渡されるかもしれません await AddCacheRequest(info.RawVideoId, info.Quality, forceUpdate : true); } } } }
private async Task RemoveDownloadOperation(NicoVideoCacheProgress req) { if (_DownloadOperations.Remove(req)) { req.Session?.Dispose(); var op = req.DownloadOperation; if (op.Progress.BytesReceived != op.Progress.TotalBytesToReceive) { op.AttachAsync().Cancel(); await op.ResultFile.DeleteAsync(); } } else { return; } }
// 次のキャッシュダウンロードを試行 // ダウンロード用の本数 private async Task TryNextCacheRequestedVideoDownload() { if (State != CacheManagerState.Running) { return; } NicoVideoCacheRequest nextDownloadItem = null; using (var releaser = await _CacheRequestProcessingLock.LockAsync()) { while (CanAddDownloadLine) { if (_DownloadOperations.Count == 0) { nextDownloadItem = _CacheDownloadPendingVideos .FirstOrDefault(); } if (nextDownloadItem == null) { break; } if (_DownloadOperations.Any(x => x.RawVideoId == nextDownloadItem.RawVideoId && x.Quality == nextDownloadItem.Quality)) { _CacheDownloadPendingVideos.Remove(nextDownloadItem); break; } Debug.WriteLine($"キャッシュ準備を開始: {nextDownloadItem.RawVideoId} {nextDownloadItem.Quality}"); // 動画ダウンロードURLを取得 var nicoVideo = new NicoVideo(nextDownloadItem.RawVideoId, _HohoemaApp.ContentProvider, _HohoemaApp.NiconicoContext, _HohoemaApp.CacheManager); var videoInfo = await _HohoemaApp.ContentProvider.GetNicoVideoInfo(nextDownloadItem.RawVideoId); // DownloadSessionを保持して、再生完了時にDisposeさせる必要がある var downloadSession = await nicoVideo.CreateVideoStreamingSession(nextDownloadItem.Quality, forceDownload : true); var uri = await downloadSession.GetDownloadUrlAndSetupDonwloadSession(); var downloader = new BackgroundDownloader() { TransferGroup = _NicoCacheVideoBGTransferGroup }; downloader.SuccessToastNotification = MakeSuccessToastNotification(videoInfo); downloader.FailureToastNotification = MakeFailureToastNotification(videoInfo); // 保存先ファイルの確保 var filename = VideoCacheManager.MakeCacheVideoFileName( videoInfo.Title, nextDownloadItem.RawVideoId, videoInfo.MovieType, downloadSession.Quality ); var videoFolder = await _HohoemaApp.GetVideoCacheFolder(); var videoFile = await videoFolder.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists); // ダウンロード操作を作成 var operation = downloader.CreateDownload(uri, videoFile); var progress = new NicoVideoCacheProgress(nextDownloadItem, operation, downloadSession); await AddDownloadOperation(progress); Debug.WriteLine($"キャッシュ準備完了: {nextDownloadItem.RawVideoId} {nextDownloadItem.Quality}"); // ダウンロードを開始 /* * if (Helpers.ApiContractHelper.IsFallCreatorsUpdateAvailable) * { * operation.IsRandomAccessRequired = true; * } */ var action = operation.StartAsync(); action.Progress = OnDownloadProgress; var task = action.AsTask(); TaskIdToCacheProgress.Add(task.Id, progress); var _ = task.ContinueWith(OnDownloadCompleted); VideoCacheStateChanged?.Invoke(this, new VideoCacheStateChangedEventArgs() { CacheState = NicoVideoCacheState.Downloading, Request = progress }); Debug.WriteLine($"キャッシュ開始: {nextDownloadItem.RawVideoId} {nextDownloadItem.Quality}"); SendUpdatableToastWithProgress(videoInfo.Title, nextDownloadItem); // DL作業を作成できたらDL待ちリストから削除 _CacheDownloadPendingVideos.Remove(nextDownloadItem); await SaveDownloadRequestItems(); } } }
private Task AddDownloadOperation(NicoVideoCacheProgress req) { _DownloadOperations.Add(req); return(Task.CompletedTask); }