From b5a4ab116fde10e8fc4f9ad9ee02e1e9ed830b98 Mon Sep 17 00:00:00 2001 From: Hexah Date: Fri, 19 Jun 2020 16:24:16 +0200 Subject: [PATCH 1/4] Remove failing test. --- test/streams_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/streams_test.dart b/test/streams_test.dart index 814d04d..37eaf9d 100644 --- a/test/streams_test.dart +++ b/test/streams_test.dart @@ -15,7 +15,7 @@ void main() { test('GetStreamsOfAnyVideo', () async { var data = { '9bZkp7q19f0', - 'SkRSXFQerZs', +// 'SkRSXFQerZs', age restricted videos are not supported anymore. 'hySoCSoH-g8', '_kmeFXjjGfk', 'MeJVWBSsPAY', From c1d13cba4eda143eaaa27b7839cf44ceebe86f0a Mon Sep 17 00:00:00 2001 From: Hexah Date: Fri, 19 Jun 2020 19:19:00 +0200 Subject: [PATCH 2/4] Ignore `isRateLimited`. --- CHANGELOG.md | 3 +++ .../youtube_http_client.dart | 25 ++++++++++--------- pubspec.yaml | 2 +- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c0dcf82..e2eafd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.2.2 +- Momentarily ignore `isRateLimited()` when getting streams. + ## 1.2.1 - Fixed `SearchPage.nextPage`. diff --git a/lib/src/reverse_engineering/youtube_http_client.dart b/lib/src/reverse_engineering/youtube_http_client.dart index b8f3dc7..c8e9e53 100644 --- a/lib/src/reverse_engineering/youtube_http_client.dart +++ b/lib/src/reverse_engineering/youtube_http_client.dart @@ -73,29 +73,30 @@ class YoutubeHttpClient { return response.body; } + // TODO: Check why isRateLimited is not working. Stream> getStream(StreamInfo streamInfo, {Map headers, bool validate = true}) async* { var url = streamInfo.url; - if (!streamInfo.isRateLimited()) { +// if (streamInfo.isRateLimited()) { +// var request = Request('get', url); +// request.headers.addAll(_defaultHeaders); +// var response = await request.send(); +// if (validate) { +// _validateResponse(response, response.statusCode); +// } +// yield* response.stream; +// } else { + for (var i = 0; i < streamInfo.size.totalBytes; i += 9898989) { var request = Request('get', url); + request.headers['range'] = 'bytes=$i-${i + 9898989}'; request.headers.addAll(_defaultHeaders); var response = await request.send(); if (validate) { _validateResponse(response, response.statusCode); } yield* response.stream; - } else { - for (var i = 0; i < streamInfo.size.totalBytes; i += 9898989) { - var request = Request('get', url); - request.headers['range'] = 'bytes=$i-${i + 9898989}'; - request.headers.addAll(_defaultHeaders); - var response = await request.send(); - if (validate) { - _validateResponse(response, response.statusCode); - } - yield* response.stream; - } } +// } } Future getContentLength(dynamic url, diff --git a/pubspec.yaml b/pubspec.yaml index 89d1e1b..11eea2b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: youtube_explode_dart description: A port in dart of the youtube explode library. Supports several API functions without the need of Youtube API Key. -version: 1.2.1 +version: 1.2.2 homepage: https://github.com/Hexer10/youtube_explode_dart environment: From aad1c895cbad30a18b28c3b17bb008c524086a82 Mon Sep 17 00:00:00 2001 From: Hexah Date: Sat, 20 Jun 2020 12:45:28 +0200 Subject: [PATCH 3/4] Fix duplicated bytes in streams. Closes #41 --- example/video_download.dart | 4 +- .../youtube_http_client.dart | 42 +++++++------------ pubspec.yaml | 2 +- 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/example/video_download.dart b/example/video_download.dart index 751ab44..c8353b8 100644 --- a/example/video_download.dart +++ b/example/video_download.dart @@ -36,8 +36,8 @@ Future download(String id) async { var manifest = await yt.videos.streamsClient.getManifest(id); var streams = manifest.audioOnly; - // Get the last audio track (the one with the highest bitrate). - var audio = streams.last; + // Get the audio track with the highest bitrate. + var audio = streams.withHighestBitrate(); var audioStream = yt.videos.streamsClient.get(audio); // Compose the file name removing the unallowed characters in windows. diff --git a/lib/src/reverse_engineering/youtube_http_client.dart b/lib/src/reverse_engineering/youtube_http_client.dart index c8e9e53..ddb27d5 100644 --- a/lib/src/reverse_engineering/youtube_http_client.dart +++ b/lib/src/reverse_engineering/youtube_http_client.dart @@ -1,10 +1,10 @@ -import 'package:http/http.dart'; +import 'package:http/http.dart' as http; import '../exceptions/exceptions.dart'; import '../videos/streams/streams.dart'; -class YoutubeHttpClient { - final Client _httpClient = Client(); +class YoutubeHttpClient extends http.BaseClient { + final http.Client _httpClient = http.Client(); final Map _defaultHeaders = const { 'user-agent': @@ -15,7 +15,7 @@ class YoutubeHttpClient { }; /// Throws if something is wrong with the response. - void _validateResponse(BaseResponse response, int statusCode) { + void _validateResponse(http.BaseResponse response, int statusCode) { var request = response.request; if (request.url.host.endsWith('.google.com') && request.url.path.startsWith('/sorry/')) { @@ -35,22 +35,9 @@ class YoutubeHttpClient { } } - Future get(dynamic url, {Map headers}) { - return _httpClient.get(url, headers: {...?headers, ..._defaultHeaders}); - } - - Future post(dynamic url, {Map headers}) { - return _httpClient.post(url, headers: {...?headers, ..._defaultHeaders}); - } - - Future head(dynamic url, {Map headers}) { - return _httpClient.head(url, headers: {...?headers, ..._defaultHeaders}); - } - Future getString(dynamic url, {Map headers, bool validate = true}) async { - var response = - await _httpClient.get(url, headers: {...?headers, ..._defaultHeaders}); + var response = await get(url, headers: {...?headers, ..._defaultHeaders}); if (validate) { _validateResponse(response, response.statusCode); @@ -63,8 +50,7 @@ class YoutubeHttpClient { {Map body, Map headers, bool validate = true}) async { - var response = await _httpClient.post(url, - headers: {...?headers, ..._defaultHeaders}, body: body); + var response = await post(url, headers: headers, body: body); if (validate) { _validateResponse(response, response.statusCode); @@ -87,10 +73,9 @@ class YoutubeHttpClient { // yield* response.stream; // } else { for (var i = 0; i < streamInfo.size.totalBytes; i += 9898989) { - var request = Request('get', url); - request.headers['range'] = 'bytes=$i-${i + 9898989}'; - request.headers.addAll(_defaultHeaders); - var response = await request.send(); + var request = http.Request('get', url); + request.headers['range'] = 'bytes=$i-${i + 9898989 - 1}'; + var response = await send(request); if (validate) { _validateResponse(response, response.statusCode); } @@ -110,7 +95,12 @@ class YoutubeHttpClient { return int.tryParse(response.headers['content-length'] ?? ''); } - /// Closes the [Client] assigned to this [YoutubeHttpClient]. - /// Should be called after this is not used anymore. + @override void close() => _httpClient.close(); + + @override + Future send(http.BaseRequest request) { + request.headers.addAll(_defaultHeaders); + return _httpClient.send(request); + } } diff --git a/pubspec.yaml b/pubspec.yaml index 11eea2b..6f2375d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: youtube_explode_dart description: A port in dart of the youtube explode library. Supports several API functions without the need of Youtube API Key. -version: 1.2.2 +version: 1.2.3 homepage: https://github.com/Hexer10/youtube_explode_dart environment: From 926042e33f9d027e736a8095a1ed9f91fbf09a3a Mon Sep 17 00:00:00 2001 From: Hexah Date: Sat, 20 Jun 2020 12:49:11 +0200 Subject: [PATCH 4/4] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2eafd7..03d2cd7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 1.2.3 +- Fix duplicated bytes when downloading a stream. See [#41][Comment41] + ## 1.2.2 - Momentarily ignore `isRateLimited()` when getting streams. @@ -116,3 +119,6 @@ - Fixed bug in #23 + + +[Comment41]: https://github.com/Hexer10/youtube_explode_dart/issues/41#issuecomment-646974990 \ No newline at end of file