Skip to content
Flutter WebRTC plugin for Mobile/Desktop
Java Objective-C Dart Ruby
Branch: master
Clone or download
cloudwebrtc Merge pull request #114 from looffee/master
[Android] Fix 'createIceServer' method Invalid value error
Latest commit dd6edbe Aug 11, 2019


pub package Join the chat at

Flutter WebRTC plugin for iOS/Android


Add flutter_webrtc as a dependency in your pubspec.yaml file.


Add the following entry to your Info.plist file, located in <project root>/ios/Runner/Info.plist:

<string>$(PRODUCT_NAME) Camera Usage!</string>
<string>$(PRODUCT_NAME) Microphone Usage!</string>

This entry allows your app to access camera and microphone.


Ensure the following permission is present in your Android Manifest file, located in `/android/app/src/main/AndroidManifest.xml:

<uses-feature android:name="" />
<uses-feature android:name="" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

The Flutter project template adds it, so it may already be there.

Also you will need to set your build settings to Java 8, because official WebRTC jar now uses static methods in EglBase interface. Just add this to your app level build.gradle:

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8


We intend to implement support the following features:


import 'package:flutter/material.dart';
import 'package:flutter_webrtc/webrtc.dart';
import 'dart:core';

 * getUserMedia sample
class GetUserMediaSample extends StatefulWidget {
  static String tag = 'get_usermedia_sample';

  _GetUserMediaSampleState createState() => new _GetUserMediaSampleState();

class _GetUserMediaSampleState extends State<GetUserMediaSample> {
  MediaStream _localStream;
  final _localRenderer = new RTCVideoRenderer();
  bool _inCalling = false;

  initState() {

  deactivate() {
    if (_inCalling) {

  initRenderers() async {
    await _localRenderer.initialize();

  // Platform messages are asynchronous, so we initialize in an async method.
  _makeCall() async {
    final Map<String, dynamic> mediaConstraints = {
      "audio": true,
      "video": {
        "mandatory": {
          "minWidth":'640', // Provide your own width, height and frame rate here
          "minHeight": '480',
          "minFrameRate": '30',
        "facingMode": "user",
        "optional": [],

    try {
      var stream = await navigator.getUserMedia(mediaConstraints);
      _localStream = stream;
      _localRenderer.srcObject = _localStream;
    } catch (e) {
    if (!mounted) return;

    setState(() {
      _inCalling = true;

  _hangUp() async {
    try {
      await _localStream.dispose();
      _localRenderer.srcObject = null;
    } catch (e) {
    setState(() {
      _inCalling = false;

  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('GetUserMedia API Test'),
      body: new OrientationBuilder(
        builder: (context, orientation) {
          return new Center(
            child: new Container(
              margin: new EdgeInsets.fromLTRB(0.0, 0.0, 0.0, 0.0),
              width: MediaQuery.of(context).size.width,
              height: MediaQuery.of(context).size.height,
              child: RTCVideoView(_localRenderer),
              decoration: new BoxDecoration(color: Colors.black54),
      floatingActionButton: new FloatingActionButton(
        onPressed: _inCalling ? _hangUp : _makeCall,
        tooltip: _inCalling ? 'Hangup' : 'Call',
        child: new Icon(_inCalling ? Icons.call_end :,

For more examples, please refer to flutter-webrtc-demo.

You can’t perform that action at this time.