I’m developing a Flutter app for a caption embeding on a video that needs to export a video file after processing it. I’m using the flutter_ffmpeg_kit package. However, I’m having trouble getting the export to work correctly.
Here’s the code I’m using:
initially this is my stack
Expanded(
child: Stack(
children: [
Center(
child: _videoPlayerController.value.isInitialized
? AspectRatio(
aspectRatio:
_videoPlayerController.value.aspectRatio,
child: VideoPlayer(_videoPlayerController),
)
: CircularProgressIndicator(),
),
if (_currentCaption.isNotEmpty)
Positioned.fill(
child: Center(child: _buildCaptionText()),
),
],
),
),
and in export button i executed this function
Future<void> _exportVideo() async {
setState(() {
_isProcessing = true;
});
try {
final directory = await getExternalStorageDirectory();
final rootPath = directory?.parent.parent.parent.parent.path;
final mobixPath = path.join(rootPath!, 'Mobix App');
final appPath = path.join(mobixPath, 'Caption');
final outputPath = path.join(appPath, 'Output');
// Create the directories if they don't exist
await Directory(outputPath).create(recursive: true);
final timestamp = DateTime.now().millisecondsSinceEpoch;
final outputFilePath = path.join(outputPath, 'output-$timestamp.mp4');
// Generate the FFmpeg command
final ffmpegCommand = _generateFFmpegCommand(
widget.videoPath,
outputFilePath,
widget.words,
_fontSize,
_isBold,
_isItalic,
_fontColor,
_backgroundColor,
);
// Execute the FFmpeg command
await FFmpegKit.execute(
ffmpegCommand,
).then(
(session) async {
// Update progress if needed
final returnCode = await session.getReturnCode();
if (ReturnCode.isSuccess(returnCode)) {
setState(() {
_outputFilePath = outputFilePath;
});
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Export successful: $_outputFilePath')),
);
} else {
print('Export failed with rc: $returnCode');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Export failed with rc: $returnCode')),
);
}
setState(() {
_isProcessing = false;
});
},
);
} catch (e) {
print('Export failed: $e');
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Export failed: $e')),
);
setState(() {
_isProcessing = false;
});
}
}
String _generateFFmpegCommand(
String inputPath,
String outputPath,
List<dynamic> words,
double fontSize,
bool isBold,
bool isItalic,
Color fontColor,
Color backgroundColor,
) {
final ffmpegCommand = StringBuffer();
// Add input file
ffmpegCommand.write('-i $inputPath ');
// Add subtitles filter
final subtitleFilter = StringBuffer();
for (var word in words) {
final startTime = word['startTime'].toDouble();
final endTime = word['endTime'].toDouble();
final caption = word['word'];
final fontStyle = isBold && isItalic
? 'bold italic'
: isBold
? 'bold'
: isItalic
? 'italic'
: 'normal';
final fontColorHex = fontColor.value.toRadixString(16).substring(2);
final backgroundColorHex =
backgroundColor.value.toRadixString(16).substring(2);
subtitleFilter.write(
"drawtext=text='$caption':x=(w-tw)/2:y=h-(2*lh):fontcolor=$fontColorHex:fontsize=$fontSize:fontStyle=$fontStyle:box=1:[email protected]:boxborderw=5:enable='between(t,$startTime,$endTime)',");
}
ffmpegCommand.write('-vf "${subtitleFilter.toString()}" ');
// Add output file
ffmpegCommand.write('$outputPath');
return ffmpegCommand.toString();
}
when i run this it returns ReturnCode 1. what am i doing wrong?