utd_media_client 2.7.0
utd_media_client: ^2.7.0 copied to clipboard
UTD Media Client — real-time audio and video for Flutter (iOS, Android, Web).
UTD Media Client — Flutter SDK #
Use this SDK to add realtime video, audio and data features to your Flutter app. By connecting to the UTD Media Engine, you can quickly build applications such as live streaming, voice rooms, video calls, and multi-modal experiences with just a few lines of code.
This package is published to pub.dev as utd_media_client.
Docs #
More docs and guides are available at https://utdsoftware.com.
Supported platforms #
The UTD Media Client for Flutter is designed to work across all platforms supported by Flutter:
- Android
- iOS
- Web
- macOS
- Windows
- Linux
Installation #
Include this package in your pubspec.yaml:
dependencies:
utd_media_client: ^2.7.0
iOS #
Camera and microphone usage need to be declared in your Info.plist file.
<dict>
...
<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) uses your camera</string>
<key>NSMicrophoneUsageDescription</key>
<string>$(PRODUCT_NAME) uses your microphone</string>
Your application can still run the voice call when it is switched to the background if the background mode is enabled. Select the app target in Xcode, click the Capabilities tab, enable Background Modes, and check Audio, AirPlay, and Picture in Picture.
Your Info.plist should have the following entries.
<dict>
...
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
</array>
For iOS, the minimum supported deployment target is 12.1. You will need to add the following to your Podfile.
platform :ios, '12.1'
You may need to delete Podfile.lock and re-run pod install after updating the deployment target.
Android #
We require a set of permissions that need to be declared in your AppManifest.xml.
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.your.package">
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<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" />
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
...
</manifest>
Audio Modes
By default, we use the communication audio mode on Android which works best for two-way voice communication.
If your app is media-playback oriented and does not need the device's microphone, you can use the media audio mode which provides better audio quality.
Desktop support #
In order to enable Flutter desktop development, please follow the official Flutter desktop setup instructions.
Usage #
Connecting to a room, publish video & audio #
final roomOptions = RoomOptions(
adaptiveStream: true,
dynacast: true,
// ... your room options
);
final room = Room();
// you can use `prepareConnection` to speed up connection.
await room.prepareConnection(url, token);
await room.connect(url, token, roomOptions: roomOptions);
try {
// video will fail when running in the ios simulator
await room.localParticipant.setCameraEnabled(true);
} catch (error) {
print('Could not publish video, error: $error');
}
await room.localParticipant.setMicrophoneEnabled(true);
Screen sharing #
Screen sharing is supported across all platforms. You can enable it with:
room.localParticipant.setScreenShareEnabled(true);
Rendering video #
Each track can be rendered separately with the provided VideoTrackRenderer widget.
VideoTrack? track;
@override
Widget build(BuildContext context) {
if (track != null) {
return VideoTrackRenderer(track);
} else {
return Container(
color: Colors.grey,
);
}
}
Audio handling #
Audio tracks are played automatically as long as you are subscribed to them.
Handling changes #
The client makes it simple to build declarative UI that reacts to state changes. It notifies changes in two ways:
ChangeNotifier— generic notification of changes. Useful when building reactive UI that only cares about changes that may impact rendering.EventsListener<Event>— listener pattern to listen to specific events.
class _RoomState extends State<RoomWidget> {
late final EventsListener<RoomEvent> _listener = widget.room.createListener();
@override
void initState() {
super.initState();
widget.room.addListener(_onChange);
_listener
..on<RoomDisconnectedEvent>((_) {
// handle disconnect
})
..on<ParticipantConnectedEvent>((e) {
print("participant joined: ${e.participant.identity}");
});
}
@override
void dispose() {
_listener.dispose();
widget.room.removeListener(_onChange);
super.dispose();
}
void _onChange() {
setState(() {
// your updates here
});
}
}
Mute, unmute local tracks #
On LocalTrackPublications, you can control whether the track is muted by setting its muted property. Changing the mute status emits a TrackMutedEvent or TrackUnmutedEvent.
// mute track
trackPub.muted = true;
// unmute track
trackPub.muted = false;
End-to-end encryption #
The SDK supports end-to-end encryption for audio/video data sent over the network. On native platforms E2EE works without extra setup; on Flutter web you need to compile an e2ee.worker.dart.js file.
License #
Apache License 2.0