transcribe method
Future<CactusTranscriptionResult>
transcribe({
- String? audioFilePath,
- Stream<
Uint8List> ? audioStream, - dynamic onChunk()?,
- String prompt = whisperPrompt,
- CactusTranscriptionParams? params,
Implementation
Future<CactusTranscriptionResult> transcribe({
String? audioFilePath,
Stream<Uint8List>? audioStream,
Function(CactusTranscriptionResult)? onChunk,
String prompt = whisperPrompt,
CactusTranscriptionParams? params,
}) async {
if (audioFilePath == null && audioStream == null) {
throw ArgumentError('Must provide either audioFilePath or audioStream');
}
if (audioFilePath != null && audioStream != null) {
throw ArgumentError('Cannot provide both audioFilePath and audioStream');
}
// File transcription mode
if (audioFilePath != null) {
return await _handleLock.synchronized(() async {
final transcriptionParams = params ?? defaultTranscriptionParams;
final model = _lastInitializedModel ?? defaultInitParams.model;
final currentHandle = await _getValidatedHandle(model: model);
if (currentHandle != null) {
try {
final result = await CactusContext.transcribe(
currentHandle,
prompt,
audioFilePath: audioFilePath,
params: transcriptionParams,
);
_logTranscriptionTelemetry(result, model, success: result.success, message: result.errorMessage);
return result;
} catch (e) {
debugPrint('Transcription failed: $e');
_logTranscriptionTelemetry(null, model, success: false, message: e.toString());
rethrow;
}
}
throw Exception('Model $_lastInitializedModel is not downloaded. Please download it before transcribing.');
});
}
final List<int> buffer = [];
final completer = Completer<CactusTranscriptionResult>();
final subscription = audioStream!.listen(
(pcmChunk) {
buffer.addAll(pcmChunk);
},
onError: (error) {
debugPrint('Audio stream error: $error');
if (!completer.isCompleted) {
completer.completeError(error);
}
},
onDone: () async {
if (buffer.isEmpty) {
debugPrint('No audio data received');
if (!completer.isCompleted) {
completer.complete(CactusTranscriptionResult(
success: false,
text: '',
errorMessage: 'No audio data received',
));
}
return;
}
final pcmData = PCMUtils.validatePCMBuffer(buffer)
? buffer
: PCMUtils.trimToValidSamples(buffer);
if (pcmData.isEmpty) {
debugPrint('No valid audio data after trimming');
if (!completer.isCompleted) {
completer.complete(CactusTranscriptionResult(
success: false,
text: '',
errorMessage: 'No valid audio data received',
));
}
return;
}
try {
final result = await _transcribePCMInternal(pcmData, prompt, params);
if (!completer.isCompleted) {
completer.complete(result);
}
onChunk?.call(result);
} catch (e) {
debugPrint('Failed to transcribe audio: $e');
if (!completer.isCompleted) {
completer.completeError(e);
}
}
},
);
// Store subscription for potential cancellation
completer.future.whenComplete(() => subscription.cancel());
return completer.future;
}