notube-export/lib/services/converter.dart

94 lines
2.7 KiB
Dart

import 'dart:io';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter/foundation.dart';
import 'package:process_run/process_run.dart';
import 'package:notube/models/video.dart';
import 'package:path/path.dart' as p;
import 'package:notube/services/file_logger.dart';
class ConverterService {
late Directory tempDir;
late String ffmpegPath;
ConverterService._();
static Future<ConverterService> init() async {
FileLogger().d('Initializing DLServices');
var dlService = ConverterService._();
await dlService._init();
return dlService;
}
Future<void> _init() async {
tempDir = await getTemporaryDirectory();
if (Platform.isWindows) {
ffmpegPath = 'ffmpeg.exe';
} else if (Platform.isLinux) {
ffmpegPath = 'ffmpeg';
} else if (Platform.isMacOS) {
ffmpegPath = 'ffmpeg';
}
await checkFFmpeg();
}
Future<void> checkFFmpeg() async {
try {
var result = await Process.run(ffmpegPath, ['-version']);
if (result.exitCode == 0) {
print('FFmpeg is installed.');
return;
}
} catch (e) {
print('FFmpeg is not installed.');
}
}
Future<File?> getTmpFile(String filename) async {
final Directory directory = Directory('temp');
final List<FileSystemEntity> files = directory.listSync();
for (FileSystemEntity file in files) {
final String dirFilename = p.basenameWithoutExtension(file.path);
FileLogger().d('dirFilename $dirFilename');
FileLogger().d('filename $filename');
if (dirFilename == '${filename}_tmp') {
return File(file.path);
}
}
return null;
}
Future<Stream> convertFile(Video video) async {
FileLogger().d(
'____Converting ${video.title} to ${video.format.format} format_____');
File tmpFile = File('temp/${video.filename}_tmp.mp4');
if (!tmpFile.existsSync()) {
tmpFile = await getTmpFile(video.filename) ??
File('temp/${video.filename}_tmp.mp4');
}
File doneFile =
File('temp/${video.filename}_done.${video.format.extension}');
if (doneFile.existsSync()) {
FileLogger().d('File already converted');
return Stream.fromIterable(['progress=end']);
}
var command =
'-i "${tmpFile.path}" ${video.format.ffmpegCmd} "temp/${video.filename}_done.${video.format.extension}"';
var shellLinesController = ShellLinesController();
var shell = Shell(
stdout: shellLinesController.sink, stderr: shellLinesController.sink);
await shell.run('''
$ffmpegPath $command
''');
return shellLinesController.stream;
}
}