/// <summary> /// 実装 /// </summary> /// <param name="nicoId"></param> /// <param name="info"></param> /// <param name="options"></param> /// <returns></returns> private async Task <IAttemptResult <IListVideoInfo> > GetVideoInfoAsync(string nicoId) { IAttemptResult <IDomainVideoInfo> result; try { result = await this.handler.GetVideoInfoAsync(nicoId); } catch (Exception e) { this.logger.Error($"動画情報を取得中に不明なエラーが発生しました。(id:{nicoId})", e); return(new AttemptResult <IListVideoInfo>() { Message = $"不明なエラーが発生しました。(詳細:{e.Message})" }); } if (!result.IsSucceeded || result.Data is null) { return(new AttemptResult <IListVideoInfo>() { Message = result.Message, Exception = result.Exception }); } IListVideoInfo info = this.container.GetVideo(nicoId); this.converter.ConvertDomainVideoInfoToListVideoInfo(info, result.Data); return(new AttemptResult <IListVideoInfo>() { IsSucceeded = true, Data = info }); }
public IAttemptResult WireVideoToPlaylist(int videoID, int playlistID) { IAttemptResult <STypes::Video> vResult = this._videoStoreHandler.GetVideo(videoID); if (!vResult.IsSucceeded || vResult.Data is null) { return(AttemptResult.Fail("追加する動画はDBに保存されていません。")); } STypes::Video video = vResult.Data; video.PlaylistIds.AddUnique(playlistID); this._videoStoreHandler.Update(video); IAttemptResult result = this._playlistStoreHandler.WireVideo(video, playlistID); ITreePlaylistInfo playlistInfo = this._playlistInfoContainer.GetPlaylist(playlistID); IListVideoInfo videoInfo = this._videoInfoContainer.GetVideo(video.NiconicoId); if (!playlistInfo.Videos.Any(v => v.Id.Value == videoID)) { playlistInfo.Videos.Add(videoInfo); } return(result); }
/// <summary> /// プレイヤーで開く /// </summary> /// <param name="appPath"></param> /// <param name="videoInfo"></param> /// <returns></returns> private IAttemptResult OpenPlayer(string appPath, IListVideoInfo videoInfo) { var folderPath = this.current.SelectedPlaylist.Value?.Folderpath; if (!videoInfo.IsDownloaded.Value || videoInfo.FileName.Value.IsNullOrEmpty()) { return new AttemptResult() { Message = $"{videoInfo.NiconicoId.Value}はダウンロードされていません。", } } ; if (folderPath is null) { return new AttemptResult() { Message = "フォルダーパスが設定されていません。" } } ; var path = Path.Combine(folderPath, videoInfo.FileName.Value) .Replace(@"\\?\", string.Empty) ; return(this.commandExecuter.Execute(appPath, $"\"{path}\"")); }
/// <summary> /// サムネイルのパスをサーバーから取得して設定する /// </summary> /// <param name="video"></param> /// <param name="fource"></param> /// <returns></returns> public void GetThumbAsync(IListVideoInfo video, Action onDone, bool overwrite = false) { if (!this.IsValidThumbnailUrl(video)) { return; } lock (this.lockObj) { if (this.niconicoIDsAndActions.ContainsKey(video.NiconicoId.Value)) { this.niconicoIDsAndActions[video.NiconicoId.Value] += onDone; } if (!this.niconicoIDsAndActions.Any(p => p.Key == video.NiconicoId.Value)) { this.thumbConfigs.Enqueue(new ThumbConfig() { NiconicoID = video.NiconicoId.Value, Url = video.ThumbUrl.Value, Overwrite = overwrite }); this.niconicoIDsAndActions.Add(video.NiconicoId.Value, onDone); } } if (!this.isFetching) { Task.Run(() => this.GetThumbAsync()); } }
public async Task <IAttemptResult <IListVideoInfo> > GetVideoListInfoAsync(string id, CancellationToken?ct = null) { IListVideoInfo video = this._videoInfoContainer.GetVideo(id); bool registerOnlyID = this._settingHandler.GetBoolSetting(SettingsEnum.StoreOnlyNiconicoID); if (registerOnlyID) { return(AttemptResult <IListVideoInfo> .Succeeded(video)); } this._messageHandler.AppendMessage($"{id}の取得を開始します。"); IAttemptResult <IListVideoInfo> result = await this._wacthPagehandler.TryGetVideoInfoAsync(id); if (!result.IsSucceeded || result.Data is null) { this._messageHandler.AppendMessage($"{id}の取得に失敗しました。(詳細:{result.Message})"); return(AttemptResult <IListVideoInfo> .Fail($"{id}の取得に失敗しました。(詳細:{result.Message})")); } else { this._messageHandler.AppendMessage($"{id}の取得に成功しました。"); video.SetNewData(result.Data); } return(AttemptResult <IListVideoInfo> .Succeeded(video)); }
public IAttemptResult Update(IListVideoInfo video) { STypes::Video converted = this._converter.ConvertLocalVideoToStoreVideo(video); IAttemptResult result = this._videoStoreHandler.Update(converted); return(result); }
/// <summary> /// アプリに送る /// </summary> /// <param name="appPath"></param> /// <param name="argBase"></param> /// <param name="videoInfo"></param> /// <returns></returns> private IAttemptResult SendToAppCommand(string appPath, string argBase, IListVideoInfo videoInfo) { var constructedArg = argBase .Replace("<url>", NetConstant.NiconicoWatchUrl + videoInfo.NiconicoId.Value) .Replace("<url:short>", NetConstant.NiconicoShortUrl + videoInfo.NiconicoId.Value) .Replace("<id>", videoInfo.NiconicoId.Value) ; return(this.commandExecuter.Execute(appPath, constructedArg)); }
public void インスタンスの同一性を確認する() { string title = "レッツゴー!陰陽師"; IListVideoInfo onmyoji = this.container !.GetVideo("sm9"); onmyoji.Title.Value = title; IListVideoInfo reOnmyoji = this.container !.GetVideo("sm9"); Assert.That(reOnmyoji.Title.Value, Is.EqualTo(title)); }
/// <summary> /// リモートプレイリストの動画情報を変換する /// </summary> /// <param name="remoteVideoInfo"></param> /// <param name="listVideoInfo"></param> public void ConvertRemoteVideoInfoToListVideoInfo(VideoInfo remoteVideoInfo, IListVideoInfo listVideoInfo) { listVideoInfo.NiconicoId.Value = remoteVideoInfo.ID; listVideoInfo.Title.Value = remoteVideoInfo.Title; listVideoInfo.OwnerName.Value = remoteVideoInfo.OwnerName; listVideoInfo.OwnerID.Value = remoteVideoInfo.OwnerID; listVideoInfo.UploadedOn.Value = remoteVideoInfo.UploadedDT; listVideoInfo.ViewCount.Value = (int)remoteVideoInfo.ViewCount; listVideoInfo.CommentCount.Value = (int)remoteVideoInfo.CommentCount; listVideoInfo.MylistCount.Value = (int)remoteVideoInfo.MylistCount; listVideoInfo.ThumbUrl.Value = remoteVideoInfo.ThumbUrl; }
/// <summary> /// ローカルファイルの取得を試行する /// </summary> /// <param name="video"></param> /// <param name="folderPath"></param> /// <returns></returns> public string GetFilePath(IListVideoInfo video, string folderPath, string format, bool replaceStricted, bool searchExact) { if (!Path.IsPathRooted(folderPath)) { folderPath = Path.Combine(AppContext.BaseDirectory, folderPath); } if (this.cachedFiles is null) { this.cachedFiles = new List <string>(); if (this.directoryIO.Exists(folderPath)) { this.cachedFiles.AddRange(this.directoryIO.GetFiles(folderPath, $"*{FileFolder.Mp4FileExt}", true).Select(p => Path.Combine(folderPath, p)).ToList()); this.cachedFiles.AddRange(this.directoryIO.GetFiles(folderPath, $"*{FileFolder.TsFileExt}", true).Select(p => Path.Combine(folderPath, p)).ToList()); } } bool SearchFunc(string currentPath, string targetPath) { if (searchExact) { return(currentPath == targetPath); } else { return(currentPath.Contains(video.NiconicoId.Value)); } } var fn = this.niconicoUtils.GetFileName(format, video, FileFolder.Mp4FileExt, replaceStricted); var path = IOUtils.GetPrefixedPath(Path.Combine(folderPath, fn)); string?firstMp4 = this.cachedFiles.FirstOrDefault(p => SearchFunc(p, path)); //.mp4ファイルを確認 if (firstMp4 is not null) { return(firstMp4); } else //.tsファイルを確認 { fn = this.niconicoUtils.GetFileName(format, video, FileFolder.TsFileExt, replaceStricted); path = IOUtils.GetPrefixedPath(Path.Combine(folderPath, fn)); string?firstTS = this.cachedFiles.FirstOrDefault(p => SearchFunc(p, path)); if (firstTS is not null) { return(firstTS); } } return(Path.GetDirectoryName(path) ?? folderPath); }
public IAttemptResult <IListVideoInfo> GetVideo(int id) { IAttemptResult <STypes::Video> sResult = this._videoStoreHandler.GetVideo(id); if (!sResult.IsSucceeded || sResult.Data is null) { return(AttemptResult <IListVideoInfo> .Fail(sResult.Message)); } IListVideoInfo converted = this._converter.ConvertStoreVideoToLocalVideo(sResult.Data); return(AttemptResult <IListVideoInfo> .Succeeded(converted)); }
/// <summary> /// プレイヤーBで開く /// </summary> /// <param name="videoInfo"></param> /// <returns></returns> public IAttemptResult OpenInPlayerB(IListVideoInfo videoInfo) { var appPath = this.localSettingHandler.GetStringSetting(SettingsEnum.PlayerBPath); if (appPath is null) { return new AttemptResult() { Message = "プレイヤーBは登録されていません。" } } ; return(this.OpenPlayer(appPath, videoInfo)); }
/// <summary> /// 動画情報からファイル名を取得する /// </summary> /// <param name="format"></param> /// <param name="video"></param> /// <param name="extension"></param> /// <param name="replaceStricted"></param> /// <param name="suffix"></param> /// <returns></returns> public string GetFileName(string format, IListVideoInfo video, string extension, bool replaceStricted, string?suffix = null) { var info = new VideoInfoForPath() { Title = video.Title.Value, OwnerName = video.OwnerName.Value, NiconicoID = video.NiconicoId.Value, UploadedOn = video.UploadedOn.Value, DownloadStartedOn = DateTime.Now, OwnerID = video.OwnerID.Value.ToString(), Duration = video.Duration.Value, }; return(this.GetFilenameInternal(format, info, extension, replaceStricted, suffix)); }
public IAttemptResult UnWireVideoToPlaylist(int videoID, int playlistID) { IAttemptResult <STypes::Video> vResult = this._videoStoreHandler.GetVideo(videoID); if (!vResult.IsSucceeded || vResult.Data is null) { return(AttemptResult.Fail("削除する動画はDBに保存されていません。")); } STypes::Video video = vResult.Data; ITreePlaylistInfo playlistInfo = this._playlistInfoContainer.GetPlaylist(playlistID); IListVideoInfo videoInfo = this._videoInfoContainer.GetVideo(video.NiconicoId); playlistInfo.Videos.RemoveAll(v => v.Id.Value == videoID); IAttemptResult result = this._playlistStoreHandler.UnWireVideo(videoID, playlistID); return(result); }
public void 動画を更新する() { var count = 100; var original = new NonBindableListVideoInfo() { NiconicoId = new Reactive.Bindings.ReactiveProperty <string>("1") }; var newItem = new NonBindableListVideoInfo() { NiconicoId = new Reactive.Bindings.ReactiveProperty <string>("1"), ViewCount = new Reactive.Bindings.ReactiveProperty <int>(count) }; this.videoListContainer !.Add(original); IAttemptResult result = this.videoListContainer.Update(newItem); IListVideoInfo video = this.videoListContainer.Videos.First(); Assert.That(result.IsSucceeded, Is.True); Assert.That(video.ViewCount.Value, Is.EqualTo(count)); }
/// <summary> /// Domainの動画情報を変換する /// </summary> /// <param name="videoInfo"></param> /// <returns></returns> public void ConvertDomainVideoInfoToListVideoInfo(IListVideoInfo info, IDomainVideoInfo domainVideoInfo) { //タイトル info.Title.Value = domainVideoInfo.Title; //ID info.NiconicoId.Value = domainVideoInfo.Id; //タグ info.Tags = domainVideoInfo.Tags; //再生回数 info.ViewCount.Value = domainVideoInfo.ViewCount; info.CommentCount.Value = domainVideoInfo.CommentCount; info.MylistCount.Value = domainVideoInfo.MylistCount; info.LikeCount.Value = domainVideoInfo.LikeCount; //チャンネル情報 info.ChannelID.Value = domainVideoInfo.ChannelID; info.ChannelName.Value = domainVideoInfo.ChannelName; //投稿者情報 info.OwnerID.Value = domainVideoInfo.OwnerID; info.OwnerName.Value = domainVideoInfo.Owner; //再生時間 info.Duration.Value = domainVideoInfo.Duration; //投稿日時 if (domainVideoInfo.DmcInfo is not null) { info.UploadedOn.Value = domainVideoInfo.DmcInfo.UploadedOn; } //サムネイル if (domainVideoInfo.DmcInfo is not null && domainVideoInfo.DmcInfo.ThumbInfo is not null) { info.ThumbUrl.Value = domainVideoInfo.DmcInfo.ThumbInfo.GetSpecifiedThumbnail(ThumbSize.Large); } }
/// <summary> /// アプリAで開く /// </summary> /// <param name="videoInfo"></param> /// <returns></returns> public IAttemptResult SendToAppA(IListVideoInfo videoInfo) { var appPath = this.localSettingHandler.GetStringSetting(SettingsEnum.AppAPath); if (appPath is null) { return new AttemptResult() { Message = "アプリAは登録されていません。" } } ; var paramBase = this.localSettingHandler.GetStringSetting(SettingsEnum.AppAParam); if (paramBase is null) { paramBase = "<url>"; } return(this.SendToAppCommand(appPath, paramBase, videoInfo)); }
/// <summary> /// 検索する /// </summary> /// <param name="query"></param> /// <param name="searchType"></param> /// <returns></returns> public async Task <ISearchResult> SearchAsync(ISearchQuery query) { string url = this.urlConstructor.GetUrl(query); Api::Response data; try { data = await this.client.GetResponseAsync(url); } catch (Exception e) { this.logger.Error("スナップショット検索APIへのアクセスに失敗しました。", e); return(new SearchResult() { Message = $"APIへのアクセスに失敗しました。(詳細: {e.Message})" }); } var videos = data.Data.Select(v => { IListVideoInfo videoInfo = this.container.GetVideo(v.ContentId); videoInfo.NiconicoId.Value = v.ContentId; videoInfo.UploadedOn.Value = v.StartTime.Date; videoInfo.Title.Value = v.Title; videoInfo.ViewCount.Value = v.ViewCounter; videoInfo.CommentCount.Value = v.CommentCounter; videoInfo.MylistCount.Value = v.MylistCounter; videoInfo.Tags = v.Tags.Split(" "); videoInfo.ThumbUrl.Value = v.ThumbnailUrl; return(videoInfo); }); return(new SearchResult() { IsSucceeded = true, Videos = videos }); }
public STypes::Video ConvertLocalVideoToStoreVideo(IListVideoInfo source) { var converted = new STypes::Video(); converted.Id = source.Id.Value; converted.NiconicoId = source.NiconicoId.Value; converted.Title = source.Title.Value; converted.UploadedOn = source.UploadedOn.Value; converted.ThumbUrl = source.ThumbUrl.Value; converted.LargeThumbUrl = source.LargeThumbUrl.Value; converted.ThumbPath = source.ThumbPath.Value; converted.IsSelected = source.IsSelected.Value; converted.FileName = source.FileName.Value; converted.Tags = source.Tags.ToList(); converted.ViewCount = source.ViewCount.Value; converted.CommentCount = source.CommentCount.Value; converted.MylistCount = source.MylistCount.Value; converted.LikeCount = source.LikeCount.Value; converted.Duration = source.Duration.Value; converted.OwnerID = source.OwnerID.Value; converted.OwnerName = source.OwnerName.Value; return(converted); }
public IListVideoInfo ConvertStoreVideoToLocalVideo(STypes::Video source) { IListVideoInfo converted = this._container.GetVideo(source.NiconicoId); converted.Id.Value = source.Id; converted.NiconicoId.Value = source.NiconicoId; converted.Title.Value = source.Title; converted.IsDeleted.Value = source.IsDeleted; converted.OwnerName.Value = source.OwnerName; converted.UploadedOn.Value = source.UploadedOn; converted.LargeThumbUrl.Value = source.LargeThumbUrl; converted.ThumbUrl.Value = source.ThumbUrl; converted.ThumbPath.Value = source.ThumbPath; converted.FileName.Value = source.FileName; converted.Tags = source.Tags ?? new List <string>(); converted.ViewCount.Value = source.ViewCount; converted.CommentCount.Value = source.CommentCount; converted.MylistCount.Value = source.MylistCount; converted.LikeCount.Value = source.LikeCount; converted.OwnerID.Value = source.OwnerID; converted.Duration.Value = source.Duration; return(converted); }
public Task <IAttemptResult <IDownloadContext> > TryDownloadContentAsync(IListVideoInfo videoInfo, IDownloadSettings setting, Action <string> OnMessage, CancellationToken token) { return(Task.FromResult <IAttemptResult <IDownloadContext> >(AttemptResult <IDownloadContext> .Succeeded(new DownloadContext(string.Empty)))); }
/// <summary> /// サムネイルのパスが正しいかどうかを確認する /// </summary> /// <param name="video"></param> /// <returns></returns> public bool IsValidThumbnailPath(IListVideoInfo video) { string deletedVideoPath = this.GetThumbFilePath("0"); return(!video.ThumbPath.Value.IsNullOrEmpty() && video.ThumbPath.Value != deletedVideoPath); }
public IAttemptResult Update(IListVideoInfo video) { return(AttemptResult.Succeeded()); }
public IAttemptResult RemoveVideo(IListVideoInfo video) { return(AttemptResult.Succeeded()); }
/// <summary> /// サムネイルキャッシュの存在を確認する /// </summary> /// <param name="video"></param> /// <returns></returns> public bool HasThumbnailCache(IListVideoInfo video) { return(this.cacheHandler.HasCache(video.NiconicoId.Value, CacheType.Thumbnail)); }
public IAttemptResult RemoveVideo(IListVideoInfo video) { IAttemptResult result = this._videoStoreHandler.RemoveVideo(video.Id.Value); return(result); }
public IAttemptResult Update(IListVideoInfo video, int?playlistID = null, bool commit = true) { return(AttemptResult.Succeeded()); }
public IAttemptResult <int> AddVideo(IListVideoInfo video) { return(AttemptResult <int> .Succeeded(video.Id.Value)); }
public async Task <IAttemptResult <IDownloadContext> > TryDownloadContentAsync(IListVideoInfo videoInfo, IDownloadSettings setting, Action <string> OnMessage, CancellationToken token) { var context = new DownloadContext(setting.NiconicoId); var session = DIFactory.Provider.GetRequiredService <IWatchSession>(); context.RegisterMessageHandler(OnMessage); await session.GetVideoDataAsync(setting.NiconicoId); if (session.Video is not null) { this.converter.ConvertDomainVideoInfoToListVideoInfo(videoInfo, session.Video); } if (session.Video?.DmcInfo.DownloadStartedOn is not null) { session.Video.DmcInfo.DownloadStartedOn = DateTime.Now; } if (session.State != WatchSessionState.GotPage || session.Video is null) { string message = session.State switch { WatchSessionState.PaymentNeeded => "視聴ページの解析に失敗しました。", WatchSessionState.HttpRequestOrPageAnalyzingFailure => "視聴ページの取得、または視聴ページの解析に失敗しました。", _ => "不明なエラーにより、視聴ページの取得に失敗しました。" }; return(AttemptResult <IDownloadContext> .Fail(message)); } if (token.IsCancellationRequested) { return(this.CancelledDownloadAndGetResult()); } ILocalContentInfo?info = null; if (setting.Skip) { string fileNameFormat = setting.FileNameFormat; info = this.localContentHandler.GetLocalContentInfo(setting.FolderPath, fileNameFormat, session.Video.DmcInfo, setting.IsReplaceStrictedEnable, setting.VideoInfoExt, setting.IchibaInfoExt, setting.ThumbnailExt, setting.IchibaInfoSuffix, setting.VideoInfoSuffix); } if (!Directory.Exists(setting.FolderPath)) { Directory.CreateDirectory(setting.FolderPath); } //動画 if (setting.Video) { if (info?.VideoExist ?? false) { OnMessage("動画を保存済みのためスキップしました。"); } else if (setting.FromAnotherFolder && (info?.VIdeoExistInOnotherFolder ?? false) && info?.LocalPath is not null) { var vResult = this.localContentHandler.MoveDownloadedFile(setting.NiconicoId, info.LocalPath, setting.FolderPath); if (!vResult.IsSucceeded) { return(AttemptResult <IDownloadContext> .Fail(vResult.Message ?? "None")); } else { OnMessage("別フォルダーに保存済みの動画をコピーしました。"); } } else { var vResult = await this.TryDownloadVideoAsync(setting, OnMessage, session, context, token); if (!vResult.IsSucceeded) { OnMessage("DL失敗"); return(AttemptResult <IDownloadContext> .Fail(vResult.Message ?? "None")); } } } if (token.IsCancellationRequested) { return(this.CancelledDownloadAndGetResult()); } //サムネイル if (setting.Thumbnail) { if (!info?.ThumbExist ?? true) { var tResult = await this.TryDownloadThumbAsync(setting, session); if (token.IsCancellationRequested) { return(this.CancelledDownloadAndGetResult()); } if (!tResult.IsSucceeded) { OnMessage("DL失敗"); return(AttemptResult <IDownloadContext> .Fail(tResult.Message ?? "None")); } } else if (info?.ThumbExist ?? false) { OnMessage("サムネイルを保存済みのためスキップしました。"); } } if (token.IsCancellationRequested) { return(this.CancelledDownloadAndGetResult()); } //コメント if (setting.Comment) { if (!info?.CommentExist ?? true) { var cResult = await this.TryDownloadCommentAsync(setting, session, OnMessage, context, token); if (token.IsCancellationRequested) { return(this.CancelledDownloadAndGetResult()); } if (!cResult.IsSucceeded) { OnMessage("DL失敗"); return(AttemptResult <IDownloadContext> .Fail(cResult.Message ?? "None")); } } else if (info?.CommentExist ?? false) { OnMessage("コメントを保存済みのためスキップしました。"); } } if (token.IsCancellationRequested) { return(this.CancelledDownloadAndGetResult()); } //動画情報 if (setting.DownloadVideoInfo) { if (!info?.VideoInfoExist ?? true) { var iResult = this.TryDownloadDescriptionAsync(setting, session, OnMessage); if (token.IsCancellationRequested) { return(this.CancelledDownloadAndGetResult()); } if (!iResult.IsSucceeded) { OnMessage("DL失敗"); return(AttemptResult <IDownloadContext> .Fail(iResult.Message ?? "None")); } } } if (token.IsCancellationRequested) { return(this.CancelledDownloadAndGetResult()); } //市場情報 if (setting.DownloadIchibaInfo) { if (!info?.IchibaInfoExist ?? true) { var iResult = await this.DownloadIchibaInfoAsync(setting, session, OnMessage, context); if (token.IsCancellationRequested) { return(this.CancelledDownloadAndGetResult()); } if (!iResult.IsSucceeded) { OnMessage("DL失敗"); return(AttemptResult <IDownloadContext> .Fail(iResult.Message ?? "None")); } } else { OnMessage("市場情報を保存済みのためスキップしました。"); } } if (session.IsSessionEnsured) { session.Dispose(); } return(AttemptResult <IDownloadContext> .Succeeded(context)); }
/// <summary> /// サムネイルURLの形式が正しいかどうかを確認する /// </summary> /// <param name="video"></param> /// <returns></returns> public bool IsValidThumbnailUrl(IListVideoInfo video) { string deletedVideoUrl = NetConstant.NiconicoDeletedVideothumb; return(!(video.ThumbUrl.Value.IsNullOrEmpty() || video.ThumbUrl.Value == deletedVideoUrl)); }