Пример #1
0
        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);
        }
Пример #2
0
 internal VideoCacheItem(
     VideoCacheManager videoCacheManager,
     string videoId,
     string fileName,
     string title,
     NicoVideoQuality requestedQuality,
     NicoVideoQuality downloadedQuality,
     VideoCacheStatus status,
     VideoCacheDownloadOperationFailedReason failedReason,
     DateTime requestAt,
     long?totalBytes,
     long?progressBytes,
     int sortIndex
     )
 {
     _videoCacheManager = videoCacheManager;
     VideoId            = videoId;
     FileName           = fileName;
     Title = title;
     RequestedVideoQuality  = requestedQuality;
     DownloadedVideoQuality = downloadedQuality;
     Status        = status;
     FailedReason  = failedReason;
     TotalBytes    = totalBytes;
     ProgressBytes = progressBytes;
     RequestedAt   = requestAt;
     SortIndex     = sortIndex;
 }
Пример #3
0
 public CacheRequest(string videoId, DateTime requestAt, NicoVideoCacheState cacheState = NicoVideoCacheState.NotCacheRequested, NicoVideoQuality priorityQuality = NicoVideoQuality.Unknown)
 {
     VideoId         = videoId;
     CacheState      = cacheState;
     RequestAt       = requestAt;
     PriorityQuality = priorityQuality;
 }
Пример #4
0
        public async Task PlayAsync(NicoVideoQuality quality = NicoVideoQuality.Unknown, TimeSpan startPosition = default)
        {
            if (_niconicoVideoSessionProvider == null) { throw new ArgumentException("please call VideoPlayer.UpdatePlayingVideo() before VideoPlayer.PlayAsync()."); }

            if ((_currentSession as IVideoStreamingSession)?.Quality == quality)
            {
                return;
            }

            _currentSession?.Dispose();

            _currentSession = await _niconicoVideoSessionProvider.CreateVideoSessionAsync(quality);
            if (_currentSession is IVideoStreamingSession videoStreamingSession)
            {
                CurrentQuality = AvailableQualities.First(x => x.Quality == videoStreamingSession.Quality);
            }
            if (_currentSession is LocalVideoStreamingSession)
            {
                IsPlayWithCache.Value = true;
            }

            NowPlayingWithDmcVideo = _currentSession is Models.DmcVideoStreamingSession;
            
            await _currentSession.StartPlayback(_mediaPlayer, startPosition);
        }
Пример #5
0
 public async Task <NicoVideoCacheProgress> GetCacheProgress(string videoId, NicoVideoQuality quality)
 {
     using (var releaser2 = await _CacheRequestProcessingLock.LockAsync())
     {
         return(_DownloadOperations.FirstOrDefault(x => x.RawVideoId == videoId && x.Quality == quality));
     }
 }
Пример #6
0
 public NicoVideoCached(string videoId, NicoVideoQuality quality, DateTime requestAt, IStorageFile file)
 {
     VideoId   = videoId;
     Quality   = quality;
     RequestAt = requestAt;
     File      = file;
 }
 public LocalVideoStreamingSession(IStorageFile file, NicoVideoQuality requestQuality, NiconicoSession niconicoSession)
     : base(niconicoSession, null)
 {
     File      = file;
     Quality   = requestQuality;
     QualityId = requestQuality.ToString();
 }
Пример #8
0
        public async Task ChangeQualityAsync(NicoVideoQuality quality)
        {
            if (CurrentPlaylistItem == null)
            {
                return;
            }

            if (CurrentPlayingSession?.IsSuccess is null or false)
            {
                return;
            }

            var currentPosition = GetCurrentPlaybackPosition();

            _videoSessionDisposable?.Dispose();
            _videoSessionDisposable = null;

            var quelityEntity = AvailableQualities.First(x => x.Quality == quality);

            if (quelityEntity.IsAvailable is false)
            {
                throw new HohoemaExpception("unavailable video quality : " + quality);
            }

            var videoSession = await CurrentPlayingSession.VideoSessionProvider.CreateVideoSessionAsync(quality);

            _videoSessionDisposable = videoSession;
            await videoSession.StartPlayback(_mediaPlayer, currentPosition ?? TimeSpan.Zero);

            CurrentQuality = quelityEntity;

            _playerSettings.DefaultVideoQuality = quality;
            Guard.IsNotNull(_mediaPlayer.PlaybackSession, nameof(_mediaPlayer.PlaybackSession));
        }
Пример #9
0
        public static string FileNameWithQualityNameExtention(this NicoVideoQuality quality, string filename)
        {
            var toQualityNameExtention = filename;

            switch (quality)
            {
            case NicoVideoQuality.Original:
                toQualityNameExtention = Path.ChangeExtension(filename, ".mp4");
                break;

            case NicoVideoQuality.Low:
                toQualityNameExtention = Path.ChangeExtension(filename, ".low.mp4");
                break;

            case NicoVideoQuality.Dmc_Low:
                toQualityNameExtention = Path.ChangeExtension(filename, ".xlow.mp4");
                break;

            case NicoVideoQuality.Dmc_Midium:
                toQualityNameExtention = Path.ChangeExtension(filename, ".xmid.mp4");
                break;

            case NicoVideoQuality.Dmc_High:
                toQualityNameExtention = Path.ChangeExtension(filename, ".xhigh.mp4");
                break;

            default:
                throw new NotSupportedException(quality.ToString());
            }

            return(toQualityNameExtention);
        }
 public CachedVideoStreamingSession(VideoCacheItem videoCacheItem, NiconicoSession niconicoSession)
     : base(niconicoSession, null)
 {
     Quality         = videoCacheItem.DownloadedVideoQuality;
     QualityId       = Quality.ToString();
     _videoCacheItem = videoCacheItem;
 }
Пример #11
0
        public async Task <bool> CancelCacheRequest(string rawVideoId, NicoVideoQuality quality)
        {
            bool removed = false;
            var  items   = await GetCacheRequest(rawVideoId);

            var item = items.FirstOrDefault(x => x.Quality == quality);

            if (item != null)
            {
                switch (item.ToCacheState())
                {
                case NicoVideoCacheState.Pending:
                    using (var releaser2 = await _CacheRequestProcessingLock.LockAsync())
                    {
                        var removeTarget = _CacheDownloadPendingVideos.FirstOrDefault(x => x.RawVideoId == rawVideoId && x.Quality == quality);
                        removed = _CacheDownloadPendingVideos.Remove(removeTarget);
                        await SaveDownloadRequestItems();
                    }
                    break;

                case NicoVideoCacheState.Downloading:
                    var canceledReq = await CancelDownload(rawVideoId, quality);

                    await Task.Delay(500);

                    using (var releaser2 = await _CacheRequestProcessingLock.LockAsync())
                    {
                        var removeTarget = _CacheDownloadPendingVideos.FirstOrDefault(x => x.RawVideoId == rawVideoId && x.Quality == quality);
                        removed = _CacheDownloadPendingVideos.Remove(removeTarget);
                        await SaveDownloadRequestItems();
                    }
                    removed = canceledReq != null;
                    break;

                case NicoVideoCacheState.Cached:
                    removed = await DeleteCachedVideo(rawVideoId, quality);

                    break;

                default:
                    break;
                }
            }

            if (removed)
            {
                RequestCanceled?.Invoke(this, item);
                VideoCacheStateChanged?.Invoke(this, new VideoCacheStateChangedEventArgs()
                {
                    CacheState = NicoVideoCacheState.NotCacheRequested,
                    Request    = item
                });

                return(true);
            }
            else
            {
                return(false);
            }
        }
Пример #12
0
        public async Task <bool> RemoveCacheRequest(string rawVideoId, NicoVideoQuality quality)
        {
            NicoVideoCacheRequest removeTarget = null;

            using (var pendingVideoLockReleaser = await _CacheDownloadPendingVideosLock.LockAsync())
            {
                removeTarget = _CacheDownloadPendingVideos.SingleOrDefault(x => x.RawVideoId == rawVideoId && x.Quality == quality);
            }

            // ダウンロード中タスクを削除(DLのキャンセル)

            bool removed = false;

            if (removeTarget != null)
            {
                await RemoveDownloadOperation(removeTarget);

                using (var pendingVideoLockReleaser = await _CacheDownloadPendingVideosLock.LockAsync())
                {
                    _CacheDownloadPendingVideos.Remove(removeTarget);
                }

                await SaveDownloadRequestItems();

                RequestCanceled?.Invoke(this, removeTarget);

                removed = true;
            }

            await TryNextCacheRequestedVideoDownload();

            return(removed);
        }
Пример #13
0
        public DmcVideoStreamingSession(DmcWatchData res, NicoVideoQuality requestQuality, NiconicoContext context)
            : base(context)
        {
            RequestedQuality = requestQuality;
            _DmcWatchData    = res;
            DmcWatchResponse = res.DmcWatchResponse;

#if DEBUG
            Debug.WriteLine($"Id/Bitrate/Resolution/Available");
            foreach (var q in _DmcWatchData.DmcWatchResponse.Video.DmcInfo.Quality.Videos)
            {
                Debug.WriteLine($"{q.Id}/{q.Bitrate}/{q.Available}/{q.Resolution}");
            }
#endif

            VideoContent = ResetActualQuality();

            if (VideoContent == null || !VideoContent.Available)
            {
                VideoContent = DmcWatchResponse.Video.DmcInfo.Quality.Videos.FirstOrDefault(x => x.Available);
                _Quality     = NicoVideoVideoContentHelper.VideoContentToQuality(VideoContent);
            }
            else
            {
                _Quality = requestQuality;
            }

            if (VideoContent != null)
            {
                Debug.WriteLine($"quality={_Quality}");
                Debug.WriteLine($"{VideoContent.Id}/{VideoContent.Bitrate}/{VideoContent.Available}/w={VideoContent.Resolution.Width} h={VideoContent.Resolution.Height}");
            }
        }
Пример #14
0
 public DividedQualityNicoVideo(NicoVideoQuality quality, NicoVideo nicoVideo, NiconicoMediaManager mediaManager)
 {
     Quality              = quality;
     NicoVideo            = nicoVideo;
     HohoemaApp           = nicoVideo.HohoemaApp;
     NiconicoMediaManager = mediaManager;
     VideoDownloadManager = mediaManager.VideoDownloadManager;
 }
        /// <summary>
        /// 動画ストリームの取得します
        /// </summary>
        /// <exception cref="NotSupportedException" />
        public async Task <IStreamingSession> CreateVideoSessionAsync(NicoVideoQuality quality = NicoVideoQuality.Unknown)
        {
            IStreamingSession streamingSession = null;

            if (_watchApiResponse != null)
            {
                var ownership = await _ownershipManager.TryRentVideoSessionOwnershipAsync(_watchApiResponse.videoDetail.id, !IsForCacheDownload);

                if (ownership != null)
                {
                    streamingSession = new SmileVideoStreamingSession(
                        _watchApiResponse.VideoUrl,
                        _niconicoSession,
                        ownership
                        );
                }
            }
            else if (_dmcWatchData != null)
            {
                if (_dmcWatchData.DmcWatchResponse.Video.DmcInfo != null)
                {
                    var qualityEntity = AvailableQualities.Where(x => x.IsAvailable).FirstOrDefault(x => x.Quality == quality);
                    if (qualityEntity == null)
                    {
                        qualityEntity = AvailableQualities.Where(x => x.IsAvailable).First();
                    }

                    var ownership = await _ownershipManager.TryRentVideoSessionOwnershipAsync(_dmcWatchData.DmcWatchResponse.Video.Id, !IsForCacheDownload);

                    if (ownership != null)
                    {
                        streamingSession = new DmcVideoStreamingSession(qualityEntity.QualityId, _dmcWatchData, _niconicoSession, ownership);
                    }
                }
                else if (_dmcWatchData.DmcWatchResponse.Video.SmileInfo != null)
                {
                    var ownership = await _ownershipManager.TryRentVideoSessionOwnershipAsync(_dmcWatchData.DmcWatchResponse.Video.Id, !IsForCacheDownload);

                    if (ownership != null)
                    {
                        streamingSession = new SmileVideoStreamingSession(
                            new Uri(_dmcWatchData.DmcWatchResponse.Video.SmileInfo.Url), _niconicoSession, ownership);
                    }
                }
                else
                {
                    throw new NotSupportedException("動画ページ情報から動画ファイルURLを検出できませんでした");
                }
            }
            else
            {
                throw new NotSupportedException("動画の再生準備に失敗(動画ページの解析でエラーが発生)");
            }

            return(streamingSession);
        }
Пример #16
0
        /// <summary>
        /// キャッシュリクエストをキューの最後尾に積みます
        /// 通常のダウンロードリクエストではこちらを利用します
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public Task AddCacheRequest(string rawVideoId, NicoVideoQuality quality, bool forceUpdate = false)
        {
            var req = new NicoVideoCacheRequest()
            {
                RawVideoId = rawVideoId,
                Quality    = quality,
                RequestAt  = DateTime.Now
            };

            return(AddCacheRequest(req, forceUpdate));
        }
Пример #17
0
        /// <summary>
        /// キャッシュリクエストをキューの最後尾に積みます
        /// 通常のダウンロードリクエストではこちらを利用します
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        public Task RequestCache(string rawVideoId, NicoVideoQuality quality = NicoVideoQuality.Unknown, bool forceUpdate = false)
        {
            var req = new NicoVideoCacheRequest()
            {
                RawVideoId = rawVideoId,
                Quality    = quality,
                RequestAt  = DateTime.Now
            };

            return(RequestCache(req));
        }
Пример #18
0
 public NicoVideoCacheInfo GetCacheInfo(string videoId, NicoVideoQuality quality)
 {
     if (_CacheVideos.TryGetValue(videoId, out var list))
     {
         return(list.FirstOrDefault(x => x.Quality == quality));
     }
     else
     {
         return(null);
     }
 }
Пример #19
0
 internal NicoVideoQualityEntity(
     bool isAvailable, NicoVideoQuality quality, string qualityId,
     int?bitrate = null, int?width = null, int?height = null
     )
 {
     IsAvailable = isAvailable;
     Quality     = quality;
     QualityId   = qualityId;
     Bitrate     = bitrate;
     Width       = width;
     Height      = height;
 }
Пример #20
0
        public NicoVideoCacheProgress(DownloadOperation op, IVideoStreamingDownloadSession session, string videoId, NicoVideoQuality quality, DateTime requestAt)
        {
            DownloadOperation = op;
            Session           = session;
            VideoId           = videoId;
            Quality           = quality;
            RequestAt         = requestAt;

            _nicoVideo = Database.NicoVideoDb.Get(VideoId);
            SendUpdatableToastWithProgress();

            Progress = 0.0;
            _invertedProgressTotal = 1.0 / op.Progress.TotalBytesToReceive;
        }
Пример #21
0
        public async Task RestoreCache(NicoVideoQuality quality, string filepath)
        {
            var divided = GetDividedQualityNicoVideo(quality);

            await FillVideoInfoFromDb();

            await divided.RestoreCache(filepath);

            await divided.RequestCache();

            if (divided.VideoFileCreatedAt > this.CachedAt)
            {
                this.CachedAt = divided.VideoFileCreatedAt;
            }
        }
Пример #22
0
        public DividedQualityNicoVideo GetDividedQualityNicoVideo(NicoVideoQuality quality)
        {
            DividedQualityNicoVideo qualityDividedVideo = null;

            if (_InterfaceByQuality.ContainsKey(quality))
            {
                qualityDividedVideo = _InterfaceByQuality[quality];
            }
            else
            {
                switch (quality)
                {
                case NicoVideoQuality.Original:
                    qualityDividedVideo = new OriginalQualityNicoVideo(this, _NiconicoMediaManager);
                    break;

                case NicoVideoQuality.Low:
                    qualityDividedVideo = new LowQualityNicoVideo(this, _NiconicoMediaManager);
                    break;

                case NicoVideoQuality.Dmc_High:
                    qualityDividedVideo = new DmcQualityNicoVideo(quality, this, _NiconicoMediaManager);
                    break;

                case NicoVideoQuality.Dmc_Midium:
                    qualityDividedVideo = new DmcQualityNicoVideo(quality, this, _NiconicoMediaManager);
                    break;

                case NicoVideoQuality.Dmc_Low:
                    qualityDividedVideo = new DmcQualityNicoVideo(quality, this, _NiconicoMediaManager);
                    break;

                case NicoVideoQuality.Dmc_Mobile:
                    qualityDividedVideo = new DmcQualityNicoVideo(quality, this, _NiconicoMediaManager);
                    break;

                default:
                    throw new NotSupportedException(quality.ToString());
                }

                _InterfaceByQuality.Add(quality, qualityDividedVideo);
                _QualityDividedVideos.Add(qualityDividedVideo);
            }

            return(qualityDividedVideo);
        }
Пример #23
0
        public DmcVideoStreamingSession(string qualityId, DmcWatchApiData res, NiconicoSession niconicoSession, NicoVideoSessionOwnershipManager.VideoSessionOwnership videoSessionOwnership, bool forCacheDownload = false)
            : base(niconicoSession, videoSessionOwnership)
        {
            _dmcWatchData     = res;
            _forCacheDownload = forCacheDownload;
            QualityId         = qualityId;
            Quality           = res.ToNicoVideoQuality(qualityId);

#if DEBUG
            Debug.WriteLine($"Id/Bitrate/Resolution/Available");
            foreach (var q in _dmcWatchData.Media.Delivery.Movie.Videos)
            {
                Debug.WriteLine($"{q.Id}/{q.Metadata.Bitrate}/{q.IsAvailable}/{q.Metadata.Resolution}");
            }
#endif

            VideoContent = _dmcWatchData.Media.Delivery.Movie.Videos.FirstOrDefault(x => x.Id == qualityId);

            if (VideoContent != null)
            {
                Debug.WriteLine($"{VideoContent.Id}/{VideoContent.Metadata.Bitrate}/{VideoContent.IsAvailable}/w={VideoContent.Metadata.Resolution.Width} h={VideoContent.Metadata.Resolution.Height}");
            }
        }
Пример #24
0
        public async Task <bool> DeleteCachedVideo(string videoId, NicoVideoQuality quality)
        {
            using (var releaser = await _CacheRequestProcessingLock.LockAsync())
            {
                if (_CacheVideos.TryGetValue(videoId, out var cachedItems))
                {
                    var removeCached = cachedItems.FirstOrDefault(x => x.RawVideoId == videoId && x.Quality == quality);
                    if (removeCached != null)
                    {
                        var result = await removeCached.Delete();

                        if (result)
                        {
                            cachedItems.Remove(removeCached);
                        }

                        if (cachedItems.Count == 0)
                        {
                            _CacheVideos.TryRemove(videoId, out var list);
                        }

                        RequestCanceled?.Invoke(this, removeCached);
                        VideoCacheStateChanged?.Invoke(this, new VideoCacheStateChangedEventArgs()
                        {
                            CacheState = NicoVideoCacheState.NotCacheRequested,
                            Request    = removeCached
                        });


                        return(result);
                    }
                }

                return(false);
            }
        }
        public DmcVideoStreamingSession(string qualityId, DmcWatchData res, NiconicoSession niconicoSession, NicoVideoSessionOwnershipManager.VideoSessionOwnership videoSessionOwnership)
            : base(niconicoSession, videoSessionOwnership)
        {
            _DmcWatchData    = res;
            DmcWatchResponse = res.DmcWatchResponse;

            QualityId = qualityId;
            Quality   = res.ToNicoVideoQuality(qualityId);

#if DEBUG
            Debug.WriteLine($"Id/Bitrate/Resolution/Available");
            foreach (var q in _DmcWatchData.DmcWatchResponse.Video.DmcInfo.Quality.Videos)
            {
                Debug.WriteLine($"{q.Id}/{q.Bitrate}/{q.Available}/{q.Resolution}");
            }
#endif

            VideoContent = DmcWatchResponse.Video.DmcInfo.Quality.Videos.FirstOrDefault(x => x.Id == qualityId);

            if (VideoContent != null)
            {
                Debug.WriteLine($"{VideoContent.Id}/{VideoContent.Bitrate}/{VideoContent.Available}/w={VideoContent.Resolution.Width} h={VideoContent.Resolution.Height}");
            }
        }
Пример #26
0
 public static bool IsDmc(this NicoVideoQuality quality)
 {
     return(!IsLegacy(quality));
 }
Пример #27
0
 public static bool IsLegacy(this NicoVideoQuality quality)
 {
     return(quality == NicoVideoQuality.Low || quality == NicoVideoQuality.Original);
 }
        /// <summary>
        /// 動画ストリームの取得します
        /// 他にダウンロードされているアイテムは強制的に一時停止し、再生終了後に再開されます
        /// </summary>
        /// <exception cref="NotSupportedException" />
        public async Task <IStreamingSession> CreateStreamingSessionAsync(string contentId, NicoVideoQuality requestedQuality = NicoVideoQuality.Unknown)
        {
            // オンラインの場合は削除済みかを確認する
            object watchRes = null;

            if (Helpers.InternetConnection.IsInternet())
            {
                // 動画視聴ページへアクセス
                // 動画再生準備およびコメント取得準備が行われる
                watchRes = await VisitWatchPage(contentId);

                // 動画情報ページアクセスだけでも内部の動画情報データは更新される
                var videoInfo = Database.NicoVideoDb.Get(contentId);

                if (videoInfo.IsDeleted)
                {
                    // ニコニコサーバー側で動画削除済みの場合は再生不可
                    // (NicoVideoProvider側で動画削除動作を実施している)
                    throw new NotSupportedException($"動画は {videoInfo.PrivateReasonType.ToCulturelizeString()} のため視聴できません");
                }
            }

            if (watchRes is WatchApiResponse)
            {
                var res = watchRes as WatchApiResponse;
                if (res.flashvars.movie_type == "swf")
                {
                    throw new NotSupportedException("SWF形式の動画はサポートしていません");
                }

                if (res.VideoUrl.OriginalString.StartsWith("rtmp"))
                {
                    throw new NotSupportedException("RTMP形式の動画はサポートしていません");
                }

                if (res.IsDeleted)
                {
                    throw new NotSupportedException("動画は削除されています");
                }

                return(new SmileVideoStreamingSession(
                           res.VideoUrl,
                           NiconicoSession
                           ));
            }
            else if (watchRes is DmcWatchData)
            {
                var res = watchRes as DmcWatchData;

                if (res.DmcWatchResponse.Video.IsDeleted)
                {
                    throw new NotSupportedException("動画は削除されています");
                }

                if (res.DmcWatchResponse.Video.DmcInfo != null)
                {
                    if (res.DmcWatchResponse.Video?.DmcInfo?.Quality == null)
                    {
                        throw new NotSupportedException("動画の視聴権がありません");
                    }

                    return(new DmcVideoStreamingSession(
                               res,
                               requestedQuality,
                               NiconicoSession
                               ));
                }
                else if (res.DmcWatchResponse.Video.SmileInfo != null)
                {
                    return(new SmileVideoStreamingSession(
                               new Uri(res.DmcWatchResponse.Video.SmileInfo.Url),
                               NiconicoSession
                               ));
                }
                else
                {
                    throw new NotSupportedException("動画ページ情報から動画ファイルURLを検出できませんでした");
                }
            }
            else
            {
                throw new NotSupportedException("動画の再生準備に失敗(動画ページの解析でエラーが発生)");
            }
        }
 public LocalVideoStreamingSession(StorageFile file, NicoVideoQuality requestQuality, NiconicoSession niconicoSession)
     : base(niconicoSession)
 {
     File    = file;
     Quality = requestQuality;
 }
Пример #30
0
 public DownloadProgressVideoStreamingSession(IRandomAccessStreamReference streamRef, NicoVideoQuality requestQuality)
 {
     StreamRef = streamRef;
     Quality   = requestQuality;
 }