public VideoUrlParseResult ParseBySoundCloudUrl(string url) { var apiUrl = string.Format("http://api.soundcloud.com/resolve?url=http://soundcloud.com/{0}&client_id=YOUR_CLIENT_ID", url); var request = WebRequest.Create(apiUrl); XDocument doc; try { using (var response = request.GetResponse()) using (var stream = response.GetResponseStream()) { doc = XDocument.Load(stream); } } catch (WebException x) { log.WarnException("Unable to load SoundCloud URL " + url, x); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException("Unable to load SoundCloud URL: " + x.Message, x))); } var trackIdElem = doc.XPathSelectElement("//track/id"); var titleElem = doc.XPathSelectElement("//track/title"); if (trackIdElem == null || titleElem == null) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "Unable to load SoundCloud URL: Invalid response.")); } var trackId = trackIdElem.Value; var title = titleElem.Value; var author = XmlHelper.GetNodeTextOrEmpty(doc, "//track/user/username"); var thumbUrl = XmlHelper.GetNodeTextOrEmpty(doc, "//track/artwork-url"); var id = new SoundCloudId(trackId, url); return(VideoUrlParseResult.CreateOk(url, PVService.SoundCloud, id.ToString(), VideoTitleParseResult.CreateSuccess(title, author, thumbUrl))); }
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))); }
protected virtual async Task <VideoUrlParseResult> ParseByIdAsync(string id, string url, bool getMeta) { var meta = (getMeta ? await GetVideoTitleAsync(id) : VideoTitleParseResult.Empty) ?? VideoTitleParseResult.Empty; // Note that even if meta lookup failed, we're returning Ok here, because for example NND API doesn't support all PVs. return(VideoUrlParseResult.CreateOk(url, Service, id, meta)); }
public async Task <VideoUrlParseResult> ParseBySoundCloudUrl(string url) { var apikey = AppConfig.SoundCloudClientId; var apiUrl = string.Format("https://api.soundcloud.com/resolve?url=http://soundcloud.com/{0}&client_id={1}", url, apikey); SoundCloudResult result; bool HasStatusCode(WebException x, HttpStatusCode statusCode) => x.Response != null && ((HttpWebResponse)x.Response).StatusCode == statusCode; VideoUrlParseResult ReturnError(Exception x, string additionalInfo = null) { var msg = string.Format("Unable to load SoundCloud URL '{0}'.{1}", url, additionalInfo != null ? " " + additionalInfo + ".": string.Empty); log.Warn(x, msg); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(msg, x))); } try { result = await JsonRequest.ReadObjectAsync <SoundCloudResult>(apiUrl, timeoutMs : 10000); } catch (WebException x) when(HasStatusCode(x, HttpStatusCode.Forbidden)) { // Forbidden most likely means the artist has prevented API access to their tracks, http://stackoverflow.com/a/36529330 return(ReturnError(x, "This track cannot be embedded")); } catch (WebException x) when(HasStatusCode(x, HttpStatusCode.NotFound)) { return(ReturnError(x, "Not found")); } catch (WebException x) { return(ReturnError(x)); } catch (JsonSerializationException x) { return(ReturnError(x)); } var trackId = result.Id; var title = result.Title; if (trackId == null || title == null) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "Unable to load SoundCloud URL: Invalid response.")); } var author = result.User.Username; var length = result.Duration / 1000; var thumbUrl = result.Artwork_url; // Substitute song thumbnail with user avatar, if no actual thumbnail is provided. This is what the SoundCloud site does as well. if (string.IsNullOrEmpty(thumbUrl)) { thumbUrl = result.User.Avatar_url; } var uploadDate = result.Created_at; var id = new SoundCloudId(trackId, url); var authorId = result.User.Permalink; // Using permalink because that's the public URL return(VideoUrlParseResult.CreateOk(url, PVService.SoundCloud, id.ToString(), VideoTitleParseResult.CreateSuccess(title, author, authorId, thumbUrl, length, uploadDate: uploadDate))); }
protected virtual async Task <VideoUrlParseResult> ParseByIdAsync(string id, string url, bool getMeta) { var meta = (getMeta ? await GetVideoTitleAsync(id) : VideoTitleParseResult.Empty) ?? VideoTitleParseResult.Empty; // Note that even if meta lookup failed, we're returning Ok here, because for example NND API doesn't support all PVs. // Metadata is optional. We should only return an error if the metadata is mandatory or there was a fatal unhandled error. return(VideoUrlParseResult.CreateOk(url, Service, id, meta)); }
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 virtual Task <VideoUrlParseResult> ParseByUrlAsync(string url, bool getTitle) { var id = GetIdByUrl(url); if (id == null) { return(Task.FromResult(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.NoMatcher))); } return(ParseByIdAsync(id, url, getTitle)); }
public static VideoUrlParseResult ParseByUrl(string url, bool getTitle, IUserPermissionContext permissionContext) { var service = services.FirstOrDefault(s => s.IsAuthorized(permissionContext) && s.IsValidFor(url)); if (service == null) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.NoMatcher)); } return(service.ParseByUrl(url, getTitle)); }
public static VideoUrlParseResult ParseByUrl(string url, bool getTitle) { var service = services.FirstOrDefault(s => s.IsValidFor(url)); if (service == null) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.NoMatcher)); } return(service.ParseByUrl(url, getTitle)); }
public static Task <VideoUrlParseResult> ParseByUrlAsync(string url, bool getTitle, IUserPermissionContext permissionContext, params VideoService[] testServices) { var service = testServices.FirstOrDefault(s => s.IsAuthorized(permissionContext) && s.IsValidFor(url)); if (service == null) { return(Task.FromResult(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.NoMatcher))); } return(service.ParseByUrlAsync(url, getTitle)); }
public override VideoUrlParseResult ParseByUrl(string url, bool getTitle) { var id = GetIdByUrl(url); if (string.IsNullOrEmpty(id)) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.NoMatcher, "No matcher")); } 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); var request = (HttpWebRequest)WebRequest.Create(requestUrl); request.UserAgent = "VocaDB/1.0 ([email protected])"; request.Timeout = 10000; XDocument doc; try { using (var response = request.GetResponse()) using (var stream = response.GetResponseStream()) { doc = XDocument.Load(stream); } } 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 createdElem = doc.XPathSelectElement("/info/created_at"); if (titleElem == null) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "No title element")); } var title = HtmlEntity.DeEntitize(titleElem.Value); var thumb = thumbElem != null ? thumbElem.Value : string.Empty; var author = authorElem != null ? authorElem.Value : string.Empty; var created = createdElem != null ? (DateTime?)DateTime.Parse(createdElem.Value) : null; return(VideoUrlParseResult.CreateOk(url, PVService.Bilibili, id, VideoTitleParseResult.CreateSuccess(title, author, thumb, uploadDate: created))); }
public virtual VideoUrlParseResult ParseByUrl(string url, bool getTitle) { var id = GetIdByUrl(url); if (id == null) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.NoMatcher)); } return(ParseById(id, url, getTitle)); }
public override async Task <VideoUrlParseResult> ParseByUrlAsync(string url, bool getTitle) { PostQueryResult result; try { result = await new PiaproClient.PiaproClient().ParseByUrlAsync(url); } catch (PiaproException x) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(x.Message, x))); } return(Parse(result, url)); }
protected virtual VideoUrlParseResult ParseById(string id, string url, bool getMeta) { var meta = (getMeta ? GetVideoTitle(id) : VideoTitleParseResult.Empty) ?? VideoTitleParseResult.Empty; //if (!meta.Success) { // return VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, meta.Error); //} // Note that even if meta lookup failed, we're returning Ok here, because for example NND API doesn't support all PVs. return(VideoUrlParseResult.CreateOk(url, Service, id, meta)); }
public PVContract(VideoUrlParseResult parseResult, PVType type) { ParamIs.NotNull(() => parseResult); Author = parseResult.Author; Name = parseResult.Title; PVId = parseResult.Id; Service = parseResult.Service; ThumbUrl = parseResult.ThumbUrl; PVType = type; Url = PV.GetUrl(Service, PVId); }
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))); }
public VideoUrlParseResult ParseBySoundCloudUrl(string url) { var apikey = AppConfig.SoundCloudClientId; var apiUrl = string.Format("http://api.soundcloud.com/resolve?url=http://soundcloud.com/{0}&client_id={1}", url, apikey); SoundCloudResult result; try { result = JsonRequest.ReadObject <SoundCloudResult>(apiUrl, timeoutMs: 10000); } catch (WebException x) { var msg = string.Format("Unable to load SoundCloud URL '{0}'.", url); // Forbidden most likely means the artist has prevented API access to their tracks, http://stackoverflow.com/a/36529330 if (((HttpWebResponse)x.Response).StatusCode == HttpStatusCode.Forbidden) { msg += " This track cannot be embedded."; } log.Warn(x, msg); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(msg, x))); } catch (JsonSerializationException x) { var msg = string.Format("Unable to load SoundCloud URL '{0}'.", url); log.Warn(x, msg); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(msg, x))); } var trackId = result.Id; var title = result.Title; if (trackId == null || title == null) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "Unable to load SoundCloud URL: Invalid response.")); } var author = result.User.Username; var length = result.Duration / 1000; var thumbUrl = result.Artwork_url; // Substitute song thumbnail with user avatar, if no actual thumbnail is provided. This is what the SoundCloud site does as well. if (string.IsNullOrEmpty(thumbUrl)) { thumbUrl = result.User.Avatar_url; } var uploadDate = result.Created_at; var id = new SoundCloudId(trackId, url); return(VideoUrlParseResult.CreateOk(url, PVService.SoundCloud, id.ToString(), VideoTitleParseResult.CreateSuccess(title, author, thumbUrl, length, uploadDate: uploadDate))); }
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) { PostQueryResult result; var client = new PiaproClient.PiaproClient { RequestTimeout = TimeSpan.FromMilliseconds(3900) /* Value chosen after careful consideration */ }; try { result = await client.ParseByUrlAsync(url); } catch (PiaproException x) { log.Warn(x, "Unable to load Piapro URL {0}", url); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(x.Message, x))); } return(Parse(result, url)); }
public VideoUrlParseResult ParseBySoundCloudUrl(string url) { var apiUrl = string.Format("http://api.soundcloud.com/resolve?url=http://soundcloud.com/{0}&client_id=YOUR_CLIENT_ID", url); var request = WebRequest.Create(apiUrl); request.Timeout = 10000; SoundCloudResult result; try { using (var response = request.GetResponse()) using (var stream = response.GetResponseStream()) using (var streamReader = new StreamReader(stream)) using (var jsonReader = new JsonTextReader(streamReader)) { var serializer = new JsonSerializer(); result = serializer.Deserialize <SoundCloudResult>(jsonReader); } } catch (WebException x) { var msg = string.Format("Unable to load SoundCloud URL {0}", url); log.Warn(msg, x); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(msg, x))); } var trackId = result.Id; var title = result.Title; if (trackId == null || title == null) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "Unable to load SoundCloud URL: Invalid response.")); } var author = result.User.Username; var length = result.Duration / 1000; var thumbUrl = result.Artwork_url; // Substitute song thumbnail with user avatar, if no actual thumbnail is provided. This is what the SoundCloud site does as well. if (string.IsNullOrEmpty(thumbUrl)) { thumbUrl = result.User.Avatar_url; } var id = new SoundCloudId(trackId, url); return(VideoUrlParseResult.CreateOk(url, PVService.SoundCloud, id.ToString(), VideoTitleParseResult.CreateSuccess(title, author, thumbUrl, length))); }
public override VideoUrlParseResult ParseByUrl(string url, bool getTitle) { PostQueryResult result; try { result = new PiaproClient.PiaproClient().ParseByUrl(url); } catch (PiaproException x) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(x.Message, x))); } if (result.PostType != PostType.Audio) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException("Content type indicates this isn't an audio post"))); } return(VideoUrlParseResult.CreateOk(url, PVService.Piapro, result.Id, VideoTitleParseResult.CreateSuccess(result.Title, result.Author, string.Empty, result.LengthSeconds, uploadDate: result.Date))); }
public override async Task <VideoUrlParseResult> ParseByUrlAsync(string url, bool getTitle) { url = UrlHelper.MakeLink(url); Uri parsedUri; try { parsedUri = new Uri(url, UriKind.Absolute); } catch (UriFormatException x) { var msg = string.Format("{0} could not be parsed as a valid URL.", url); log.Warn(x, msg); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(msg, x))); } var request = new HttpRequestMessage(HttpMethod.Head, url); request.Headers.UserAgent.Add(new ProductInfoHeaderValue("VocaDB", "1.0")); try { using (var client = new HttpClient()) { client.Timeout = TimeSpan.FromSeconds(10); using (var response = await client.SendAsync(request)) { response.EnsureSuccessStatusCode(); var mime = response.Content.Headers.ContentType?.MediaType; if (!mimeTypes.Contains(mime)) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, string.Format("Unsupported content type: {0}", mime))); } } } } catch (WebException x) { var msg = string.Format("Unable to load file URL {0}. The file might not be publicly accessible", url); log.Warn(x, msg); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(msg, x))); } return(VideoUrlParseResult.CreateOk(url, PVService.File, url, await GetVideoTitleAsync(url))); }
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 VideoUrlParseResult ParseByUrl(string url, bool getTitle) { var id = GetIdByUrl(url); if (string.IsNullOrEmpty(id)) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.NoMatcher, "No matcher")); } var requestUrl = string.Format("http://api.bilibili.tv/view?type=xml&appkey={0}&id={1}", AppConfig.BilibiliAppKey, id); var request = WebRequest.Create(requestUrl); XDocument doc; try { using (var response = request.GetResponse()) using (var stream = response.GetResponseStream()) { doc = XDocument.Load(stream); } } catch (WebException x) { log.WarnException("Unable to load Bilibili URL " + url, x); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException("Unable to load Bilibili URL: " + x.Message, x))); } var titleElem = doc.XPathSelectElement("/info/title"); var thumbElem = doc.XPathSelectElement("/info/pic"); var authorElem = doc.XPathSelectElement("/info/author"); if (titleElem == null) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "No title element")); } var title = HtmlEntity.DeEntitize(titleElem.Value); var thumb = thumbElem != null ? thumbElem.Value : string.Empty; var author = authorElem != null ? authorElem.Value : string.Empty; return(VideoUrlParseResult.CreateOk(url, PVService.Bilibili, id, VideoTitleParseResult.CreateSuccess(title, author, thumb))); }
public override VideoUrlParseResult ParseByUrl(string url, bool getTitle) { url = UrlHelper.MakeLink(url); Uri parsedUri; try { parsedUri = new Uri(url, UriKind.Absolute); } catch (UriFormatException x) { var msg = string.Format("{0} could not be parsed as a valid URL.", url); log.Warn(x, msg); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(msg, x))); } var request = WebRequest.CreateHttp(parsedUri); request.UserAgent = "VocaDB"; request.Method = "HEAD"; request.Timeout = 10000; try { using (var response = request.GetResponse()) { var mime = response.ContentType; if (!mimeTypes.Contains(mime)) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, string.Format("Unsupported content type: {0}", mime))); } } } catch (WebException x) { var msg = string.Format("Unable to load file URL {0}. The file might not be publicly accessible", url); log.Warn(x, msg); return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, new VideoParseException(msg, x))); } return(VideoUrlParseResult.CreateOk(url, PVService.File, url, GetVideoTitle(url))); }
/*public override string GetUrlById(string id) { * * var compositeId = new CompositeId(id); * var matcher = linkMatchers.First(); * return "http://" + matcher.MakeLinkFromId(compositeId.SoundCloudUrl); * * }*/ private VideoUrlParseResult ParseByHtmlStream(Stream htmlStream, Encoding encoding, string url) { var doc = new HtmlDocument(); doc.Load(htmlStream, encoding); var catLink = doc.DocumentNode.SelectSingleNode("//div[@class = 'dtl_data']/p[3]"); if (catLink == null || !catLink.InnerHtml.Contains("/illust/?categoryId=1")) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "Content type indicates this isn't an audio file.")); } var idElem = doc.DocumentNode.SelectSingleNode("//input[@name = 'id']"); if (idElem == null) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "Could not find id element on page.")); } var contentId = idElem.GetAttributeValue("value", string.Empty); var titleElem = doc.DocumentNode.SelectSingleNode("//h1[@class = 'dtl_title']"); if (titleElem == null) { return(VideoUrlParseResult.CreateError(url, VideoUrlParseResultType.LoadError, "Could not find title element on page.")); } var title = HtmlEntity.DeEntitize(titleElem.InnerText).Trim(); var authorElem = doc.DocumentNode.SelectSingleNode("//div[@class = 'dtl_by_name']/a"); var author = (authorElem != null ? authorElem.InnerText : string.Empty); return(VideoUrlParseResult.CreateOk(url, PVService.Piapro, contentId, VideoTitleParseResult.CreateSuccess(title, author, string.Empty))); }
public virtual VideoUrlParseResult ParseById(string id, string url, bool getMeta) { var meta = (getMeta ? GetVideoTitle(id) : VideoTitleParseResult.Empty); return(VideoUrlParseResult.CreateOk(url, Service, id, meta)); }