Walkthrough

Building a Flutter App with Huddle01

Walkthrough

The following guide explains how you can integrate audio/video into your Flutter mobile-app seamlessly using the Huddle01 Flutter SDK.

Installation

Install huddle01_flutter_client in your flutter app

To power your Flutter dApp with audio communication using Huddle01 install the following:

  flutter pub add huddle01_flutter_client 

Initialization of project

Head over to API Keys Page and connect your wallet to get your project credentials:

  • API Key
  • projectId

Once done, initialize your project by calling the initialize() method and pass projectId in params.

app.dart
String projectId = 'YOUR-PROJECT-ID';
String roomId = 'YOUR-ROOM-ID';
 
// Initialize your huddleClient 
HuddleClient huddleClient = HuddleClient();
 
// Initialize project
huddleClient.initialize(projectId);

Joining the lobby

Room Id can be generated using the : Create Room API Add the following TextButton to your jsx and call the joinLobby() method.

import 'package:flutter/material.dart';
import 'package:huddle01_flutter_client/huddle_client.dart';
 
  class MeetingScreen extends StatefulWidget {
    const MeetingScreen({super.key});
 
    @override
    State<MeetingScreen> createState() => _MeetingScreenState();
  }
 
  class _MeetingScreenState extends State<MeetingScreen> {
    HuddleClient huddleClient = HuddleClient();
    String roomId = 'MY-ROOM-ID';
    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: const Text("My Meeting App"),
        ),
        body: Column(children: [
          TextButton(
            child: const Text('JOIN-LOBBY'),
            onPressed: () {
              if (huddleClient.isJoinLobbyCallable()) {
                huddleClient.joinLobby(roomId);
              } else {
                ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                  content: Text('JOIN-LOBBY -> not callable yet'),
                  backgroundColor: Colors.red,
                  elevation: 4,
                  behavior: SnackBarBehavior.floating,
                  margin: EdgeInsets.all(5),
                  duration: Duration(seconds: 1),
                ));
              }
            },
          ),
        ]),
      );
    }
  }

Joining and leaving the room

Add the joinRoom() and leaveRoom() methods for joining and leaving functionalities.

app.dart
  import 'package:flutter/material.dart';
  import 'package:huddle01_flutter_client/huddle_client.dart';
 
      class MeetingScreen extends StatefulWidget {
        const MeetingScreen({super.key});
 
        @override
        State<MeetingScreen> createState() => _MeetingScreenState();
      }
 
      class _MeetingScreenState extends State<MeetingScreen> {
        HuddleClient huddleClient = HuddleClient();
        String roomId = 'MY-ROOM-ID';
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              title: const Text("My Meeting App"),
            ),
            body: Column(children: [
              TextButton(
                child: const Text('JOIN-LOBBY'),
                onPressed: () {
                  if (huddleClient.isJoinLobbyCallable()) {
                    huddleClient.joinLobby(roomId);
                  } else {
                    ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                      content: Text('JOIN-LOBBY -> not callable yet'),
                      backgroundColor: Colors.red,
                      elevation: 4,
                      behavior: SnackBarBehavior.floating,
                      margin: EdgeInsets.all(5),
                      duration: Duration(seconds: 1),
                    ));
                  }
                },
              ),
              TextButton(
                child: const Text('FETCH-AUDIO'),
                onPressed: () {
                  if (huddleClient.isFetchAudioStreamCallable()) {
                    huddleClient.fetchAudioStream();
                  } else {
                    ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                      content: Text('FETCH-AUDIO -> not callable yet'),
                      backgroundColor: Colors.red,
                      elevation: 4,
                      behavior: SnackBarBehavior.floating,
                      margin: EdgeInsets.all(5),
                      duration: Duration(seconds: 1),
                    ));
                  }
                },
              TextButton(
                child: const Text('JOIN-ROOM'),
                onPressed: () {
                    huddleClient.joinRoom(roomId);
                },
              ),
              TextButton(
                child: const Text('LEAVE-ROOM'),
                onPressed: () {
                    huddleClient.leaveRoom();
                },
              ),
            ]),
          );
        }
      }

Clicking on the JOIN_ROOM button, will make the user join the room and will allow them to send/receive media with other participants.

Sending media across to other participants

Here, we are using a term PRODUCE which means sending your audio/video stream across to the other peer who will CONSUME (or receive) the streams.

app.dart
    import 'package:flutter/material.dart';
    import 'package:huddle01_flutter_client/huddle_client.dart';
 
      class MeetingScreen extends StatefulWidget {
        const MeetingScreen({super.key});
 
        @override
        State<MeetingScreen> createState() => _MeetingScreenState();
      }
 
      class _MeetingScreenState extends State<MeetingScreen> {
        HuddleClient huddleClient = HuddleClient();
        String roomId = 'MY-ROOM-ID';
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            appBar: AppBar(
              title: const Text("My Meeting App"),
            ),
            body: Column(children: [
              TextButton(
                child: const Text('JOIN-LOBBY'),
                onPressed: () {
                  if (huddleClient.isJoinLobbyCallable()) {
                    huddleClient.joinLobby(roomId);
                  } else {
                    ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                      content: Text('JOIN-LOBBY -> not callable yet'),
                      backgroundColor: Colors.red,
                      elevation: 4,
                      behavior: SnackBarBehavior.floating,
                      margin: EdgeInsets.all(5),
                      duration: Duration(seconds: 1),
                    ));
                  }
                },
              ),
              TextButton(
                child: const Text('FETCH-AUDIO'),
                onPressed: () {
                  if (huddleClient.isFetchAudioStreamCallable()) {
                    huddleClient.fetchAudioStream();
                  } else {
                    ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
                      content: Text('FETCH-AUDIO -> not callable yet'),
                      backgroundColor: Colors.red,
                      elevation: 4,
                      behavior: SnackBarBehavior.floating,
                      margin: EdgeInsets.all(5),
                      duration: Duration(seconds: 1),
                    ));
                  }
                },
              TextButton(
                child: const Text('JOIN-ROOM'),
                onPressed: () {
                    huddleClient.joinRoom(roomId);
                },
              ),
              TextButton(
                child: const Text('LEAVE-ROOM'),
                onPressed: () {
                    huddleClient.leaveRoom();
                },
              ),
              TextButton(
                child: const Text('PRODUCE_AUDIO'),
                onPressed: () {
                    huddleClient.produceAudio(stream);
                },
              ),
              TextButton(
                child: const Text('STOP-PRODUCING-AUDIO'),
                onPressed: () {
                    huddleClient.stopProducingAudio();
                },
              ),
            ]),
          );
        }
      }

Receiving the audio and video streams

Here, we are using a term PRODUCE which means sending your audio/video stream across to the other peer who will CONSUME (or receive) the streams.

Getting access to remote video/audio streams

JSX:

// remote-stream
RTCVideoRenderer? remoteRenderer;
initilialize() async {
  remoteRenderer = RTCVideoRenderer();
  await remoteRenderer!.initialize();
  remoteRenderer!.srcObject = huddleClient.getRemoteStream();
}
app.dart
  const Text(
              "Local Stream",
              style: TextStyle(fontSize: 18),
            ),
            Padding(
              padding: const EdgeInsets.fromLTRB(25, 0, 25, 0),
              child: Container(
                  color: Colors.grey,
                  width: 500,
                  height: 250,
                  child: huddleClient.getRenderer() != null
                      ? RTCVideoView(
                          huddleClient.getRenderer()!,
                          objectFit:
                              RTCVideoViewObjectFit.RTCVideoViewObjectFitCover,
                        )
                      : null),
            ),
            TextButton(
              child: const Text(
                'Get Remote Stream',
                style: TextStyle(fontSize: 18),
              ),
              onPressed: () {
                initilialize();
              },
            ),
          
            Padding(
              padding: const EdgeInsets.fromLTRB(25, 0, 25, 0),
              child: Container(
                  color: Colors.grey,
                  width: 500,
                  height: 250,
                  child: huddleClient.getConsumers().isNotEmpty
                      ? RTCVideoView(
                          remoteRenderer!,
                          objectFit:
                              RTCVideoViewObjectFit.RTCVideoViewObjectFitCover,
                        )
                      : null),
            ),
 

You're all set! Happy Hacking! 🎉

For more information, please refer to the SDK Reference.

Audio/Video Infrastructure designed for the developers to empower them ship simple yet powerful Audio/Video Apps.
support
company
Copyright © 2022 Graphene 01, Inc. All Rights Reserved.