Version 1.9.1

Bug Fixes
This commit is contained in:
Mattia 2021-04-02 22:56:32 +02:00
parent 7661c1d232
commit 1633db88f7
6 changed files with 37 additions and 19 deletions

View File

@ -1,3 +1,6 @@
## 1.9.1
- Bug fixes (due to youtube changes)
## 1.9.0
- Support nnbd (dart 1.12)
- New api: `getQuerySuggestions`: Returns the suggestions youtube provides while making a video search.

View File

@ -2,6 +2,8 @@ library _youtube_explode.retry;
import 'dart:async';
import 'package:http/http.dart';
import 'exceptions/exceptions.dart';
/// Run the [function] each time an exception is thrown until the retryCount
@ -28,7 +30,8 @@ Future<T> retry<T>(FutureOr<T> Function() function) async {
int getExceptionCost(Exception e) {
if (e is TransientFailureException ||
e is FormatException ||
e is SearchItemSectionException) {
e is SearchItemSectionException ||
e is ClientException) {
return 1;
}
if (e is RequestLimitExceededException) {

View File

@ -12,18 +12,19 @@ class EmbedPage {
static final _playerConfigExp =
RegExp('[\'""]PLAYER_CONFIG[\'""]\\s*:\\s*(\\{.*\\})');
static final _playerConfigExp2 = RegExp(r'yt.setConfig\((\{.*\})');
static final _playerConfigExp3 = RegExp(r'ytcfg.set\((\{.*\})');
final Document root;
late final EmbedPlayerConfig? playerConfig = getPlayerConfig();
///
String? get sourceUrl {
var url = root
.querySelectorAll('*[name="player_ias/base"]')
final url = root
.querySelectorAll('script')
.map((e) => e.attributes['src'])
.where((e) => !e.isNullOrWhiteSpace)
.firstWhere((e) => e!.contains('player_ias') && e.endsWith('.js'),
orElse: () => null);
.whereNotNull()
.firstWhereOrNull((e) => e.contains('player_ias') && e.endsWith('.js'));
// _root.querySelector('*[name="player_ias/base"]').attributes['src'];
if (url == null) {
return null;
@ -34,7 +35,8 @@ class EmbedPage {
///
EmbedPlayerConfig? getPlayerConfig() {
var playerConfigJson =
(_playerConfigJson ?? _playerConfigJson2)?.extractJson();
(_playerConfigJson3 ?? _playerConfigJson2 ?? _playerConfigJson)
?.extractJson();
if (playerConfigJson == null) {
return null;
}
@ -53,6 +55,12 @@ class EmbedPage {
.map((e) => _playerConfigExp2.firstMatch(e)?.group(1))
.firstWhereOrNull((e) => !e.isNullOrWhiteSpace);
String? get _playerConfigJson3 => root
.getElementsByTagName('script')
.map((e) => e.text)
.map((e) => _playerConfigExp3.firstMatch(e)?.group(1))
.firstWhereOrNull((e) => !e.isNullOrWhiteSpace);
///
EmbedPage(this.root);
@ -62,6 +70,7 @@ class EmbedPage {
///
static Future<EmbedPage> get(YoutubeHttpClient httpClient, String videoId) {
var url = 'https://youtube.com/embed/$videoId?hl=en';
// final url = 'http://localhost:8080/embed/$videoId?hl=en';
return retry(() async {
var raw = await httpClient.getString(url);
return EmbedPage.parse(raw);

View File

@ -1,6 +1,7 @@
import 'dart:async';
import 'package:http/http.dart' as http;
import 'package:youtube_explode_dart/src/retry.dart';
import '../exceptions/exceptions.dart';
import '../videos/streams/streams.dart';
@ -12,15 +13,16 @@ class YoutubeHttpClient extends http.BaseClient {
final Map<String, String> _defaultHeaders = const {
'user-agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36',
'accept-language': 'en-US,en;q=1.0',
'x-youtube-client-name': '1',
'x-youtube-client-version': '2.20200609.04.02',
'x-spf-previous': 'https://www.youtube.com/',
'x-spf-referer': 'https://www.youtube.com/',
'x-youtube-device':
'cbr=Chrome&cbrver=81.0.4044.138&ceng=WebKit&cengver=537.36'
'&cos=Windows&cosver=10.0',
'x-youtube-page-label': 'youtube.ytfe.desktop_20200617_1_RC1'
'cookie': 'CONSENT=YES+cb',
'accept':
'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
'accept-language': 'accept-language: en-US,en;q=0.9',
'sec-fetch-dest': 'document',
'sec-fetch-mode': 'navigate',
'sec-fetch-site': 'none',
'sec-fetch-user': '?1',
'sec-gpc': '1',
'upgrade-insecure-requests': '1'
};
/// Initialize an instance of [YoutubeHttpClient]
@ -99,7 +101,7 @@ class YoutubeHttpClient extends http.BaseClient {
try {
final request = http.Request('get', url);
request.headers['range'] = 'bytes=$i-${i + 9898989 - 1}';
final response = await send(request);
final response = await retry(() => send(request));
if (validate) {
_validateResponse(response, response.statusCode);
}

View File

@ -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.9.0
version: 1.9.1
homepage: https://github.com/Hexer10/youtube_explode_dart

View File

@ -14,7 +14,8 @@ void main() {
group('Get streams manifest of any video', () {
for (final val in {
VideoId('9bZkp7q19f0'), // very popular
// VideoId('SkRSXFQerZs'), // age restricted (embed allowed) - This is unplayable
VideoId(
'SkRSXFQerZs'), // age restricted (embed allowed) - This is unplayable
VideoId('hySoCSoH-g8'), // age restricted (embed not allowed)
VideoId('_kmeFXjjGfk'), // embed not allowed (type 1)
VideoId('MeJVWBSsPAY'), // embed not allowed (type 2)