Version 1.7.6

Fix tests
Fix `isEmptyOrNull` exception.
This commit is contained in:
Mattia 2021-01-28 10:32:09 +01:00
parent b89f786348
commit 5d76402694
7 changed files with 43 additions and 19 deletions

View File

@ -1,6 +1,9 @@
name: Dart CI name: Dart CI
on: [push] on:
push:
schedule:
- cron: '0 0 * * * '
jobs: jobs:
build: build:

View File

@ -2,6 +2,7 @@ import 'dart:convert';
import 'package:html/dom.dart'; import 'package:html/dom.dart';
import 'package:html/parser.dart' as parser; import 'package:html/parser.dart' as parser;
import 'package:youtube_explode_dart/src/reverse_engineering/responses/player_config_base.dart';
import '../../extensions/helpers_extension.dart'; import '../../extensions/helpers_extension.dart';
import '../../retry.dart'; import '../../retry.dart';
@ -14,7 +15,7 @@ class EmbedPage {
static final _playerConfigExp2 = RegExp(r'yt.setConfig\((\{.*\})'); static final _playerConfigExp2 = RegExp(r'yt.setConfig\((\{.*\})');
final Document _root; final Document _root;
_PlayerConfig _playerConfig; EmbedPlayerConfig _playerConfig;
/// ///
String get sourceUrl { String get sourceUrl {
@ -32,7 +33,7 @@ class EmbedPage {
} }
/// ///
_PlayerConfig get playerConfig { EmbedPlayerConfig get playerConfig {
if (_playerConfig != null) { if (_playerConfig != null) {
return _playerConfig; return _playerConfig;
} }
@ -41,7 +42,7 @@ class EmbedPage {
return null; return null;
} }
return _playerConfig = return _playerConfig =
_PlayerConfig(json.decode(playerConfigJson.extractJson())); EmbedPlayerConfig(json.decode(playerConfigJson.extractJson()));
} }
String get _playerConfigJson => _root String get _playerConfigJson => _root
@ -72,11 +73,14 @@ class EmbedPage {
} }
} }
class _PlayerConfig { /// Used internally
// Json parsed map. class EmbedPlayerConfig implements PlayerConfigBase<Map<String, dynamic>> {
final Map<String, dynamic> _root; @override
final Map<String, dynamic> root;
_PlayerConfig(this._root); ///
EmbedPlayerConfig(this.root);
String get sourceUrl => 'https://youtube.com${_root['assets']['js']}'; @override
String get sourceUrl => 'https://youtube.com${root['assets']['js']}';
} }

View File

@ -0,0 +1,12 @@
/// Base class for PlayerConfig.
abstract class PlayerConfigBase<T> {
/// Root node.
final T root;
///
PlayerConfigBase(this.root);
/// Player source url.
String get sourceUrl;
}

View File

@ -1,5 +1,6 @@
import 'package:html/dom.dart'; import 'package:html/dom.dart';
import 'package:html/parser.dart' as parser; import 'package:html/parser.dart' as parser;
import 'package:youtube_explode_dart/src/reverse_engineering/responses/player_config_base.dart';
import '../../../youtube_explode_dart.dart'; import '../../../youtube_explode_dart.dart';
import '../../extensions/helpers_extension.dart'; import '../../extensions/helpers_extension.dart';
@ -34,7 +35,7 @@ class WatchPage {
_InitialData _initialData; _InitialData _initialData;
String _xsfrToken; String _xsfrToken;
_PlayerConfig _playerConfig; WatchPlayerConfig _playerConfig;
/// ///
String get sourceUrl { String get sourceUrl {
@ -125,7 +126,7 @@ class WatchPage {
static final _playerConfigExp = RegExp(r'ytplayer\.config\s*=\s*(\{.*\})'); static final _playerConfigExp = RegExp(r'ytplayer\.config\s*=\s*(\{.*\})');
/// ///
_PlayerConfig get playerConfig => _playerConfig ??= _PlayerConfig( WatchPlayerConfig get playerConfig => _playerConfig ??= WatchPlayerConfig(
PlayerConfigJson.fromRawJson(_playerConfigExp PlayerConfigJson.fromRawJson(_playerConfigExp
.firstMatch(_root.getElementsByTagName('html').first.text) .firstMatch(_root.getElementsByTagName('html').first.text)
?.group(1) ?.group(1)
@ -172,14 +173,18 @@ class WatchPage {
} }
} }
class _PlayerConfig { /// Used internally
// Json parsed map class WatchPlayerConfig implements PlayerConfigBase<PlayerConfigJson> {
@override
final PlayerConfigJson root; final PlayerConfigJson root;
_PlayerConfig(this.root); ///
WatchPlayerConfig(this.root);
@override
String get sourceUrl => 'https://youtube.com${root.assets.js}'; String get sourceUrl => 'https://youtube.com${root.assets.js}';
///
PlayerResponse get playerResponse => PlayerResponse get playerResponse =>
PlayerResponse.parse(root.args.playerResponse); PlayerResponse.parse(root.args.playerResponse);
} }

View File

@ -79,7 +79,7 @@ class StreamsClient {
Future<StreamContext> _getStreamContextFromWatchPage(VideoId videoId) async { Future<StreamContext> _getStreamContextFromWatchPage(VideoId videoId) async {
var watchPage = await WatchPage.get(_httpClient, videoId.toString()); var watchPage = await WatchPage.get(_httpClient, videoId.toString());
dynamic /* _PlayerConfig */ playerConfig; WatchPlayerConfig playerConfig;
try { try {
playerConfig = watchPage.playerConfig; playerConfig = watchPage.playerConfig;
} on FormatException { } on FormatException {
@ -92,13 +92,13 @@ class StreamsClient {
} }
var previewVideoId = playerResponse.previewVideoId; var previewVideoId = playerResponse.previewVideoId;
if (!((previewVideoId as String)?.isNullOrWhiteSpace ?? true)) { if (!(previewVideoId.isNullOrWhiteSpace ?? true)) {
throw VideoRequiresPurchaseException.preview( throw VideoRequiresPurchaseException.preview(
videoId, VideoId(previewVideoId)); videoId, VideoId(previewVideoId));
} }
var playerSourceUrl = var playerSourceUrl =
watchPage.sourceUrl ?? playerConfig?.sourceUrl as String; watchPage.sourceUrl ?? playerConfig?.sourceUrl;
var playerSource = !playerSourceUrl.isNullOrWhiteSpace var playerSource = !playerSourceUrl.isNullOrWhiteSpace
? await PlayerSource.get(_httpClient, playerSourceUrl) ? await PlayerSource.get(_httpClient, playerSourceUrl)
: null; : null;

View File

@ -1,6 +1,6 @@
name: youtube_explode_dart 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. description: A port in dart of the youtube explode library. Supports several API functions without the need of Youtube API Key.
version: 1.7.5 version: 1.7.6
homepage: https://github.com/Hexer10/youtube_explode_dart homepage: https://github.com/Hexer10/youtube_explode_dart
environment: environment:

View File

@ -55,7 +55,7 @@ void main() {
VideoId('5VGm0dczmHc'), // rating not allowed VideoId('5VGm0dczmHc'), // rating not allowed
VideoId('ZGdLIwrGHG8'), // unlisted VideoId('ZGdLIwrGHG8'), // unlisted
VideoId('rsAAeyAr-9Y'), // recording of a live stream VideoId('rsAAeyAr-9Y'), // recording of a live stream
VideoId('AI7ULzgf8RU'), // has DASH manifest VideoId('AI7ULzgf8RU'), // has DASH manifest TODO: Test timesout
VideoId('-xNN-bJQ4vI'), // 360° video VideoId('-xNN-bJQ4vI'), // 360° video
}) { }) {
test('VideoId - ${val.value}', () async { test('VideoId - ${val.value}', () async {