55 lines
2.1 KiB
Dart
55 lines
2.1 KiB
Dart
import 'dart:io';
|
|
import 'package:ffmpeg_kit_flutter_new/ffmpeg_kit.dart';
|
|
import 'package:ffmpeg_kit_flutter_new/ffmpeg_session.dart';
|
|
import 'package:ffmpeg_kit_flutter_new/return_code.dart';
|
|
import 'package:path_provider/path_provider.dart';
|
|
|
|
class VideoStitchingService {
|
|
/// Stitches multiple video files into a single video file using FFmpeg.
|
|
///
|
|
/// Returns the stitched file, or null if stitching failed or input is empty.
|
|
static Future<File?> stitchVideos(List<File> segments) async {
|
|
if (segments.isEmpty) return null;
|
|
if (segments.length == 1) return segments.first;
|
|
|
|
try {
|
|
// 1. Create a temporary file listing all segments for FFmpeg concat demuxer
|
|
final tempDir = await getTemporaryDirectory();
|
|
final listFile = File('${tempDir.path}/segments_list.txt');
|
|
|
|
final buffer = StringBuffer();
|
|
for (final segment in segments) {
|
|
// FFmpeg requires safe paths (escaping special chars might be needed, but usually basic paths are fine)
|
|
// IMPORTANT: pathways in list file for concat demuxer must be absolute.
|
|
buffer.writeln("file '${segment.path}'");
|
|
}
|
|
await listFile.writeAsString(buffer.toString());
|
|
|
|
// 2. Define output path
|
|
final outputFile = File('${tempDir.path}/stitched_${DateTime.now().millisecondsSinceEpoch}.mp4');
|
|
|
|
// 3. Execute FFmpeg command
|
|
// -f concat: format
|
|
// -safe 0: allow unsafe paths (required for absolute paths)
|
|
// -i listFile: input list
|
|
// -c copy: stream copy (fast, no re-encoding)
|
|
final command = "-f concat -safe 0 -i '${listFile.path}' -c copy '${outputFile.path}'";
|
|
|
|
final session = await FFmpegKit.execute(command);
|
|
final returnCode = await session.getReturnCode();
|
|
|
|
if (ReturnCode.isSuccess(returnCode)) {
|
|
return outputFile;
|
|
} else {
|
|
// Fallback: return the last segment or first one to at least save something?
|
|
// For strict correctness, return null or throw.
|
|
// Let's print logs.
|
|
final logs = await session.getOutput();
|
|
return null;
|
|
}
|
|
} catch (e) {
|
|
return null;
|
|
}
|
|
}
|
|
}
|