I have a Flutter application that allows users to convert a video file into an audio file using the FFmpeg library. The relevant code is as follows:
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:ffmpeg_kit_flutter/ffmpeg_kit.dart';
import 'package:image_picker/image_picker.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
class VideoToAudioConverter extends StatefulWidget {
@override
_VideoToAudioConverterState createState() => _VideoToAudioConverterState();
}
class _VideoToAudioConverterState extends State<VideoToAudioConverter> {
final FFmpegKit _ffmpeg = FFmpegKit();
final ImagePicker _picker = ImagePicker();
XFile? _pickedVideo;
String _outputPath = ""; // Store output path
Future<void> _pickVideo() async {
final XFile? video = await _picker.pickVideo(source: ImageSource.gallery);
if (video != null) {
setState(() {
_pickedVideo = video;
});
}
}
Future<void> _convertVideoToAudio() async {
if (_pickedVideo != null) {
String videoPath = _pickedVideo!.path;
_outputPath = await getOutputFilePath(); // Get platform-specific path
try {
await FFmpegKit.execute(
"-i $videoPath -vn -acodec copy $_outputPath" // FFmpeg command
);
print("Video converted to audio successfully!");
_showSuccessDialog(); // Display success dialog
} catch (e) {
print("Error converting video: $e");
_showErrorDialog(); // Display error dialog
} finally {
setState(() {
_pickedVideo = null; // Clear selected video
});
}
} else {
print("Please pick a video first.");
}
}
Future<String> getOutputFilePath() async {
final Directory? downloadsDir = await getDownloadsDirectory();
final String fileName = path
.basename(_pickedVideo!.path)
.replaceAll('.mp4', '.aac'); // Replace extension
return '${downloadsDir!.path}/$fileName'; // Save in downloads folder
}
void _showSuccessDialog() {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Success!'),
content: Text('Audio converted successfully at: $_outputPath'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('OK'),
),
],
),
);
}
void _showErrorDialog() {
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Error!'),
content: Text('An error occurred during conversion.'),
actions: [
TextButton(
onPressed: () => Navigator.pop(context),
child: Text('OK'),
),
],
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Video to Audio Converter'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (_pickedVideo != null)
Text('Selected video: ${_pickedVideo!.path}'),
ElevatedButton(
onPressed: _pickVideo,
child: Text('Pick Video'),
),
ElevatedButton(
onPressed: _convertVideoToAudio,
child: Text('Convert Video to Audio'),
),
],
),
),
);
}
}
Now, I’d like to take the generated audio file and transcribe it into text, with the ability to retrieve the start and end timestamps for each word in the transcript. This would allow me to synchronize the text with the audio, for example, to display subtitles or captions.
What is the best approach to achieve this functionality in a Flutter application? Are there any libraries or services I can use to perform the audio transcription and get the word-level timestamps? I’m open to using both on-device and cloud-based solutions.
Please provide a solution or point me in the right direction. Any help would be greatly appreciated!