Skip to content

Instantly share code, notes, and snippets.

@willsmanley
Created July 9, 2024 20:30
Show Gist options
  • Save willsmanley/31a94e0f9d014680adb73f3c73630e33 to your computer and use it in GitHub Desktop.
Save willsmanley/31a94e0f9d014680adb73f3c73630e33 to your computer and use it in GitHub Desktop.
Retell Flutter Service
import 'package:livekit_client/livekit_client.dart' as livekit;
import 'package:permission_handler/permission_handler.dart';
import 'dart:async';
class RetellService {
livekit.Room? _room;
bool _connected = false;
final StreamController<String> _eventStreamController =
StreamController<String>.broadcast();
Stream<String> get eventStream => _eventStreamController.stream;
RetellService({required String accessToken}) {
startCall(accessToken);
}
Future<void> startCall(String accessToken) async {
_eventStreamController.add('Starting call');
var status = await Permission.microphone.request();
if (status != PermissionStatus.granted) {
_eventStreamController.add('Microphone permission not granted');
return;
}
try {
_room = livekit.Room();
await _room!.connect(
'wss://retell-ai-4ihahnq7.livekit.cloud',
accessToken,
roomOptions: const livekit.RoomOptions(
adaptiveStream: true,
dynacast: true,
),
);
await _room!.localParticipant?.setMicrophoneEnabled(true);
_connected = true;
_eventStreamController.add('Connected to room: ${_room!.name}');
_handleRoomEvents();
_handleAudioEvents();
_handleDataEvents();
} catch (error) {
_eventStreamController.add('Error starting call: $error');
stopCall();
}
}
void stopCall() {
if (_connected) {
_room?.disconnect();
_connected = false;
_eventStreamController.add('Call ended');
}
}
void _handleRoomEvents() {
_room?.addListener(() {
if (_room?.connectionState == livekit.ConnectionState.disconnected) {
stopCall();
}
});
}
void _handleAudioEvents() {
_room?.addListener(() {
for (var participant in _room!.remoteParticipants.values) {
for (var trackPublication in participant.trackPublications.values) {
if (trackPublication.kind == livekit.TrackType.AUDIO) {
if (trackPublication.subscribed == true) {
if (trackPublication.track is livekit.RemoteAudioTrack) {
livekit.RemoteAudioTrack audioTrack =
trackPublication.track as livekit.RemoteAudioTrack;
audioTrack.addListener(() {});
}
}
}
}
}
});
}
void _handleDataEvents() {
_room?.addListener(() {
// Handle data events if needed
});
}
void dispose() {
stopCall();
_eventStreamController.close();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment