notube-export/lib/services/download.dart

102 lines
2.8 KiB
Dart

import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:notube/constants.dart';
import 'package:notube/models/Video.dart';
import 'package:path_provider/path_provider.dart';
import 'package:process_run/shell.dart';
import 'dart:developer';
class DLServices {
late Directory tempDir;
late String assetName;
late String ytDlpPath;
String extractor = '';
String url = '';
bool isPlaylist = false;
String playlistTitle = '';
List<Video> _videos = [];
List<Video> get videos => _videos;
DLServices._();
static Future<DLServices> init() async {
debugPrint('Initializing DLServices');
var dlService = DLServices._();
await dlService._init();
return dlService;
}
Future<void> _init() async {
tempDir = await getTemporaryDirectory();
assetName = 'yt-dlp.exe';
await copyExecutable();
}
Future<void> copyExecutable() async {
File tempFile = File('${tempDir.path}/$assetName');
ByteData data = await rootBundle.load('assets/executable/$assetName');
await tempFile.exists().then((value) {
if (!value) {
debugPrint('Copying $assetName to ${tempFile.path}');
tempFile.writeAsBytes(
data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes));
}
});
ytDlpPath = tempFile.path;
}
Future<Stream> downloadFile(Video video) async {
debugPrint('Downloading $url in $video.format format');
/*
https://youtu.be/playlist?list=PLk1fi9OrZmvGBdh9BdWIhZImGVDUqls1X
https://youtube.com/watch?v=8bJBX-rrrn4
*/
// get the format code from the Format enum
var formatCmd =
Format.values.firstWhere((e) => e.format == video.format).ytCmd;
debugPrint('Format code: $formatCmd');
var cleanTitle = video.title.replaceAll(RegExp(r'[^\w\s]+'), '');
var command =
'${video.url.trim()} --sub-langs "all,-live_chat" --embed-subs --embed-thumbnail --embed-metadata --progress -o "temp/%(playlist)s/${cleanTitle}_${video.format}_tmp.%(ext)s" -f "$formatCmd"';
var shellLinesController = ShellLinesController();
var shell = Shell(stdout: shellLinesController.sink, verbose: false);
debugPrint('Running $ytDlpPath $command');
shell.run('$ytDlpPath $command');
return shellLinesController.stream;
}
Future analyseUrl(String url) async {
debugPrint('Analyse $url');
var command = '${url.trim()} -q --flat-playlist -J';
var shellLinesController = ShellLinesController();
var shell = Shell(stdout: shellLinesController.sink);
await shell.run('''
$ytDlpPath $command
''').then((result) {
debugPrint('Analyse result: $result');
});
return shellLinesController.stream;
}
}