public override async Task <VideoUrlParseResult> ParseByUrlAsync(string url, bool getTitle) { var id = GetIdByUrl(url); if (string.IsNullOrEmpty(id)) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.NoMatcher, "No matcher")); } if (!getTitle) { return(VideoUrlParseResult.CreateOk(url, PVService.Bilibili, id, VideoTitleParseResult.Empty)); } var paramStr = string.Format("appkey={0}&id={1}&type=xml{2}", AppConfig.BilibiliAppKey, id, AppConfig.BilibiliSecretKey); var paramStrMd5 = CryptoHelper.HashString(paramStr, CryptoHelper.MD5).ToLowerInvariant(); var requestUrl = string.Format("https://api.bilibili.com/view?appkey={0}&id={1}&type=xml&sign={2}", AppConfig.BilibiliAppKey, id, paramStrMd5); XDocument doc; try { doc = await HtmlRequestHelper.GetStreamAsync(requestUrl, stream => XDocument.Load(stream), timeoutSec : 10, userAgent : "VocaDB/1.0 ([email protected])"); } catch (WebException x) { log.Warn(x, "Unable to load Bilibili URL {0}", url); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(string.Format("Unable to load Bilibili URL: {0}", x.Message), x))); } catch (XmlException x) { log.Warn(x, "Unable to load Bilibili URL {0}", url); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(string.Format("Unable to load Bilibili URL: {0}", x.Message), x))); } catch (IOException x) { log.Warn(x, "Unable to load Bilibili URL {0}", url); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(string.Format("Unable to load Bilibili URL: {0}", x.Message), x))); } var titleElem = doc.XPathSelectElement("/info/title"); var thumbElem = doc.XPathSelectElement("/info/pic"); var authorElem = doc.XPathSelectElement("/info/author"); var authorId = GetValue(doc, "/info/mid"); var createdElem = doc.XPathSelectElement("/info/created_at"); int.TryParse(GetValue(doc, "/info/cid"), out var cid); // Unsure what this is, but it's required for embedding if (titleElem == null) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "No title element")); } var title = HtmlEntity.DeEntitize(titleElem.Value); var thumb = thumbElem?.Value ?? string.Empty; var author = authorElem?.Value ?? string.Empty; var created = createdElem != null ? (DateTime?)DateTime.Parse(createdElem.Value) : null; var length = await GetLength(id); var metadata = new PVExtendedMetadata(new BiliMetadata { Cid = cid }); return(VideoUrlParseResult.CreateOk(url, PVService.Bilibili, id, VideoTitleParseResult.CreateSuccess(title, author, authorId, thumb, length: length, uploadDate: created, extendedMetadata: metadata))); }
public override string GetUrlById(string id, PVExtendedMetadata extendedMetadata = null) { var compositeId = new SoundCloudId(id); var matcher = _linkMatchers.First(); return($"http://{matcher.MakeLinkFromId(compositeId.SoundCloudUrl)}"); }
public override async Task <VideoUrlParseResult> ParseByUrlAsync(string url, bool getTitle) { var youtubeDl = new YoutubeDL { RetrieveAllInfo = true, YoutubeDlPath = GetPath(AppConfig.YoutubeDLPath), PythonPath = GetPath(AppConfig.PythonPath) }; youtubeDl.StandardOutputEvent += StandardOutputEvent; youtubeDl.StandardErrorEvent += StandardErrorEvent; DownloadInfo result; try { var task = youtubeDl.GetDownloadInfoAsync(url); result = await TimeoutAfter(task, 10000); } catch (TaskCanceledException) { var warnings = GetErrorString(youtubeDl.Info); _log.Error("Timeout. Error list: {0}", warnings); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "Timeout")); } catch (TimeoutException) { youtubeDl.CancelDownload(); _log.Error("Timeout"); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "Timeout")); } if (result == null) { var warnings = GetErrorString(youtubeDl.Info); _log.Error("Result from parser is empty. Error list: {0}", warnings); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "Result from parser is empty")); } if (!(result is VideoDownloadInfo info)) { var warnings = GetErrorString(youtubeDl.Info); _log.Error("Unexpected result from parser. Error list: {0}. Result type is {1}. Title is {2}", warnings, result.GetType().Name, result.Title); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "Unexpected result from parser.")); } DateTime?date = null; if (DateTime.TryParseExact(info.UploadDate, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out var parsedDate)) { date = parsedDate; } var bandcampMetadata = new PVExtendedMetadata(new BandcampMetadata { Url = info.WebpageUrl }); var meta = VideoTitleParseResult.CreateSuccess(info.Title, info.Uploader, info.UploaderId, info.Thumbnail, (int?)info.Duration, uploadDate: date, extendedMetadata: bandcampMetadata); return(VideoUrlParseResult.CreateOk(url, PVService.Bandcamp, info.Id, meta)); }
public VideoTitleParseResult(bool success, string error, string title, string author, string authorId, string thumbUrl, int?length = null, string[] tags = null, DateTime?uploadDate = null, PVExtendedMetadata extendedMetadata = null) { Error = error; Success = success; Title = title ?? string.Empty; Author = author ?? string.Empty; AuthorId = authorId ?? string.Empty; ThumbUrl = thumbUrl ?? string.Empty; LengthSeconds = length; UploadDate = uploadDate; ExtendedMetadata = extendedMetadata; Tags = tags ?? new string[0]; }
public override async Task <VideoUrlParseResult> ParseByUrlAsync(string url, bool getTitle) { var id = GetIdByUrl(url); if (string.IsNullOrEmpty(id)) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.NoMatcher, "No matcher")); } var requestUrl = "https://api.bilibili.com/x/web-interface/view?" + (id.StartsWith("BV") ? $"bvid={id}" : $"aid={id}"); BilibiliResponse response; try { response = await JsonRequest.ReadObjectAsync <BilibiliResponse>(requestUrl, timeout : TimeSpan.FromSeconds(10), userAgent : "VocaDB/1.0 ([email protected])"); } catch (Exception x) when(x is HttpRequestException || x is WebException || x is JsonSerializationException || x is IOException) { log.Warn(x, "Unable to load Bilibili URL {0}", url); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(string.Format("Unable to load Bilibili URL: {0}", x.Message), x))); } var authorId = response.Data.Owner.Mid.ToString(); var aid = response.Data.Aid; var bvid = response.Data.Bvid; var cid = response.Data.Cid; if (!getTitle) { return(VideoUrlParseResult.CreateOk(url, PVService.Bilibili, aid.ToString(), VideoTitleParseResult.Empty)); } if (string.IsNullOrEmpty(response.Data.Title)) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "No title element")); } var title = HtmlEntity.DeEntitize(response.Data.Title); var thumb = response.Data.Pic ?? string.Empty; var author = response.Data.Owner.Name ?? string.Empty; var created = response.Data.PubDate; var length = response.Data.Duration; var metadata = new PVExtendedMetadata(new BiliMetadata { Aid = aid, Bvid = bvid, Cid = cid }); return(VideoUrlParseResult.CreateOk(url, PVService.Bilibili, aid.ToString(), VideoTitleParseResult.CreateSuccess(title, author, authorId, thumb, length: length, uploadDate: created, extendedMetadata: metadata))); }
private VideoUrlParseResult Parse(PostQueryResult result, string url) { if (result.PostType != PostType.Audio) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException("Content type indicates this isn't an audio post"))); } var piaproMetadata = new PVExtendedMetadata(new PiaproMetadata { Timestamp = result.UploadTimestamp }); return(VideoUrlParseResult.CreateOk(url, PVService.Piapro, result.Id, VideoTitleParseResult.CreateSuccess(result.Title, result.Author, result.AuthorId, result.ArtworkUrl, result.LengthSeconds, uploadDate: result.Date, extendedMetadata: piaproMetadata))); }
public override async Task <VideoUrlParseResult> ParseByUrlAsync(string url, bool getTitle) { var extractor = new BandcampMetadataClient(); var info = await extractor.ExtractAsync(url); DateTime?date = null; if (DateTime.TryParseExact(info.UploadDate, "yyyyMMdd", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out var parsedDate)) { date = parsedDate; } var bandcampMetadata = new PVExtendedMetadata(new BandcampMetadata { Url = info.WebpageUrl }); var meta = VideoTitleParseResult.CreateSuccess(info.Title, info.Uploader, info.UploaderId, info.Thumbnail, (int?)info.Duration, uploadDate: date, extendedMetadata: bandcampMetadata); return(VideoUrlParseResult.CreateOk(url, PVService.Bandcamp, info.Id, meta)); }
public override string GetUrlById(string id, PVExtendedMetadata extendedMetadata = null) { var bandcampMetadata = extendedMetadata?.GetExtendedMetadata <BandcampMetadata>(); return(bandcampMetadata?.Url ?? base.GetUrlById(id, extendedMetadata)); }
public override string GetUrlById(string id, PVExtendedMetadata _) => $"https://www.bilibili.com/video/av{id}";
public override string GetUrlById(string id, PVExtendedMetadata _) { return(VocaUriBuilder.StaticResource("/media/" + id)); }
public override string GetUrlById(string id, PVExtendedMetadata _) { var matcher = _linkMatchers.First(); return($"https://{matcher.MakeLinkFromId(id)}"); }
public override string GetUrlById(string id, PVExtendedMetadata _) { return(id); }
public virtual string GetUrlById(string id, PVExtendedMetadata extendedMetadata) { var matcher = linkMatchers.First(); return(string.Format("http://{0}", matcher.MakeLinkFromId(id))); }
public override string GetUrlById(string id, PVExtendedMetadata _) { var matcher = linkMatchers.First(); return(string.Format("https://{0}", matcher.MakeLinkFromId(id))); }
public static VideoTitleParseResult CreateSuccess(string title, string author, string authorId, string thumbUrl, int?length = null, string[] tags = null, DateTime?uploadDate = null, PVExtendedMetadata extendedMetadata = null) { return(new VideoTitleParseResult(true, null, title, author, authorId, thumbUrl, length, tags, uploadDate, extendedMetadata)); }