internal PlayingOrchestrateResult(INiconicoVideoSessionProvider vss, INiconicoCommentSessionProvider <VideoComment> cs, INicoVideoDetails videoDetails)
 {
     IsSuccess              = vss != null;
     VideoSessionProvider   = vss;
     CommentSessionProvider = cs;
     VideoDetails           = videoDetails;
 }
        public async Task InitializeRelatedVideos(INicoVideoDetails currentVideo)
        {
            NowLoading = true;
            OnPropertyChanged(nameof(NowLoading));
            try
            {
                using (var releaser = await _InitializeLock.LockAsync())
                {
                    if (_IsInitialized)
                    {
                        return;
                    }
                    _IsInitialized = true;

                    var result = await _relatedVideoContentsAggregator.GetRelatedContentsAsync(currentVideo);

                    CurrentVideo?.Dispose();
                    CurrentVideo = new VideoListItemControlViewModel(currentVideo);
                    OnPropertyChanged(nameof(CurrentVideo));

                    Videos = result.OtherVideos;
                    OnPropertyChanged(nameof(Videos));

                    if (currentVideo.Series?.Video.Next is not null and NvapiVideoItem nextSeriesVideo)
                    {
                        NextVideo?.Dispose();
                        NextVideo = new VideoListItemControlViewModel(nextSeriesVideo);
                        OnPropertyChanged(nameof(NextVideo));
                    }
                }
            }
            finally
            {
                NowLoading = false;
                OnPropertyChanged(nameof(NowLoading));
            }
        }
Beispiel #3
0
        public async Task <VideoRelatedContents> GetRelatedContentsAsync(INicoVideoDetails currentVideo)
        {
            var videoId = currentVideo.VideoId;

            if (_cachedVideoRelatedContents?.ContentId == videoId)
            {
                return(_cachedVideoRelatedContents);
            }

            var videoInfo           = _nicoVideoProvider.GetCachedVideoInfo(videoId);
            var videoViewerHelpInfo = NicoVideoSessionProvider.GetVideoRelatedInfomationWithVideoDescription(videoId, videoInfo.Description);

            VideoRelatedContents result = new VideoRelatedContents(videoId);

            // 再生中アイテムのタイトルと投稿者説明文に含まれる動画IDの動画タイトルを比較して
            // タイトル文字列が近似する動画をシリーズ動画として取り込む
            // 違うっぽい動画も投稿者が提示したい動画として確保
            var videoIds = videoViewerHelpInfo.GetVideoIds();
            List <NicoVideo> seriesVideos = new List <NicoVideo>();

            seriesVideos.Add(videoInfo);
            foreach (var id in videoIds)
            {
                var video = await _nicoVideoProvider.GetCachedVideoInfoAsync(id);

                var titleSimilarity = videoInfo.Title.CalculateSimilarity(video.Title);
                if (titleSimilarity > _SeriesVideosTitleSimilarityValue)
                {
                    seriesVideos.Add(video);
                }
                else
                {
                    var otherVideo = new VideoListItemControlViewModel(video);
                    result.OtherVideos.Add(otherVideo);
                }
            }


            // シリーズ動画として集めたアイテムを投稿日が新しいものが最後尾になるよう並び替え
            // シリーズ動画に番兵として仕込んだ現在再生中のアイテムの位置と動画数を比べて
            // 動画数が上回っていた場合は次動画が最後尾にあると決め打ちで取得する
            var orderedSeriesVideos = seriesVideos.OrderBy(x => x.PostedAt).ToList();
            var currentVideoIndex   = orderedSeriesVideos.IndexOf(videoInfo);

            if (orderedSeriesVideos.Count - 1 > currentVideoIndex)
            {
                var nextVideo = orderedSeriesVideos.Last();
                if (nextVideo.Id != videoId)
                {
                    result.NextVideo = new VideoListItemControlViewModel(nextVideo);

                    orderedSeriesVideos.Remove(nextVideo);
                }
            }

            // 次動画を除いてシリーズ動画っぽいアイテムを投稿者が提示したい動画として優先表示されるようにする
            orderedSeriesVideos.Remove(videoInfo);
            orderedSeriesVideos.Reverse();
            foreach (var video in orderedSeriesVideos)
            {
                var videoVM = new VideoListItemControlViewModel(video);
                result.OtherVideos.Insert(0, videoVM);
            }


            // マイリスト
            var relatedMylistIds = videoViewerHelpInfo.GetMylistIds();

            foreach (var mylistId in relatedMylistIds)
            {
                var mylist = await _mylistRepository.GetMylistAsync(mylistId);

                if (mylist != null)
                {
                    result.Mylists.Add(mylist);
                }
            }


            VideoRecommendResponse recommendResponse = null;

            if (currentVideo is IVideoContentProvider provider)
            {
                if (provider.ProviderType == OwnerType.Channel)
                {
                    recommendResponse = await _niconicoSession.ToolkitContext.Recommend.GetVideoRecommendForChannelAsync(currentVideo.VideoId, provider.ProviderId, currentVideo.Tags.Select(x => x.Tag).ToArray());
                }
            }

            if (recommendResponse == null)
            {
                recommendResponse = await _niconicoSession.ToolkitContext.Recommend.GetVideoRecommendForNotChannelAsync(currentVideo.VideoId);
            }

            if (recommendResponse?.IsSuccess ?? false)
            {
                result.OtherVideos = new List <VideoListItemControlViewModel>();
                foreach (var item in recommendResponse.Data.Items)
                {
                    if (item.ContentType is RecommendContentType.Video)
                    {
                        result.OtherVideos.Add(new VideoListItemControlViewModel(item.ContentAsVideo));
                    }
                }
            }

            result.CurrentVideo = result.Videos.FirstOrDefault(x => x.VideoId == videoId);

            _cachedVideoRelatedContents = result;

            return(result);
        }
        private async Task UpdateVideoDescription()
        {
            using (var releaser = await _UpdateLock.LockAsync())
            {
                if (VideoInfo.RawVideoId == null)
                {
                    return;
                }

                IsLoadFailed.Value = false;

                try
                {
                    var res = await NicoVideo.PreparePlayVideoAsync(VideoInfo.RawVideoId);

                    VideoDetals = res.GetVideoDetails();

                    //VideoTitle = details.VideoTitle;
                    //Tags = details.Tags.ToList();
                    //ThumbnailUrl = details.ThumbnailUrl;
                    //VideoLength = details.VideoLength;
                    //SubmitDate = details.SubmitDate;
                    //ViewCount = details.ViewCount;
                    //CommentCount = details.CommentCount;
                    //MylistCount = details.MylistCount;
                    //ProviderId = details.ProviderId;
                    //ProviderName = details.ProviderName;
                    //OwnerIconUrl = details.OwnerIconUrl;
                    //IsChannelOwnedVideo = details.IsChannelOwnedVideo;
                }
                catch
                {
                    IsLoadFailed.Value = true;
                    return;
                }
            }

            try
            {
                ApplicationTheme appTheme;
                if (_appearanceSettings.Theme == ElementTheme.Dark)
                {
                    appTheme = ApplicationTheme.Dark;
                }
                else if (_appearanceSettings.Theme == ElementTheme.Light)
                {
                    appTheme = ApplicationTheme.Light;
                }
                else
                {
                    appTheme = Views.Helpers.SystemThemeHelper.GetSystemTheme();
                }

                DescriptionHtmlFileUri = await Models.Helpers.HtmlFileHelper.PartHtmlOutputToCompletlyHtml(VideoInfo.VideoId, VideoDetals.DescriptionHtml, appTheme);

                RaisePropertyChanged(nameof(DescriptionHtmlFileUri));
            }
            catch
            {
                IsLoadFailed.Value = true;
                return;
            }


            VideoDescriptionHyperlinkItems.Clear();
            try
            {
                var htmlDocument = new HtmlAgilityPack.HtmlDocument();
                htmlDocument.LoadHtml(VideoDetals.DescriptionHtml);
                var root        = htmlDocument.DocumentNode;
                var anchorNodes = root.Descendants("a");

                foreach (var anchor in anchorNodes)
                {
                    var href = anchor.Attributes["href"].Value;
                    if (!Uri.IsWellFormedUriString(href, UriKind.Absolute))
                    {
                        Debug.WriteLine("リンク抽出スキップ: " + anchor.InnerText);
                        continue;
                    }

                    VideoDescriptionHyperlinkItems.Add(new HyperlinkItem()
                    {
                        Label = anchor.InnerText,
                        Url   = new Uri(href)
                    });

                    Debug.WriteLine($"{anchor.InnerText} : {anchor.Attributes["href"].Value}");
                }

                var matches = GeneralUrlRegex.Matches(VideoDetals.DescriptionHtml);
                foreach (var match in matches.Cast <Match>())
                {
                    if (!VideoDescriptionHyperlinkItems.Any(x => x.Url.OriginalString == match.Value))
                    {
                        VideoDescriptionHyperlinkItems.Add(new HyperlinkItem()
                        {
                            Label = match.Value,
                            Url   = new Uri(match.Value)
                        });

                        Debug.WriteLine($"{match.Value} : {match.Value}");
                    }
                }

                RaisePropertyChanged(nameof(VideoDescriptionHyperlinkItems));
            }
            catch
            {
                Debug.WriteLine("動画説明からリンクを抜き出す処理に失敗");
            }
        }
Beispiel #5
0
        /// <summary>
        /// 再生処理
        /// </summary>
        /// <returns></returns>
        public async Task <PlayingOrchestrateResult> CreatePlayingOrchestrateResultAsync(string videoId)
        {
            var cacheVideoResult = await _videoCacheManager.TryCreateCachedVideoSessionProvider(videoId);

            if (cacheVideoResult.IsSuccess)
            {
                INiconicoCommentSessionProvider commentSessionProvider = null;
                INicoVideoDetails nicoVideoDetails = null;
                if (!Models.Helpers.InternetConnection.IsInternet())
                {
                    var cachedComment = _commentRepository.GetCached(videoId);
                    if (cachedComment != null)
                    {
                        commentSessionProvider = new CachedCommentsProvider(videoId, cachedComment.Comments);
                    }

                    var videoInfo = Database.NicoVideoDb.Get(videoId);
                    if (videoInfo != null)
                    {
                        nicoVideoDetails = new CachedVideoDetails()
                        {
                            VideoTitle      = videoInfo.Title,
                            ViewCount       = videoInfo.ViewCount,
                            CommentCount    = videoInfo.CommentCount,
                            MylistCount     = videoInfo.MylistCount,
                            VideoLength     = videoInfo.Length,
                            SubmitDate      = videoInfo.PostedAt,
                            Tags            = videoInfo.Tags.Select(x => new NicoVideoTag(x.Id)).ToArray(),
                            ProviderId      = videoInfo.Owner?.OwnerId,
                            ProviderName    = videoInfo.Owner?.ScreenName,
                            OwnerIconUrl    = videoInfo.Owner.IconUrl,
                            DescriptionHtml = videoInfo.DescriptionWithHtml,
                            ThumbnailUrl    = videoInfo.ThumbnailUrl
                        };
                    }
                }
                else
                {
                    var preparePlayVideo = await _nicoVideoSessionProvider.PreparePlayVideoAsync(videoId);

                    commentSessionProvider = preparePlayVideo;
                    nicoVideoDetails       = preparePlayVideo?.GetVideoDetails();
                }

                // キャッシュからコメントを取得する方法が必要
                return(new PlayingOrchestrateResult(
                           cacheVideoResult.VideoSessionProvider,
                           commentSessionProvider,
                           nicoVideoDetails
                           ));
            }
            else
            {
                /*
                 * bool canPlay = true;
                 * var downloadLineOwnership = await _videoCacheManager.TryRentDownloadLineAsync();
                 * if (downloadLineOwnership == null)
                 * {
                 *  canPlay = false;
                 *  if (await ShowSuspendCacheDownloadingDialog())
                 *  {
                 *      await _videoCacheManager.SuspendCacheDownload();
                 *      canPlay = true;
                 *  }
                 * }
                 *
                 * if (!canPlay)
                 * {
                 *  return new PlayingOrchestrateResult();
                 * }
                 */

                var preparePlayVideo = await _nicoVideoSessionProvider.PreparePlayVideoAsync(videoId);

                if (!preparePlayVideo.IsSuccess)
                {
                    var progress = await _videoCacheManager.GetDownloadProgressVideosAsync();

                    if (!_niconicoSession.IsPremiumAccount && progress.Any())
                    {
                        var result = await ShowSuspendCacheDownloadingDialog();

                        if (result)
                        {
                            preparePlayVideo = await _nicoVideoSessionProvider.PreparePlayVideoAsync(videoId);
                        }
                    }
                }

                if (preparePlayVideo == null || !preparePlayVideo.IsSuccess)
                {
                    throw new NotSupportedException("不明なエラーにより再生できません");
                }

                return(new PlayingOrchestrateResult(
                           preparePlayVideo,
                           preparePlayVideo,
                           preparePlayVideo.GetVideoDetails()
                           ));
            }
        }