Implement caching of player source

This commit is contained in:
Hexah 2020-06-27 21:32:03 +02:00
parent 2e1fd2c7be
commit bd8f071a72
4 changed files with 40 additions and 31 deletions

View File

@ -3,28 +3,24 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:dart_console/dart_console.dart'; import 'package:console/console.dart';
import 'package:youtube_explode_dart/youtube_explode_dart.dart'; import 'package:youtube_explode_dart/youtube_explode_dart.dart';
// Initialize the YoutubeExplode instance. // Initialize the YoutubeExplode instance.
final yt = YoutubeExplode(); final yt = YoutubeExplode();
final console = Console();
Future<void> main() async { Future<void> main() async {
console.writeLine('Type the video id or url: '); stdout.writeln('Type the video id or url: ');
var url = stdin.readLineSync().trim(); var url = stdin.readLineSync().trim();
// Save the video to the download directory. // Save the video to the download directory.
Directory('downloads').createSync(); Directory('downloads').createSync();
console.hideCursor();
// Download the video. // Download the video.
await download(url); await download(url);
yt.close(); yt.close();
console.showCursor();
exit(0); exit(0);
} }
@ -42,7 +38,6 @@ Future<void> download(String id) async {
// Compose the file name removing the unallowed characters in windows. // Compose the file name removing the unallowed characters in windows.
var fileName = '${video.title}.${audio.container.name.toString()}' var fileName = '${video.title}.${audio.container.name.toString()}'
.replaceAll('Container.', '')
.replaceAll(r'\', '') .replaceAll(r'\', '')
.replaceAll('/', '') .replaceAll('/', '')
.replaceAll('*', '') .replaceAll('*', '')
@ -53,9 +48,12 @@ Future<void> download(String id) async {
.replaceAll('|', ''); .replaceAll('|', '');
var file = File('downloads/$fileName'); var file = File('downloads/$fileName');
// Create the StreamedRequest to track the download status. // Delete the file if exists.
if (file.existsSync()) {
file.deleteSync();
}
// Open the file in appendMode. // Open the file in writeAppend.
var output = file.openWrite(mode: FileMode.writeOnlyAppend); var output = file.openWrite(mode: FileMode.writeOnlyAppend);
// Track the file download status. // Track the file download status.
@ -64,24 +62,23 @@ Future<void> download(String id) async {
var oldProgress = -1; var oldProgress = -1;
// Create the message and set the cursor position. // Create the message and set the cursor position.
var msg = 'Downloading `${video.title}`(.${audio.container.name}): \n'; var msg = 'Downloading ${video.title}.${audio.container.name}';
print(msg); stdout.writeln(msg);
// var row = console.cursorPosition.row;
// var col = msg.length - 2;
// console.cursorPosition = Coordinate(row, 0);
// console.write(msg);
// Listen for data received. // Listen for data received.
var progressBar = ProgressBar();
await for (var data in audioStream) { await for (var data in audioStream) {
// Keep track of the current downloaded data.
count += data.length; count += data.length;
var progress = ((count / len) * 100).round();
if (progress != oldProgress) { // Calculate the current progress.
// console.cursorPosition = Coordinate(row, col); var progress = ((count / len) * 100).ceil();
print('$progress%');
oldProgress = progress; // Update the progressbar.
} progressBar.update(progress);
// Write to file.
output.add(data); output.add(data);
} }
console.writeLine();
await output.close(); await output.close();
} }

View File

@ -1,3 +1,5 @@
import 'dart:async';
import '../../exceptions/exceptions.dart'; import '../../exceptions/exceptions.dart';
import '../../retry.dart'; import '../../retry.dart';
import '../cipher/cipher_operations.dart'; import '../cipher/cipher_operations.dart';
@ -105,12 +107,22 @@ class PlayerSource {
// Same as default constructor // Same as default constructor
PlayerSource.parse(this._root); PlayerSource.parse(this._root);
static Future<PlayerSource> get(YoutubeHttpClient httpClient, String url) { static Future<PlayerSource> get(
return retry(() async { YoutubeHttpClient httpClient, String url) async {
var raw = await httpClient.getString(url); if (_cache[url] == null) {
return PlayerSource.parse(raw); Timer(const Duration(minutes: 10), () {
}); _cache[url] = null;
});
return _cache[url] = await retry(() async {
var raw = await httpClient.getString(url);
return PlayerSource.parse(raw);
});
}
return _cache[url];
} }
static final Map<String, PlayerSource> _cache = {};
} }
extension on String { extension on String {

View File

@ -147,8 +147,8 @@ class YoutubeHttpClient extends http.BaseClient {
request.headers[key] = _defaultHeaders[key]; request.headers[key] = _defaultHeaders[key];
} }
}); });
//print('Request: $request'); // print('Request: $request');
//print('Stack:\n${StackTrace.current}'); // print('Stack:\n${StackTrace.current}');
return _httpClient.send(request); return _httpClient.send(request);
} }
} }

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.3.2 version: 1.3.3
homepage: https://github.com/Hexer10/youtube_explode_dart homepage: https://github.com/Hexer10/youtube_explode_dart
environment: environment:
@ -17,5 +17,5 @@ dependencies:
dev_dependencies: dev_dependencies:
effective_dart: ^1.2.1 effective_dart: ^1.2.1
dart_console: ^0.5.0 console: ^3.1.0
test: ^1.12.0 test: ^1.12.0