public static async Task <string> GetDmcWatchResponseDataAsync(NiconicoContext context, string requestId) { if (!NiconicoRegex.IsVideoId(requestId)) { // throw new ArgumentException(); } var dict = new Dictionary <string, string>(); var url = $"{NiconicoUrls.VideoWatchPageUrl}{requestId}"; url += "?" + HttpQueryExtention.DictionaryToQuery(dict); try { var message = new HttpRequestMessage(HttpMethod.Get, new Uri(url)); var res = await context.SendAsync(message); if (res.ReasonPhrase == "Forbidden") { throw new WebException("require payment."); } var text = await res.Content.ReadAsStringAsync(); return(text); } catch (Exception e) { throw new WebException("access failed watch/" + requestId, e); } }
public static Task <string> GetVideoDataAsync(NiconicoVitaContext context, string requestId) { if (!NiconicoRegex.IsLiveId(requestId)) { throw new ArgumentException(); } return(context.GetClient().GetStringWithoutHttpRequestExceptionAsync(NiconicoUrls.VideoUrl + requestId)); }
public void AddWatchAfterPlaylist(string contentId) { if (!NiconicoRegex.IsVideoId(contentId) && !int.TryParse(contentId, out var temp)) { return; } var result = DefaultPlaylist.AddMylistItem(contentId, ContentInsertPosition.Tail); }
public static Task <string> GetTagRevisionDataAsync(NiconicoContext context, string requestId) { if (!NiconicoRegex.IsLiveId(requestId)) { throw new ArgumentException(); } return(context.GetConvertedStringAsync(NiconicoUrls.LiveTagRevisionUrl + requestId)); }
// あとで見るプレイリストを通じての再生をサポート // プレイリストが空だった場合、その場で再生を開始 public void PlayVideo(string contentId, string title = "", NicoVideoQuality?quality = null) { if (!NiconicoRegex.IsVideoId(contentId) && !int.TryParse(contentId, out var temp)) { return; } var newItem = DefaultPlaylist.AddVideo(contentId, title, ContentInsertPosition.Head); Play(newItem); }
private async Task ExtractNicoContentId_And_SubmitSuggestion(string contentId) { if (NiconicoRegex.IsVideoId(contentId)) { SubmitVideoContentSuggestion(contentId); } else if (NiconicoRegex.IsLiveId(contentId)) { await SubmitLiveContentSuggestion(contentId); } }
private async Task ExtractNicoContentId_And_SubmitSuggestion(Uri url) { var match = NicoContentRegex.Match(url.OriginalString); if (match.Success) { var hostNameGroup = match.Groups[1]; var contentTypeGroup = match.Groups[3]; var contentIdGroup = match.Groups[4]; var contentId = contentIdGroup.Value; if (NiconicoRegex.IsVideoId(contentId)) { SubmitVideoContentSuggestion(contentId); } else if (NiconicoRegex.IsLiveId(contentId)) { await SubmitLiveContentSuggestion(contentId); } else if (contentTypeGroup.Success) { var contentType = contentTypeGroup.Value; switch (contentType) { case "mylist": await SubmitMylistContentSuggestion(contentId); break; case "community": await SubmitCommunityContentSuggestion(contentId); break; case "user": await SubmitUserSuggestion(contentId); break; } } else if (hostNameGroup.Success) { var hostName = hostNameGroup.Value; if (hostName == "ch.nicovideo.jp") { var channelId = contentId; // TODO: クリップボードから受け取ったチャンネルIdを開く } } } }
public static Task <string> RemoveHistoryDataAsync( NiconicoContext context, string token, string requestId) { if (!NiconicoRegex.IsVideoId(requestId) && !uint.TryParse(requestId, out var _)) { throw new ArgumentException(); } return(context .GetStringAsync($"{NiconicoUrls.VideoRemoveUrl}{token}&video_id={requestId}")); }
public void PlayVideo(IVideoContent video) { if (!(NiconicoRegex.IsVideoId(video.Id) || video.Id.All(x => '0' <= x && x <= '9'))) { return; } var item = DefaultPlaylist.PlaylistItems.FirstOrDefault(x => x.Type == PlaylistItemType.Video && x.ContentId == video.Id) ?? DefaultPlaylist.AddVideo(video.Id, video.Label, ContentInsertPosition.Head); Play(item); }
public static Task <string> GetVideosDataAsync(NiconicoVitaContext context, IReadOnlyList <string> requestIds) { foreach (var requestId in requestIds) { if (!NiconicoRegex.IsLiveId(requestId)) { throw new ArgumentException(); } } return(context.GetClient().GetStringWithoutHttpRequestExceptionAsync(NiconicoUrls.VideosUrl + string.Join(",", requestIds))); }
public static async Task <byte[]> GetIconAsync(NiconicoContext context, string requestId) #endif { if (!NiconicoRegex.IsChannelId(requestId)) { throw new ArgumentException(); } var channelNumber = requestId.Substring(2).ToUInt(); return(await context.HttpClient #if WINDOWS_UWP .GetBufferAsync(new Uri(string.Format(NiconicoUrls.ChannelIconUrl, channelNumber))));
public static Task <string> VoteDataAsync(NiconicoContext context, string requestId, ushort choiceNumber) { if (!NiconicoRegex.IsLiveId(requestId)) { throw new ArgumentException(); } if (choiceNumber > 8) { throw new ArgumentException(); } return(context .GetStringAsync($"{NiconicoUrls.LiveVoteUrl}?v={requestId}&id={choiceNumber}")); }
public static Task <string> GetCKeyDataAsync(NiconicoContext context, string refererId, string requestId) { if (!NiconicoRegex.IsLiveId(refererId)) { throw new ArgumentException(); } if (!NiconicoRegex.IsVideoId(requestId)) { throw new ArgumentException(); } return(context .GetStringAsync($"{NiconicoUrls.LiveCKeyUrl}?referer_id={refererId}&id={requestId}")); }
// https://www.nicovideo.jp/api/watch/v3_guest/1615359905?_frontendId=6&_frontendVersion=0&actionTrackId=rV8Nf4Qith_1615871913294&skips=harmful&additionals=pcWatchPage,external,marquee,series&isContinueWatching=true&i18nLanguage=ja-jp&t=1615871919713 // https://www.nicovideo.jp/api/watch/v3/1615359905?_frontendId=6&_frontendVersion=0&actionTrackId=nYQzK4jFdB_1615872059788&skips=harmful&additionals=pcWatchPage,external,marquee,series&isContinueWatching=true&i18nLanguage=ja-jp&t=1615872080318 public static async Task <string> GetDmcWatchJsonDataAsync(NiconicoContext context, string requestId, bool isLoggedIn, string actionTrackId) { if (!NiconicoRegex.IsVideoId(requestId)) { // throw new ArgumentException(); } //bool isLoggedIn = true; var dict = new Dictionary <string, string>(); var url = $"{NiconicoUrls.VideoApiUrlBase}watch/{(isLoggedIn ? "v3" : "v3_guest")}/{requestId}"; dict.Add("_frontendId", "6"); dict.Add("_frontendVersion", "0"); dict.Add("actionTrackId", actionTrackId); dict.Add("skips", "harmful"); dict.Add("additionals", WebUtility.UrlEncode("pcWatchPage,external,marquee,series")); dict.Add("isContinueWatching", "true"); dict.Add("i18nLanguage", "ja-jp"); dict.Add("t", DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString()); url += "?" + HttpQueryExtention.DictionaryToQuery(dict); var requestMessage = new HttpRequestMessage(HttpMethod.Get, new Uri(url)); requestMessage.Headers.Add("Accept", "*/*"); requestMessage.Headers.Referer = new Uri($"https://www.nicovideo.jp/watch/{requestId}"); requestMessage.Headers.Add("Sec-Fetch-Site", "same-origin"); requestMessage.Headers.Host = new Windows.Networking.HostName("www.nicovideo.jp"); try { var res = await context.SendAsync(requestMessage); if (res.ReasonPhrase == "Forbidden") { throw new WebException("require payment."); } var text = await res.Content.ReadAsStringAsync(); return(text); } catch (Exception e) { throw new WebException("access failed watch/" + requestId, e); } }
public void Play(IMylist mylist) { var videoId = mylist.FirstOrDefault(); if (!(NiconicoRegex.IsVideoId(videoId) || videoId.All(x => '0' <= x && x <= '9'))) { throw new Exception("Video Id not correct format. (\"sm0123456\" or \"12345678\") "); } Play(new QualityVideoPlaylistItem() { ContentId = videoId, Owner = mylist, Type = PlaylistItemType.Video, }); }
public override void OnNavigatedTo(NavigatedToEventArgs e, Dictionary <string, object> viewModelState) { IsValidCommunity = false; if (e.Parameter is string) { var id = e.Parameter as string; if (NiconicoRegex.IsCommunityId(id)) { CommunityId = id; IsValidCommunity = true; } } base.OnNavigatedTo(e, viewModelState); }
public void PlayVideo(IVideoContent video) { if (!(NiconicoRegex.IsVideoId(video.Id) || video.Id.All(x => '0' <= x && x <= '9'))) { return; } DefaultPlaylist.AddMylistItem(video.Id, ContentInsertPosition.Head); Play(new QualityVideoPlaylistItem() { ContentId = video.Id, Owner = video.OnwerPlaylist ?? DefaultPlaylist, Title = video.Label, Type = PlaylistItemType.Video, }); }
// あとで見るプレイリストを通じての再生をサポート // プレイリストが空だった場合、その場で再生を開始 public void PlayVideo(string contentId, string title = "", NicoVideoQuality?quality = null) { if (!NiconicoRegex.IsVideoId(contentId) && !int.TryParse(contentId, out var temp)) { return; } var result = DefaultPlaylist.AddMylistItem(contentId, ContentInsertPosition.Head); Play(new QualityVideoPlaylistItem() { ContentId = contentId, Owner = DefaultPlaylist, Title = title, Type = PlaylistItemType.Video, Quality = quality }); }
public override void OnNavigatedTo(NavigatedToEventArgs e, Dictionary <string, object> viewModelState) { IsValidCommunity = false; if (e.Parameter is string) { var id = e.Parameter as string; if (NiconicoRegex.IsCommunityId(id)) { CommunityId = id; IsValidCommunity = true; } } CanDownload = HohoemaApp.UserSettings.CacheSettings.IsUserAcceptedCache && HohoemaApp.UserSettings.CacheSettings.IsEnableCache && HohoemaApp.IsLoggedIn; base.OnNavigatedTo(e, viewModelState); }
public void PlayVideoWithPlaylist(IVideoContent video) { if (!(NiconicoRegex.IsVideoId(video.Id) || video.Id.All(x => '0' <= x && x <= '9'))) { return; } if (video.Playlist != null) { var playlistItem = video.Playlist.PlaylistItems.FirstOrDefault(x => x.ContentId == video.Id); if (playlistItem != null) { Play(playlistItem); } } else { var newItem = DefaultPlaylist.AddVideo(video.Id, video.Label, ContentInsertPosition.Head); Play(newItem); } }
private async void _NicoLiveCommentReciever_CommentRecieved(Chat chat) { await HohoemaApp.UIDispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { _LiveComments.Insert(0, chat); }); if (chat.User_id == BroadcasterId) { if (chat.Text.Contains("href")) { var root = XDocument.Parse(chat.Text); var anchor = root.Element("a"); if (anchor != null) { var href = anchor.Attribute("href"); var link = href.Value; if (chat.Text.Contains("次")) { var liveId = link.Split('/').LastOrDefault(); if (NiconicoRegex.IsLiveId(liveId)) { // TODO: liveIdの放送情報を取得して、配信者が同一ユーザーかチェックする using (var releaser = await _NextLiveSubscriveLock.LockAsync()) { await HohoemaApp.UIDispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { NextLiveId = liveId; NextLive?.Invoke(this, NextLiveId); }); } } } // TODO: linkをブラウザで開けるようにする } } } }
public static async Task <byte[]> GetIconAsync(NiconicoContext context, string requestId) { if (!NiconicoRegex.IsCommunityId(requestId)) { throw new ArgumentException(); } var communityNumber = requestId.Substring(2).ToUInt(); try { return(await context.HttpClient .GetByteArrayAsync(string.Format(NiconicoUrls.CommunityIconUrl, communityNumber / 10000, communityNumber))); } catch (AggregateException ex) { if (ex.HResult != -2146233088) { throw; } } return(await context.HttpClient.GetByteArrayAsync(NiconicoUrls.CommunityBlankIconUrl)); }
static bool IsVideoId(string videoId) { return(NiconicoRegex.IsVideoId(videoId) && !int.TryParse(videoId, out var _)); }
// TODO: 視聴開始(会場後のみ、チャンネル会員限定やチケット必要な場合あり) // TODO: タイムシフト予約(tsがある場合のみ、会場前のみ、プレミアムの場合は会場後でも可) // TODO: 後からタイムシフト予約(プレミアムの場合のみ) // TODO: 配信説明 // TODO: タグ // TODO: 配信者(チャンネルやコミュニティ)の概要説明 // TODO: 配信者(チャンネルやコミュニティ)のフォロー // TODO: オススメ生放送(放送中、放送予定を明示) // TODO: ニコニコ市場 // TODO: SNS共有 // gateとwatchをどちらも扱った上でその差を意識させないように表現する // LiveInfo.Video.CurrentStatusは開演前、放送中は時間の経過によって変化する可能性がある public LiveInfomationPageViewModel( PageManager pageManager, Models.NiconicoSession niconicoSession, NicoLiveProvider nicoLiveProvider, DialogService dialogService, Services.HohoemaPlaylist hohoemaPlaylist, ExternalAccessService externalAccessService ) : base(pageManager) { NiconicoSession = niconicoSession; NicoLiveProvider = nicoLiveProvider; HohoemaDialogService = dialogService; HohoemaPlaylist = hohoemaPlaylist; ExternalAccessService = externalAccessService; IsLoadFailed = new ReactiveProperty <bool>(false) .AddTo(_CompositeDisposable); LoadFailedMessage = new ReactiveProperty <string>() .AddTo(_CompositeDisposable); IsLiveIdAvairable = this.ObserveProperty(x => x.LiveId) .Select(x => x != null ? NiconicoRegex.IsLiveId(x) : false) .ToReadOnlyReactiveProperty() .AddTo(_CompositeDisposable); IsLoggedIn = NiconicoSession.ObserveProperty(x => x.IsLoggedIn) .ToReadOnlyReactiveProperty() .AddTo(_CompositeDisposable); IsPremiumAccount = NiconicoSession.ObserveProperty(x => x.IsPremiumAccount) .ToReadOnlyReactiveProperty() .AddTo(_CompositeDisposable); _IsTsPreserved = new ReactiveProperty <bool>(false) .AddTo(_CompositeDisposable); LiveTags = new ReadOnlyObservableCollection <LiveTagViewModel>(_LiveTags); IchibaItems = new ReadOnlyObservableCollection <IchibaItem>(_IchibaItems); ReccomendItems = _ReccomendItems.ToReadOnlyReactiveCollection(x => { var liveId = "lv" + x.ProgramId; var liveInfoVM = new LiveInfoListItemViewModel(liveId); liveInfoVM.Setup(x); var reserve = _Reservations?.ReservedProgram.FirstOrDefault(reservation => liveId == reservation.Id); if (reserve != null) { liveInfoVM.SetReservation(reserve); } return(liveInfoVM); }) .AddTo(_CompositeDisposable); IsShowOpenLiveContentButton = this.ObserveProperty(x => LiveInfo) .Select(x => { if (LiveInfo == null) { return(false); } if (NiconicoSession.IsPremiumAccount) { if (LiveInfo.Video.OpenTime > DateTime.Now) { return(false); } return(LiveInfo.Video.TimeshiftEnabled); } else { // 一般アカウントは放送中のみ if (LiveInfo.Video.OpenTime > DateTime.Now) { return(false); } if (_IsTsPreserved.Value) { return(true); } if (LiveInfo.Video.EndTime < DateTime.Now) { return(false); } return(true); } }) .ToReadOnlyReactiveProperty() .AddTo(_CompositeDisposable); IsShowAddTimeshiftButton = this.ObserveProperty(x => LiveInfo) .Select(x => { if (LiveInfo == null) { return(false); } if (!LiveInfo.Video.TimeshiftEnabled) { return(false); } if (!NiconicoSession.IsLoggedIn) { return(false); } if (!niconicoSession.IsPremiumAccount) { // 一般アカウントは放送開始の30分前からタイムシフトの登録はできなくなる if ((LiveInfo.Video.StartTime - TimeSpan.FromMinutes(30)) < DateTime.Now) { return(false); } } if (LiveInfo.Video.TsArchiveEndTime != null && LiveInfo.Video.TsArchiveEndTime > DateTime.Now) { return(false); } if (_IsTsPreserved.Value) { return(false); } return(true); }) .ToReadOnlyReactiveProperty() .AddTo(_CompositeDisposable); IsShowDeleteTimeshiftButton = _IsTsPreserved; }
protected override async Task NavigatedToAsync(CancellationToken cancelToken, NavigatedToEventArgs e, Dictionary <string, object> viewModelState) { LiveId = null; if (e.Parameter is string maybeLiveId) { if (NiconicoRegex.IsLiveId(maybeLiveId)) { LiveId = maybeLiveId; } } await RefreshLiveInfoAsync(); string htmlDescription = null; try { htmlDescription = await NiconicoSession.Context.Live.GetDescriptionAsync(LiveId); } catch { Debug.WriteLine("gateページによるHtml Descriptionの取得に失敗。programInfoによる取得に切り替えて試行"); } if (htmlDescription == null) { await Task.Delay(1000); var programInfo = await NiconicoSession.Context.Live.GetProgramInfoAsync(LiveId); if (programInfo.IsOK) { htmlDescription = programInfo.Data.Description; Debug.WriteLine("programInfoから放送説明HTML取得:Success"); } else { Debug.WriteLine("programInfoから放送説明HTML取得:Failed"); } } if (htmlDescription != null) { HtmlDescription = await Models.Helpers.HtmlFileHelper.PartHtmlOutputToCompletlyHtml(LiveId, htmlDescription); try { var htmlDocument = new HtmlAgilityPack.HtmlDocument(); htmlDocument.LoadHtml(htmlDescription); var root = htmlDocument.DocumentNode; var anchorNodes = root.Descendants("a"); foreach (var anchor in anchorNodes) { var url = new Uri(anchor.Attributes["href"].Value); string label = null; var text = anchor.InnerText; if (string.IsNullOrWhiteSpace(text) || text.Contains('\n') || text.Contains('\r')) { label = url.OriginalString; } else { label = new string(anchor.InnerText.TrimStart(' ', '\n', '\r').TakeWhile(c => c != ' ' || c != ' ').ToArray()); } DescriptionHyperlinkItems.Add(new HyperlinkItem() { Label = label, Url = url }); Debug.WriteLine($"{anchor.InnerText} : {anchor.Attributes["href"].Value}"); } /* * var matches = GeneralUrlRegex.Matches(HtmlDescription); * 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(DescriptionHyperlinkItems)); } catch { Debug.WriteLine("動画説明からリンクを抜き出す処理に失敗"); } } await base.NavigatedToAsync(cancelToken, e, viewModelState); }