From 2e1fd2c7be5c5e0d2ed36592a8cddc4877f4aded Mon Sep 17 00:00:00 2001 From: Hexah Date: Fri, 26 Jun 2020 15:30:16 +0200 Subject: [PATCH] Implement error handler for `getStream` function. --- lib/src/channels/channel_client.dart | 1 + .../youtube_http_client.dart | 44 +++++++++++++++---- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/lib/src/channels/channel_client.dart b/lib/src/channels/channel_client.dart index f0f4b50..0ccab6c 100644 --- a/lib/src/channels/channel_client.dart +++ b/lib/src/channels/channel_client.dart @@ -19,6 +19,7 @@ class ChannelClient { /// [id] must be either a [ChannelId] or a string /// which is parsed to a [ChannelId] Future get(dynamic id) async { + id = ChannelId.fromString(id); var channelPage = await ChannelPage.get(_httpClient, id.value); return Channel(id, channelPage.channelTitle, channelPage.channelLogoUrl); diff --git a/lib/src/reverse_engineering/youtube_http_client.dart b/lib/src/reverse_engineering/youtube_http_client.dart index a5fef03..e6be526 100644 --- a/lib/src/reverse_engineering/youtube_http_client.dart +++ b/lib/src/reverse_engineering/youtube_http_client.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:http/http.dart' as http; import '../exceptions/exceptions.dart'; @@ -77,7 +79,10 @@ class YoutubeHttpClient extends http.BaseClient { // TODO: Check why isRateLimited is not working. Stream> getStream(StreamInfo streamInfo, - {Map headers, bool validate = true}) async* { + {Map headers, + bool validate = true, + int start = 0, + int errorCount = 0}) async* { var url = streamInfo.url; // if (!streamInfo.isRateLimited()) { // var request = http.Request('get', url); @@ -88,14 +93,35 @@ class YoutubeHttpClient extends http.BaseClient { // } // yield* response.stream; // } else { - for (var i = 0; i < streamInfo.size.totalBytes; i += 9898989) { - 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); + + var bytesCount = start; + for (var i = start; i < streamInfo.size.totalBytes; i += 9898989) { + try { + final request = http.Request('get', url); + request.headers['range'] = 'bytes=$i-${i + 9898989 - 1}'; + final response = await send(request); + if (validate) { + _validateResponse(response, response.statusCode); + } + final stream = StreamController>(); + response.stream.listen((data) { + bytesCount += data.length; + stream.add(data); + }, onError: (_) => null, onDone: stream.close, cancelOnError: false); + errorCount = 0; + yield* stream.stream; + } on Exception { + if (errorCount == 5) { + rethrow; + } + await Future.delayed(const Duration(milliseconds: 500)); + yield* getStream(streamInfo, + headers: headers, + validate: validate, + start: bytesCount, + errorCount: errorCount + 1); + break; } - yield* response.stream; } // } } @@ -121,6 +147,8 @@ class YoutubeHttpClient extends http.BaseClient { request.headers[key] = _defaultHeaders[key]; } }); + //print('Request: $request'); + //print('Stack:\n${StackTrace.current}'); return _httpClient.send(request); } }