flutter_banuba_agora_ar 0.1.0 copy "flutter_banuba_agora_ar: ^0.1.0" to clipboard
flutter_banuba_agora_ar: ^0.1.0 copied to clipboard

Bridge plugin that pipes Banuba AR-processed frames directly into Agora RTC as an external video source. One-liner integration for AR filters in live streams.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:flutter_banuba_agora_ar/flutter_banuba_agora_ar.dart';
import 'package:agora_rtc_engine/agora_rtc_engine.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Banuba + Agora Example',
      theme: ThemeData(
        colorSchemeSeed: Colors.teal,
        useMaterial3: true,
        brightness: Brightness.dark,
      ),
      home: const BanubaAgoraExamplePage(),
    );
  }
}

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

  @override
  State<BanubaAgoraExamplePage> createState() => _BanubaAgoraExamplePageState();
}

class _BanubaAgoraExamplePageState extends State<BanubaAgoraExamplePage> {
  final BanubaARController _banuba = BanubaARController();
  late final RtcEngine _agoraEngine;
  BanubaAgoraBridge? _bridge;

  bool _isInitialized = false;
  bool _isStreaming = false;
  String _status = 'Not initialized';

  // Replace with your keys
  static const String _banubaToken = 'YOUR_BANUBA_CLIENT_TOKEN';
  static const String _agoraAppId = 'YOUR_AGORA_APP_ID';
  static const String _channelName = 'test_channel';

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

  Future<void> _initialize() async {
    setState(() => _status = 'Initializing Banuba...');

    // 1. Initialize Banuba
    await _banuba.initialize(token: _banubaToken);

    // 2. Initialize Agora
    setState(() => _status = 'Initializing Agora...');
    _agoraEngine = createAgoraRtcEngine();
    await _agoraEngine.initialize(RtcEngineContext(appId: _agoraAppId));
    await _agoraEngine.setChannelProfile(
        ChannelProfileType.channelProfileLiveBroadcasting);
    await _agoraEngine.setClientRole(
        role: ClientRoleType.clientRoleBroadcaster);

    // 3. Enable external video source
    await _agoraEngine.getMediaEngine().setExternalVideoSource(
          enabled: true,
          useTexture: false,
          sourceType: ExternalVideoSourceType.videoFrame,
        );

    // 4. Create the bridge
    _bridge = BanubaAgoraBridge(
      banuba: _banuba,
      agoraEngine: _agoraEngine,
    );

    setState(() {
      _isInitialized = true;
      _status = 'Ready — tap Start to begin streaming';
    });
  }

  Future<void> _toggleStream() async {
    if (_isStreaming) {
      // Stop
      _bridge?.stopForwarding();
      await _banuba.stopCapture();
      await _agoraEngine.leaveChannel();
      setState(() {
        _isStreaming = false;
        _status = 'Stopped';
      });
    } else {
      // Start
      setState(() => _status = 'Starting capture...');
      await _banuba.startCapture();
      await _bridge?.startForwarding();
      await _agoraEngine.joinChannel(
        token: '',
        channelId: _channelName,
        uid: 0,
        options: const ChannelMediaOptions(
          publishCustomVideoTrack: true,
          publishCameraTrack: false,
          autoSubscribeVideo: true,
          autoSubscribeAudio: true,
        ),
      );
      setState(() {
        _isStreaming = true;
        _status = 'Streaming on channel: $_channelName';
      });
    }
  }

  @override
  void dispose() {
    _bridge?.dispose();
    _banuba.dispose();
    _agoraEngine.release();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Banuba + Agora')),
      body: Padding(
        padding: const EdgeInsets.all(24),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Card(
              child: Padding(
                padding: const EdgeInsets.all(16),
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('Status',
                        style: Theme.of(context).textTheme.titleMedium),
                    const SizedBox(height: 8),
                    Text(_status),
                    if (_bridge != null) ...[
                      const SizedBox(height: 4),
                      Text('Frames sent: ${_bridge!.frameCount}',
                          style: Theme.of(context).textTheme.bodySmall),
                    ],
                  ],
                ),
              ),
            ),
            const SizedBox(height: 24),
            FilledButton.icon(
              onPressed: _isInitialized ? _toggleStream : null,
              icon: Icon(_isStreaming ? Icons.stop : Icons.live_tv),
              label: Text(_isStreaming ? 'Stop Stream' : 'Start Stream'),
            ),
            const SizedBox(height: 12),
            OutlinedButton.icon(
              onPressed: _isStreaming ? () => _bridge?.switchCamera() : null,
              icon: const Icon(Icons.cameraswitch),
              label: const Text('Switch Camera'),
            ),
            const SizedBox(height: 12),
            OutlinedButton.icon(
              onPressed:
                  _isStreaming ? () => _bridge?.loadEffect('Beauty') : null,
              icon: const Icon(Icons.auto_fix_high),
              label: const Text('Load Effect'),
            ),
            OutlinedButton.icon(
              onPressed: _isStreaming ? () => _bridge?.clearEffect() : null,
              icon: const Icon(Icons.clear),
              label: const Text('Clear Effect'),
            ),
          ],
        ),
      ),
    );
  }
}
0
likes
160
points
14
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Bridge plugin that pipes Banuba AR-processed frames directly into Agora RTC as an external video source. One-liner integration for AR filters in live streams.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

agora_rtc_engine, flutter, flutter_banuba_ar

More

Packages that depend on flutter_banuba_agora_ar