Add DownloadExtension
This commit is contained in:
parent
617db63d9b
commit
545808fd97
|
@ -42,4 +42,8 @@
|
||||||
## 0.0.10
|
## 0.0.10
|
||||||
|
|
||||||
- Bug fix: Don't throw when captions are not present.
|
- Bug fix: Don't throw when captions are not present.
|
||||||
- New extension: CaptionListExtension adding `getByTime` function.
|
- New extension: CaptionListExtension adding `getByTime` function.
|
||||||
|
|
||||||
|
## 0.0.11
|
||||||
|
|
||||||
|
- New extension: DownloadExtension adding `downloadStream` function.
|
13
README.md
13
README.md
|
@ -16,11 +16,11 @@ This doesn't require an API key and has no usage quotas.
|
||||||
- Provides static methods to validate IDs and to parse IDs from URLs
|
- Provides static methods to validate IDs and to parse IDs from URLs
|
||||||
- No need for an API key and no usage quotas
|
- No need for an API key and no usage quotas
|
||||||
- All model extend `Equatable` to easily perform equality checks
|
- All model extend `Equatable` to easily perform equality checks
|
||||||
|
- Download Stream
|
||||||
|
|
||||||
## Features not implemented
|
## Features not implemented
|
||||||
|
|
||||||
- Adaptive streams
|
- Adaptive streams
|
||||||
- Download streams functions.
|
|
||||||
|
|
||||||
## Differences from YoutubeExplode
|
## Differences from YoutubeExplode
|
||||||
|
|
||||||
|
@ -103,13 +103,20 @@ You need to close `YoutubeExplode`'s http client when done otherwise this could
|
||||||
yt.close();
|
yt.close();
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# Examples:
|
||||||
|
|
||||||
|
Available on [GitHub][Examples]
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Check the [api doc][API] for additional information.
|
Check the [api doc][API] for additional information.
|
||||||
More features are provided thru extensions.
|
More features are provided through extensions.
|
||||||
|
|
||||||
[YoutubeExplode]: https://github.com/Tyrrrz/YoutubeExplode/
|
[YoutubeExplode]: https://github.com/Tyrrrz/YoutubeExplode/
|
||||||
|
|
||||||
[Video]: https://pub.dev/documentation/youtube_explode_dart/latest/youtube_explode/Video-class.html
|
[Video]: https://pub.dev/documentation/youtube_explode_dart/latest/youtube_explode/Video-class.html
|
||||||
[MediaStreamsInfoSet]: https://pub.dev/documentation/youtube_explode_dart/latest/youtube_explode/MediaStreamInfoSet-class.html
|
[MediaStreamsInfoSet]: https://pub.dev/documentation/youtube_explode_dart/latest/youtube_explode/MediaStreamInfoSet-class.html
|
||||||
[VidExample]: https://github.com/Hexer10/youtube_explode_dart/blob/master/example/video_download.dart
|
[VidExample]: https://github.com/Hexer10/youtube_explode_dart/blob/master/example/video_download.dart
|
||||||
[API]: https://pub.dev/documentation/youtube_explode_dart/latest/youtube_explode/youtube_explode-library.html
|
[API]: https://pub.dev/documentation/youtube_explode_dart/latest/youtube_explode/youtube_explode-library.html
|
||||||
|
[Examples][https://github.com/Hexer10/youtube_explode_dart/tree/master/example]
|
|
@ -3,7 +3,6 @@ import 'dart:io';
|
||||||
|
|
||||||
import 'package:dart_console/dart_console.dart';
|
import 'package:dart_console/dart_console.dart';
|
||||||
import 'package:youtube_explode_dart/youtube_explode_dart.dart';
|
import 'package:youtube_explode_dart/youtube_explode_dart.dart';
|
||||||
import 'package:http/http.dart' as http;
|
|
||||||
|
|
||||||
// Initialize the YoutubeExplode instance.
|
// Initialize the YoutubeExplode instance.
|
||||||
final yt = YoutubeExplode();
|
final yt = YoutubeExplode();
|
||||||
|
@ -12,7 +11,7 @@ final console = Console();
|
||||||
|
|
||||||
Future<void> main() async {
|
Future<void> main() async {
|
||||||
console.writeLine('Type the video id or url: ');
|
console.writeLine('Type the video id or url: ');
|
||||||
|
|
||||||
var url = stdin.readLineSync().trim();
|
var url = stdin.readLineSync().trim();
|
||||||
|
|
||||||
// Get the video url.
|
// Get the video url.
|
||||||
|
@ -56,14 +55,12 @@ Future<void> download(String id) async {
|
||||||
var file = File('downloads/$fileName');
|
var file = File('downloads/$fileName');
|
||||||
|
|
||||||
// Create the StreamedRequest to track the download status.
|
// Create the StreamedRequest to track the download status.
|
||||||
var req = http.Request('get', audio.url);
|
|
||||||
var resp = await req.send();
|
|
||||||
|
|
||||||
// Open the file in appendMode.
|
// Open the file in appendMode.
|
||||||
var output = file.openWrite(mode: FileMode.writeOnlyAppend);
|
var output = file.openWrite(mode: FileMode.writeOnlyAppend);
|
||||||
|
|
||||||
// Track the file download status.
|
// Track the file download status.
|
||||||
var len = resp.contentLength;
|
var len = audio.size;
|
||||||
var count = 0;
|
var count = 0;
|
||||||
var oldProgress = -1;
|
var oldProgress = -1;
|
||||||
|
|
||||||
|
@ -75,7 +72,7 @@ Future<void> download(String id) async {
|
||||||
console.write(msg);
|
console.write(msg);
|
||||||
|
|
||||||
// Listen for data received.
|
// Listen for data received.
|
||||||
return resp.stream.listen((data) {
|
await for (var data in audio.downloadStream()) {
|
||||||
count += data.length;
|
count += data.length;
|
||||||
var progress = ((count / len) * 100).round();
|
var progress = ((count / len) * 100).round();
|
||||||
if (progress != oldProgress) {
|
if (progress != oldProgress) {
|
||||||
|
@ -84,7 +81,7 @@ Future<void> download(String id) async {
|
||||||
oldProgress = progress;
|
oldProgress = progress;
|
||||||
}
|
}
|
||||||
output.add(data);
|
output.add(data);
|
||||||
}, onDone: () async {
|
}
|
||||||
await output.close();
|
console.writeLine();
|
||||||
}).asFuture();
|
await output.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
|
import '../models/models.dart';
|
||||||
|
|
||||||
|
/// Download extension for [MediaStreamInfo]
|
||||||
|
extension DownloadExtension on MediaStreamInfo {
|
||||||
|
static final _rateBypassExp = RegExp('ratebypass[=/]yes');
|
||||||
|
|
||||||
|
/// Returns the stream of this media stream object.
|
||||||
|
/// The download is split in multiple requests using the `range` parameter.
|
||||||
|
///
|
||||||
|
Stream<List<int>> downloadStream() async* {
|
||||||
|
var maxSize = _rateBypassExp.hasMatch(url.toString()) ? 9898989 : size + 1;
|
||||||
|
var total = 0;
|
||||||
|
|
||||||
|
for (var i = 1; total < size; i++) {
|
||||||
|
var req = http.Request('get', url);
|
||||||
|
req.headers[HttpHeaders.rangeHeader] = 'bytes=$total-${total + maxSize}';
|
||||||
|
var resp = await req.send();
|
||||||
|
yield* resp.stream;
|
||||||
|
total += maxSize + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
export 'caption_extension.dart';
|
export 'caption_extension.dart';
|
||||||
export 'channel_extension.dart';
|
export 'channel_extension.dart';
|
||||||
|
export 'download_extension.dart';
|
||||||
export 'helpers_extension.dart';
|
export 'helpers_extension.dart';
|
||||||
export 'playlist_extension.dart';
|
export 'playlist_extension.dart';
|
||||||
export 'search_extension.dart';
|
export 'search_extension.dart';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
name: youtube_explode_dart
|
name: youtube_explode_dart
|
||||||
description: A port in dart of the youtube explode library. Support serveral API functions.
|
description: A port in dart of the youtube explode library. Support serveral API functions.
|
||||||
version: 0.0.10
|
version: 0.0.11
|
||||||
homepage: https://github.com/Hexer10/youtube_explode_dart
|
homepage: https://github.com/Hexer10/youtube_explode_dart
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
Loading…
Reference in New Issue