11 KiB
Pro Video Editor H.264 Configuration Guide
Project: Sojorn - Friend's Only Social Platform
Date: January 24, 2026
Status: Configuration Specification Ready
Overview
This document provides the technical specifications and configuration requirements for implementing the pro_video_editor package with H.264 codec support via FFmpeg in the Sojorn application.
Required ProVideoEditorConfig Settings
Complete Configuration
ProVideoEditorConfigs _buildConfigs() {
return ProVideoEditorConfigs(
// ==================== THEME CONFIGURATION ====================
theme: _buildEditorTheme(), // Custom dark theme with AppTheme.brightNavy
videoEditorTheme: VideoEditorTheme(
background: Color(0xFF0B0B0B), // Matte black
appBarBackgroundColor: Color(0xFF0B0B0B), // Matte black
appBarForegroundColor: Colors.white,
bottomBarBackgroundColor: Color(0xFF0B0B0B), // Matte black
),
// ==================== CROP & ROTATION ====================
cropRotateEditorConfigs: CropRotateEditorConfigs(
enabled: true,
cropRotateEditorTheme: CropRotateEditorTheme(
appBarBackgroundColor: Color(0xFF0B0B0B),
appBarForegroundColor: Colors.white,
background: Color(0xFF0B0B0B),
cropCornerColor: Color(0xFF1974D1), // AppTheme.brightNavy
helperLineColor: Color(0xFF1974D1), // AppTheme.brightNavy
),
),
// ==================== FILTER EDITOR ====================
filterEditorConfigs: FilterEditorConfigs(
enabled: true,
filterEditorTheme: FilterEditorTheme(
appBarBackgroundColor: Color(0xFF0B0B0B),
appBarForegroundColor: Colors.white,
background: Color(0xFF0B0B0B),
previewTextColor: Colors.white70,
previewSelectedTextColor: Color(0xFF1974D1), // AppTheme.brightNavy
),
),
// ==================== DISABLE DISTRACTING FEATURES ====================
// Per 'Friend's Only' philosophy - focus on quality over clutter
stickerEditorConfigs: const StickerEditorConfigs(
enabled: false,
),
textEditorConfigs: const TextEditorConfigs(
enabled: false,
),
// ==================== EXPORT CONFIGURATION (CRITICAL) ====================
exportConfigs: ExportConfigs(
// REQUIRED: Generate export in separate thread for non-blocking UI
generateInsideSeparateThread: true,
// REQUIRED: Export to .mp4 format
exportFormat: ExportFormat.mp4,
// REQUIRED: H.264 codec for compatibility
videoCodec: VideoCodec.h264,
// High quality output
videoQuality: VideoQuality.high,
// Audio settings
audioCodec: AudioCodec.aac,
audioQuality: AudioQuality.high,
// Resolution settings (optional - maintains original by default)
// maxWidth: 1920,
// maxHeight: 1080,
// Frame rate (optional - maintains original by default)
// targetFrameRate: 30,
),
// ==================== CUSTOM WIDGETS ====================
customWidgets: VideoEditorCustomWidgets(
appBar: (editor, rebuildStream) => ReactiveCustomAppbar(
stream: rebuildStream,
builder: (context) {
return AppBar(
backgroundColor: Color(0xFF0B0B0B),
foregroundColor: Colors.white,
leading: IconButton(
tooltip: 'Cancel',
icon: const Icon(Icons.close),
onPressed: editor.closeEditor,
),
actions: [
TextButton(
onPressed: editor.doneEditing,
style: TextButton.styleFrom(
foregroundColor: Color(0xFF1974D1), // AppTheme.brightNavy
),
child: const Text('Save'),
),
const SizedBox(width: 6),
],
);
},
),
),
);
}
FFmpeg Requirements
1. FFmpeg Kit Flutter Integration
NOTE: The ffmpeg_kit_flutter package has been temporarily removed due to build issues with Maven repository availability. When you're ready to implement the full video editor, you'll need to add it back:
dependencies:
ffmpeg_kit_flutter: ^6.0.3
Or use an alternative video processing solution. The current video editor is a placeholder that passes through videos without editing.
2. Platform-Specific Configuration
Android (android/app/build.gradle)
android {
// ...
defaultConfig {
// ...
ndk {
// Specify ABIs to include (reduces APK size)
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86_64'
}
}
packagingOptions {
// Prevent duplicate FFmpeg libraries
pickFirst 'lib/armeabi-v7a/libc++_shared.so'
pickFirst 'lib/arm64-v8a/libc++_shared.so'
pickFirst 'lib/x86_64/libc++_shared.so'
}
}
iOS (ios/Podfile)
# Minimum iOS version for FFmpeg support
platform :ios, '12.1'
target 'Runner' do
use_frameworks!
use_modular_headers!
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
# FFmpeg pod is automatically handled by ffmpeg_kit_flutter
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
# Ensure proper architecture support
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.1'
config.build_settings['ONLY_ACTIVE_ARCH'] = 'NO'
end
end
end
3. Permissions
Android (android/app/src/main/AndroidManifest.xml)
<manifest>
<!-- Required for video processing -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<!-- ... -->
</manifest>
iOS (ios/Runner/Info.plist)
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access to your photo library to edit videos.</string>
<key>NSCameraUsageDescription</key>
<string>We need access to your camera to record videos.</string>
<key>NSMicrophoneUsageDescription</key>
<string>We need access to your microphone to record audio.</string>
H.264 Codec Specifications
Video Settings
- Codec: H.264 (AVC)
- Profile: High Profile (for best quality/compression ratio)
- Level: 4.1 (supports 1080p @ 30fps)
- Container: MP4
- Bitrate: Variable (VBR) - automatically adjusted based on quality setting
Audio Settings
- Codec: AAC-LC
- Sample Rate: 44.1 kHz or 48 kHz
- Bitrate: 128 kbps (high quality)
- Channels: Stereo (2 channels)
Quality Presets
| Quality | Resolution | Target Bitrate | Use Case |
|---|---|---|---|
| High | Up to 1080p | 8-12 Mbps | Default - Best quality |
| Medium | Up to 720p | 4-6 Mbps | Balanced |
| Low | Up to 480p | 1-2 Mbps | Quick uploads |
Implementation Steps
Step 1: Initialize Video Editor
// In your video_editor_screen.dart
ProVideoEditor.file(
File(videoPath),
configs: _buildConfigs(),
callbacks: ProVideoEditorCallbacks(
onVideoEditingComplete: (String outputPath) async {
// outputPath contains the exported .mp4 file with H.264 codec
// Move to temp directory
final tempDir = await getTemporaryDirectory();
final timestamp = DateTime.now().millisecondsSinceEpoch;
final tempFile = File('${tempDir.path}/sojorn_video_$timestamp.mp4');
await File(outputPath).copy(tempFile.path);
// Return result
Navigator.pop(context, SojornMediaResult.video(
filePath: tempFile.path,
name: 'sojorn_video_$timestamp.mp4',
));
},
onVideoExporting: () {
// Show progress indicator
print('Video exporting...');
},
onVideoExported: () {
// Export completed
print('Video export completed');
},
onExportProgress: (double progress) {
// Update progress indicator (0.0 to 1.0)
print('Export progress: ${(progress * 100).toInt()}%');
},
),
);
Step 2: Handle Export Progress
class _VideoEditorState extends State<VideoEditorScreen> {
double _exportProgress = 0.0;
bool _isExporting = false;
Widget _buildExportOverlay() {
if (!_isExporting) return SizedBox.shrink();
return Container(
color: Colors.black54,
child: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
CircularProgressIndicator(
value: _exportProgress,
color: AppTheme.brightNavy,
),
SizedBox(height: 16),
Text(
'Exporting... ${(_exportProgress * 100).toInt()}%',
style: TextStyle(color: Colors.white),
),
],
),
),
);
}
}
Step 3: Test H.264 Export
// Verify exported video codec
Future<void> verifyVideoCodec(String videoPath) async {
final result = await FFmpegKit.execute(
'-i $videoPath -hide_banner'
);
final output = await result.getOutput();
print('Video info: $output');
// Should show: Video: h264, Audio: aac
}
Troubleshooting
Issue: FFmpeg Not Found
Solution: Run flutter clean and flutter pub get, then rebuild the app.
Issue: Export Fails on iOS
Solution: Ensure iOS deployment target is >= 12.1 in ios/Podfile.
Issue: Large APK Size
Solution: Use abiFilters in android/app/build.gradle to include only necessary architectures.
Issue: Slow Export
Solution: Verify generateInsideSeparateThread: true is set. Consider lowering quality preset.
Issue: Audio Missing in Export
Solution: Ensure audioCodec: AudioCodec.aac is specified in exportConfigs.
Performance Considerations
- Threading: Always use
generateInsideSeparateThread: trueto prevent UI freezing - Memory: Monitor memory usage during export, especially on low-end devices
- Storage: Exported videos are saved to temp directory and cleaned up automatically by OS
- Battery: Video encoding is CPU-intensive; warn users on low battery
Testing Checklist
- Export video with H.264 codec
- Verify .mp4 container format
- Test crop and rotation
- Test filter application
- Verify stickers/text are disabled
- Test on Android device
- Test on iOS device
- Verify temp storage implementation
- Test upload integration
- Verify exported video plays in standard players
Related Files
- Video Editor Implementation:
sojorn_app/lib/screens/compose/video_editor_screen.dart - Quip Video Editor:
sojorn_app/lib/screens/quips/create/quip_editor_screen.dart - Upload Service:
sojorn_app/lib/services/image_upload_service.dart - Result Class:
sojorn_app/lib/models/sojorn_media_result.dart
References
- pro_video_editor Documentation
- ffmpeg_kit_flutter Documentation
- H.264 Specification
- MP4 Container Format
Last Updated: January 24, 2026
Next Review: After FFmpeg configuration is completed