speech_to_text_pro 0.0.1 copy "speech_to_text_pro: ^0.0.1" to clipboard
speech_to_text_pro: ^0.0.1 copied to clipboard

High-performance, continuous speech-to-text plugin with smart punctuation, auto-restart, and deep session analytics.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'dart:async';
import 'package:speech_to_text_pro/speech_to_text_pro.dart';

void main() {
  runApp(const MaterialApp(
    home: SpeechExampleApp(),
    debugShowCheckedModeBanner: false,
  ));
}

class SpeechExampleApp extends StatefulWidget {
  const SpeechExampleApp({super.key});

  @override
  State<SpeechExampleApp> createState() => _SpeechExampleAppState();
}

class _SpeechExampleAppState extends State<SpeechExampleApp> with SingleTickerProviderStateMixin {
  late TabController _tabController;
  final _plugin = SpeechToTextPro();
  
  // State for both modes
  List<String> _availableLocales = [];
  String _selectedLocale = 'en-US';
  bool _isListening = false;
  double _volume = 0.0;
  String _status = 'Idle';

  // Standard Mode State
  String _standardResult = '';
  double _standardConfidence = 0.0;

  // Pro Mode State
  String _finalizedText = '';
  String _partialText = '';
  double _wpm = 0.0;
  int _totalWords = 0;

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 2, vsync: this);
    _loadLocales();
    
    // Global Listeners
    _plugin.onListeningStateChanged.listen((listening) {
      setState(() {
        _isListening = listening;
        _status = listening ? 'Listening' : 'Idle';
      });
    });

    _plugin.onVolumeChanged.listen((volume) {
      setState(() => _volume = volume);
    });

    _plugin.onError.listen((error) {
      setState(() => _status = 'Error: $error');
    });
  }

  Future<void> _loadLocales() async {
    final available = await _plugin.initialize();
    if (available) {
      final locales = await _plugin.getLocales();
      setState(() {
        _availableLocales = locales;
        if (locales.contains('en-US')) _selectedLocale = 'en-US';
      });
    }
  }

  @override
  void dispose() {
    _tabController.dispose();
    super.dispose();
  }

  // --- Standard Mode UI ---
  Widget _buildStandardTab() {
    return Column(
      children: [
        const Padding(
          padding: EdgeInsets.all(16.0),
          child: Text(
            'Standard Mode is ideal for short commands or single replies. It stops automatically after a pause.',
            style: TextStyle(fontStyle: FontStyle.italic, color: Colors.grey),
          ),
        ),
        Expanded(
          child: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Text(_standardResult.isEmpty ? 'Tap mic and speak' : _standardResult,
                    textAlign: TextAlign.center,
                    style: const TextStyle(fontSize: 20)),
                if (_standardConfidence > 0)
                  Text('Confidence: ${(_standardConfidence * 100).toStringAsFixed(1)}%',
                      style: const TextStyle(color: Colors.deepPurple)),
              ],
            ),
          ),
        ),
        _buildMicButton(() {
          if (_isListening) {
            _plugin.stop();
          } else {
            setState(() => _standardResult = '');
            _plugin.listen(
              localeId: _selectedLocale,
              onResult: (result) {
                setState(() {
                  _standardResult = result.text;
                  _standardConfidence = result.confidence;
                });
              },
            );
          }
        }),
      ],
    );
  }

  // --- Pro Mode UI ---
  Widget _buildProTab() {
    return Column(
      children: [
        const Padding(
          padding: EdgeInsets.all(16.0),
          child: Text(
            'Pro Mode is for infinite dictation. It stitches sentences, handles auto-restarts, and gives live analytics.',
            style: TextStyle(fontStyle: FontStyle.italic, color: Colors.grey),
          ),
        ),
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          children: [
            _buildStatCard('WPM', _wpm.toStringAsFixed(0)),
            _buildStatCard('Words', _totalWords.toString()),
          ],
        ),
        Expanded(
          child: SingleChildScrollView(
            padding: const EdgeInsets.all(16),
            child: RichText(
              text: TextSpan(
                style: const TextStyle(color: Colors.black, fontSize: 18),
                children: [
                  TextSpan(text: _finalizedText),
                  TextSpan(
                    text: _partialText.isNotEmpty ? ' $_partialText' : '',
                    style: TextStyle(color: Colors.deepPurple.withOpacity(0.4)),
                  ),
                ],
              ),
            ),
          ),
        ),
        _buildMicButton(() {
          if (_isListening) {
            _plugin.stop();
          } else {
            setState(() {
              _finalizedText = '';
              _partialText = '';
            });
            // Using Pro Stream
            _plugin.onTranscriptUpdate.listen((transcript) {
              setState(() {
                _finalizedText = transcript.finalizedText;
                _partialText = transcript.partialText;
                _wpm = transcript.analytics.wordsPerMinute;
                _totalWords = transcript.analytics.totalWords;
              });
            });
            _plugin.start(localeId: _selectedLocale);
          }
        }),
      ],
    );
  }

  Widget _buildStatCard(String label, String value) {
    return Card(
      child: Padding(
        padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
        child: Column(
          children: [
            Text(label, style: const TextStyle(fontSize: 12, color: Colors.grey)),
            Text(value, style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
          ],
        ),
      ),
    );
  }

  Widget _buildMicButton(VoidCallback onPressed) {
    return Padding(
      padding: const EdgeInsets.all(32.0),
      child: Column(
        children: [
          LinearProgressIndicator(value: _volume),
          const SizedBox(height: 16),
          FloatingActionButton.large(
            onPressed: onPressed,
            backgroundColor: _isListening ? Colors.red : Colors.deepPurple,
            child: Icon(_isListening ? Icons.stop : Icons.mic, color: Colors.white),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Speech To Text Pro'),
        bottom: TabBar(
          controller: _tabController,
          tabs: const [
            Tab(text: 'Standard Mode', icon: Icon(Icons.flash_on)),
            Tab(text: 'Continuous Pro', icon: Icon(Icons.all_inclusive)),
          ],
        ),
        actions: [
          if (_availableLocales.isNotEmpty)
            DropdownButton<String>(
              value: _selectedLocale,
              underline: const SizedBox(),
              icon: const Icon(Icons.language, color: Colors.black),
              onChanged: (val) => setState(() => _selectedLocale = val!),
              items: _availableLocales.map((l) => DropdownMenuItem(value: l, child: Text(l))).toList(),
            ),
          const SizedBox(width: 16),
        ],
      ),
      body: TabBarView(
        controller: _tabController,
        children: [
          _buildStandardTab(),
          _buildProTab(),
        ],
      ),
    );
  }
}
1
likes
140
points
110
downloads

Documentation

API reference

Publisher

verified publishershirsh.dev

Weekly Downloads

High-performance, continuous speech-to-text plugin with smart punctuation, auto-restart, and deep session analytics.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, flutter_web_plugins, plugin_platform_interface, web

More

Packages that depend on speech_to_text_pro

Packages that implement speech_to_text_pro