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'; } } 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') { FileLogger().d('Found tmp file ${file.path}'); return File(file.path); } } return null; } Future convertFile(Video video) async { FileLogger().d( '____Converting ${video.title} to ${video.format.format} format_____'); File tmpFile = File('${tempDir.path}/${video.filename}_tmp.mp4'); var dlFileExist = await tmpFile.exists(); FileLogger().d('dlFileExist: $dlFileExist'); if (!dlFileExist) { FileLogger() .d('File not found, testing destination ${video.destination}'); if (video.destination != '') { tmpFile = File('${tempDir.path}/${video.destination}'); } if (!tmpFile.existsSync()) { FileLogger().d('File not found, testing temp directory'); tmpFile = await getTmpFile(video.filename) ?? File('${tempDir.path}/${video.filename}_tmp.mp4'); } } FileLogger().d('tmpFile: ${tmpFile.path}'); File doneFile = File( '${tempDir.path}/${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} '${tempDir.path}/${video.filename}_done.${video.format.extension}'"; var shellLinesController = ShellLinesController(); var shell = Shell( stdout: shellLinesController.sink, stderr: shellLinesController.sink); FileLogger().d('Running $ffmpegPath $command'); await shell.run("$ffmpegPath $command"); return shellLinesController.stream; } }