enx_voice_bot 1.0.6+7 copy "enx_voice_bot: ^1.0.6+7" to clipboard
enx_voice_bot: ^1.0.6+7 copied to clipboard

Flutter SDK for real-time Gen-AI Voice Bots via REST call control and Pipecat WebSocket, powered by EnableX Dialogs.

example/lib/main.dart

import 'package:enx_voice_bot/enx_voice_client.dart';
import 'package:enx_voice_bot/enx_voice_listener.dart';
import 'package:enx_voice_bot/enx_voice_state.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: VoiceCallDemo(),
    );
  }
}

class VoiceCallDemo extends StatefulWidget {
  @override
  _VoiceCallDemoState createState() => _VoiceCallDemoState();
}

class _VoiceCallDemoState extends State<VoiceCallDemo> implements EnxVoiceListener {
  late EnxVoiceClient _voiceClient;
  var isConnected=false;
  var isPress=false;
  var isMutePress=false;
  var virtualNumber="911100123457";//virtual number

  /// Optional override for POST /call base URL. If empty, [EnxSdkConfig] default is used.
  static const String callApiBaseUrl = '';

  var _showDtmfKeypad = false;

  @override
  void initState() {
    super.initState();

    _voiceClient = EnxVoiceClient()
        .init(virtualNumber)
        .setEnxVoiceListener(this)
        .setOnDtmfKeypadChanged((show) {
          if (!mounted) return;
          setState(() => _showDtmfKeypad = show);
        });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Voice Call'),centerTitle: true,),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: [
            Text(isConnected ? 'Status: Connected' :isPress?'Status : Connecting': 'Status: Connect'),
            const SizedBox(height: 20),
            ElevatedButton(

              onPressed: () async{
                if(isConnected||isPress){
                  _voiceClient.disconnect();
                }else{
                  _voiceClient.connect(
                    callApiBaseUrl:
                        callApiBaseUrl.isNotEmpty ? callApiBaseUrl : null,
                  );
                  setState(() {
                    isPress=true;
                  });

                }

              },
              child: Text(isConnected ? 'Disconnect' :isPress?'Disconnect': 'Connect'),
            ),
            ElevatedButton(
              onPressed: () async{
                if(isConnected && isMutePress){
                  _voiceClient.muteAudio(false);
                }else{
                  _voiceClient.muteAudio(true);

                }
                },
              child: Text(isMutePress?'UnMute':'Mute'),
            ),

            const SizedBox(height: 20),
            if (_showDtmfKeypad && isConnected) ...[
              const Text('DTMF', style: TextStyle(fontWeight: FontWeight.w600)),
              const SizedBox(height: 8),
              Wrap(
                spacing: 6,
                runSpacing: 6,
                alignment: WrapAlignment.center,
                children: [
                  for (final d in ['1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '0', '#'])
                    SizedBox(
                      width: 56,
                      child: OutlinedButton(
                        onPressed: () async {
                          final ok = await _voiceClient.sendDtmf(d);
                          debugPrint('DTMF $d sent: $ok');
                        },
                        child: Text(d),
                      ),
                    ),
                ],
              ),
            ],

          ],
        ),
      ),
    );
  }

  @override
  void onCallConnected() {
    print('Call connected!');
    setState(() {
      isConnected=true;
      isPress=false;
      isMutePress=false;
    });


  }

  @override
  void onCallDisconnect() {
    print('Call disconnected');
    setState(() {
      isConnected=false;
      isPress=false;
      isMutePress=false;
      _showDtmfKeypad = false;
    });


  }

  @override
  void onError(String message) {
    print('Error: $message');
  }

  @override
  void onMuteStateChanged(bool isMuted) {
    print('Mute: $isMuted');
    setState(() {
      isMutePress= isMuted;

    });
  }

  @override
  void onStatus(EnxVoiceState state) {
    print('Status:  ${state.name}');
  }

  @override
  void onUserSpeaking(bool isUserSpeaking) {
    print('User speaking: $isUserSpeaking');
  }

  @override
  void onBotSpeaking(bool isBotSpeaking) {
    print('Bot speaking: $isBotSpeaking');
  }

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

}
3
likes
140
points
81
downloads

Documentation

Documentation
API reference

Publisher

verified publisherenablex.io

Weekly Downloads

Flutter SDK for real-time Gen-AI Voice Bots via REST call control and Pipecat WebSocket, powered by EnableX Dialogs.

Homepage

Topics

#voice-bot #flutter-voice-bot #conversational-ai #webrtc #enablex

License

MIT (license)

Dependencies

async, fixnum, flutter, flutter_sound, http, logger, path_provider, permission_handler, protobuf, record, uuid, web_socket_channel

More

Packages that depend on enx_voice_bot

Packages that implement enx_voice_bot