Skip to main content

Platform Setup

WebRTC needs camera/microphone permissions and a few build settings declared per platform. This is a one-time step. Do it before your first getUserMedia() call — without it, capture throws (NotAllowedError / NotReadableError) or the build fails outright.

All of this is flutter_webrtc's platform requirement, not metered_realtime's — but you need it to run a call, so it's collected here. The flutter_webrtc README is the upstream source of truth.

Android

Permissions + features

android/app/src/main/AndroidManifest.xml, inside <manifest> (before <application>):

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.microphone" android:required="false"/>

Mark the camera/mic features required="false" so audio-only devices (and the Play Store filter) don't reject your app.

minSdk

flutter_webrtc needs Android API 23+. In android/app/build.gradle.kts:

defaultConfig {
minSdk = maxOf(flutter.minSdkVersion, 23) // don't downgrade a higher template default
}

(Groovy build.gradle: minSdkVersion maxOf(flutter.minSdkVersion, 23).)

Screen share (optional)

If you add screen capture, also declare:

<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION"/>

Runtime prompts

Android shows the camera/mic prompt automatically the first time getUserMedia() runs. For a smoother flow, request ahead of time with a plugin like permission_handler and show your own rationale UI.

iOS

ios/Runner/Info.plist — add usage strings (the prompt text shown to the user). Calls fail silently without these (iOS rejects the capture with no dialog):

<key>NSCameraUsageDescription</key>
<string>This app uses the camera for video calls.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app uses the microphone for calls.</string>

To keep call audio alive when the app is backgrounded (the user switches apps mid-call), add:

<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>

Then:

cd ios && pod install

iOS deployment target should be 12.0+ (the flutter_webrtc floor).

iOS Simulator has no camera

The iOS Simulator can't capture video — getUserMedia({'video': true}) returns no frames there. Test video on a real device; use the Simulator only for audio / signalling. (Android emulators do provide a virtual camera.)

Web

No config file needed — the browser prompts for camera/mic on getUserMedia(), and the page must be served over HTTPS (or localhost) for navigator.mediaDevices to exist.

flutter run -d chrome

Two Chrome windows on localhost are the fastest way to smoke-test a call without any device setup.

macOS

macos/Runner/Info.plist:

<key>NSCameraUsageDescription</key>
<string>This app uses the camera for video calls.</string>
<key>NSMicrophoneUsageDescription</key>
<string>This app uses the microphone for calls.</string>

And add the camera + audio-input entitlements to both macos/Runner/DebugProfile.entitlements and Release.entitlements:

<key>com.apple.security.device.camera</key>
<true/>
<key>com.apple.security.device.audio-input</key>
<true/>

Windows / Linux

No manifest changes — the OS grants device access to desktop apps directly. You still need flutter_webrtc's native build dependencies; see its README for the per-OS toolchain notes.

Verifying

The quickest end-to-end check: run the example app on two targets and confirm each shows the other's camera. If a tile stays black:

  • Permissions — check the manifest / Info.plist entries above; look for a denied-permission error in the logs.
  • No Send on a pk_ key — presence fires but no media negotiates. See the pk_ gotcha.
  • TURN / network — see Troubleshooting.

See also