orbit_voice 0.4.0 copy "orbit_voice: ^0.4.0" to clipboard
orbit_voice: ^0.4.0 copied to clipboard

Orbit Voice Flutter SDK — LiveKit connect, party-room audio (media stream, mic release, headset routing, VAD gate), no ovk_ in the client.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:orbit_voice/orbit_voice.dart';

/// Demo only — mint [OrbitVoiceSession] on your Edge; never ship ovk_ here.
void main() {
  WidgetsFlutterBinding.ensureInitialized();
  runApp(const OrbitVoiceExampleApp());
}

class OrbitVoiceExampleApp extends StatelessWidget {
  const OrbitVoiceExampleApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Orbit Voice Example',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF0B3D2E)),
        useMaterial3: true,
      ),
      home: const _Home(),
    );
  }
}

class _Home extends StatefulWidget {
  const _Home();

  @override
  State<_Home> createState() => _HomeState();
}

class _HomeState extends State<_Home> {
  final _engine = OrbitEngine.instance;
  final _url = TextEditingController();
  final _token = TextEditingController();
  final _room = TextEditingController(text: 'demo-room');
  final _songUri = TextEditingController(
    text: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3',
  );
  String _state = 'disconnected';
  String _log = '';
  bool _songPublishing = false;

  @override
  void initState() {
    super.initState();
    _engine.on(_onEvent);
    // Bootstrap ADM/session once at startup (before first connect).
    OrbitAudioBootstrap.ensureInitialized();
  }

  @override
  void dispose() {
    _engine.off(_onEvent);
    _url.dispose();
    _token.dispose();
    _room.dispose();
    _songUri.dispose();
    super.dispose();
  }

  void _onEvent(String event, Map<String, dynamic> payload) {
    setState(() {
      if (event == OrbitVoiceEvents.connectionStateChanged) {
        _state = payload['state']?.toString() ?? _state;
      }
      if (event == OrbitVoiceEvents.songPublishChanged) {
        _songPublishing = payload['publishing'] == true;
      }
      _log = '$event $payload\n$_log';
    });
  }

  Future<void> _connect() async {
    final session = OrbitVoiceSession(
      token: _token.text.trim(),
      livekitUrl: _url.text.trim(),
      livekitRoom: _room.text.trim(),
      orbitRoomId: _room.text.trim(),
      canPublish: true,
      role: 'host',
      onSeat: true,
    );
    try {
      await _engine.loginRoom(session);
    } catch (e) {
      setState(() => _log = 'error: $e\n$_log');
    }
  }

  Future<void> _toggleSong() async {
    try {
      if (_engine.isSongPublishing) {
        await _engine.stopSong();
      } else {
        final raw = _songUri.text.trim();
        if (raw.isEmpty) return;
        final ok = await _engine.publishSong(Uri.parse(raw));
        setState(() {
          _songPublishing = _engine.isSongPublishing;
          _log = 'publishSong → $ok\n$_log';
        });
      }
    } catch (e) {
      setState(() => _log = 'song error: $e\n$_log');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Orbit Voice')),
      body: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          Text('State: $_state', style: Theme.of(context).textTheme.titleMedium),
          Text(
            'Song: ${_songPublishing ? "publishing" : "off"}',
            style: Theme.of(context).textTheme.bodyMedium,
          ),
          const SizedBox(height: 12),
          TextField(
            controller: _url,
            decoration: const InputDecoration(
              labelText: 'LiveKit URL (wss://…)',
              border: OutlineInputBorder(),
            ),
          ),
          const SizedBox(height: 8),
          TextField(
            controller: _token,
            decoration: const InputDecoration(
              labelText: 'JWT from your Edge',
              border: OutlineInputBorder(),
            ),
          ),
          const SizedBox(height: 8),
          TextField(
            controller: _room,
            decoration: const InputDecoration(
              labelText: 'Room id',
              border: OutlineInputBorder(),
            ),
          ),
          const SizedBox(height: 8),
          TextField(
            controller: _songUri,
            decoration: const InputDecoration(
              labelText: 'Song file path or https URL',
              border: OutlineInputBorder(),
            ),
          ),
          const SizedBox(height: 16),
          Wrap(
            spacing: 8,
            runSpacing: 8,
            children: [
              FilledButton(onPressed: _connect, child: const Text('Connect')),
              OutlinedButton(
                onPressed: () => _engine.logoutRoom(),
                child: const Text('Leave'),
              ),
              OutlinedButton(
                onPressed: () => _engine.setMicEnabled(true),
                child: const Text('Mic on'),
              ),
              OutlinedButton(
                onPressed: () => _engine.setMicEnabled(false),
                child: const Text('Mic off'),
              ),
              OutlinedButton(
                onPressed: () => _engine.enableSpeaker(true),
                child: const Text('Speaker'),
              ),
              FilledButton.tonal(
                onPressed: _toggleSong,
                child: Text(_songPublishing ? 'Stop song' : 'Publish song'),
              ),
            ],
          ),
          const SizedBox(height: 16),
          Text(_log, style: const TextStyle(fontFamily: 'monospace', fontSize: 12)),
        ],
      ),
    );
  }
}
0
likes
150
points
346
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Orbit Voice Flutter SDK — LiveKit connect, party-room audio (media stream, mic release, headset routing, VAD gate), no ovk_ in the client.

Homepage
Repository (GitHub)

License

MIT (license)

Dependencies

flutter, flutter_webrtc, livekit_client

More

Packages that depend on orbit_voice

Packages that implement orbit_voice