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 init() async { FileLogger().d('Initializing DLServices'); var dlService = ConverterService._(); await dlService._init(); return dlService; } Future _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 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 getTmpFile(String filename) async { final Directory directory = Directory('temp'); final List 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 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; } }