transcribe method

  1. @override
Future<TranscriptionResult> transcribe(
  1. Uint8List audio,
  2. VoiceConfig config
)
override

Implementation

@override
Future<TranscriptionResult> transcribe(
  Uint8List audio,
  VoiceConfig config,
) async {
  // On macOS, use the system speech recognition (limited).
  // In practice, this delegates to a more capable provider.
  if (Platform.isMacOS) {
    // Save audio to temp file and use macOS Dictation API via osascript.
    final tempFile = File(
      '${Directory.systemTemp.path}/neomage_audio_${DateTime.now().millisecondsSinceEpoch}.wav',
    );
    await tempFile.writeAsBytes(audio);

    try {
      // Fallback: use a local whisper binary if available.
      final whisperResult = await Process.run('which', ['whisper']);
      if (whisperResult.exitCode == 0) {
        final result = await Process.run('whisper', [
          tempFile.path,
          '--model',
          'base',
          '--language',
          config.language.code.split('-').first,
          '--output_format',
          'json',
          '--output_dir',
          Directory.systemTemp.path,
        ]);

        if (result.exitCode == 0) {
          final jsonFile = File(tempFile.path.replaceAll('.wav', '.json'));
          if (await jsonFile.exists()) {
            final json =
                jsonDecode(await jsonFile.readAsString())
                    as Map<String, dynamic>;
            await jsonFile.delete();
            return TranscriptionResult(
              text: json['text'] as String? ?? '',
              duration: Duration.zero,
            );
          }
        }
      }

      return const TranscriptionResult(text: '', duration: Duration.zero);
    } finally {
      if (await tempFile.exists()) await tempFile.delete();
    }
  }

  throw UnsupportedError(
    'System STT not supported on ${Platform.operatingSystem}',
  );
}