diff --git a/lib/src/youtube_explode_base.dart b/lib/src/youtube_explode_base.dart index 4a2daa6..a783da9 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 = MediaType.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 = MediaType.parse(streamInfoJson['mimeType'] as String); @@ -227,7 +231,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 +297,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); @@ -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 {