From d4b34632d8266705de8c20ba4862a66e4daa72ed Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Fri, 21 Feb 2020 19:20:34 +0100 Subject: [PATCH 1/2] Fix for videos without keywords --- lib/src/youtube_explode_base.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/youtube_explode_base.dart b/lib/src/youtube_explode_base.dart index 70ac299..5cf1cd7 100644 --- a/lib/src/youtube_explode_base.dart +++ b/lib/src/youtube_explode_base.dart @@ -227,7 +227,7 @@ class YoutubeExplode { videoInfo['shortDescription'], ThumbnailSet(videoId), Duration(seconds: int.parse(videoInfo['lengthSeconds'])), - videoInfo['keywords'].cast(), + videoInfo['keywords']?.cast(), Statistics(int.parse(videoInfo['viewCount']), 0, 0)); var streamingData = playerResponseJson['streamingData']; @@ -293,7 +293,7 @@ class YoutubeExplode { var author = details['author']; var description = details['shortDescription']; var duration = Duration(seconds: int.parse(details['lengthSeconds'])); - var keyWords = details['keywords'].cast(); + var keyWords = details['keywords']?.cast(); var viewCount = int.tryParse(details['viewCount'] ?? '0') ?? 0; var videoPageHtml = await _getVideoWatchPageHtml(videoId); From e9b67691ef4312c8b0e1e3d178f45403c1073a3f Mon Sep 17 00:00:00 2001 From: "Bodhi Mulders (BeMacized)" Date: Fri, 21 Feb 2020 19:26:22 +0100 Subject: [PATCH 2/2] Request video content length when it is not yet provided --- lib/src/youtube_explode_base.dart | 35 +++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/lib/src/youtube_explode_base.dart b/lib/src/youtube_explode_base.dart index 5cf1cd7..6f81bab 100644 --- a/lib/src/youtube_explode_base.dart +++ b/lib/src/youtube_explode_base.dart @@ -63,8 +63,10 @@ class YoutubeExplode { } url ??= Uri.parse(urlString); - var contentLength = - _parseContentLength(streamInfoJson['contentLength'], urlString); + var contentLength = await _parseContentLength( + streamInfoJson['contentLength'], + urlString, + ); // Extract container var mimeType = ContentType.parse(streamInfoJson['mimeType'] as String); @@ -125,8 +127,10 @@ class YoutubeExplode { } url ??= Uri.parse(urlString); - var contentLength = - _parseContentLength(streamInfoJson['contentLength'], urlString); + var contentLength = await _parseContentLength( + streamInfoJson['contentLength'], + urlString, + ); // Extract container var mimeType = ContentType.parse(streamInfoJson['mimeType'] as String); @@ -323,18 +327,31 @@ class YoutubeExplode { duration, keyWords, statistics); } - int _parseContentLength(String contentLengthString, String url) { - var contentLength = int.tryParse(contentLengthString) ?? -1; + Future _parseContentLength( + String contentLengthString, String url) async { + var contentLength = int.tryParse(contentLengthString ?? '') ?? -1; + if (contentLength <= 0) { contentLength = _contentLenRegexp?.firstMatch(url)?.group(1) ?? -1; } if (contentLength <= 0) { - // TODO: Implement get request to get length. -// print('Not implemented'); + contentLength = await _requestContentLength(url); + } + + return contentLength; + } + + Future _requestContentLength(String url) async { + var resp; + try { + resp = await http.head(url); + } on Exception catch (e) { return -1; } - return contentLength; + if (!resp.headers.containsKey('content-length')) return -1; + String contentLengthString = resp.headers['content-length']; + return int.tryParse(contentLengthString ?? '') ?? -1; } Future _getVideoWatchPageHtml(String videoId) async {