243 lines
7.6 KiB
Markdown
243 lines
7.6 KiB
Markdown
# liblinphone_flutter
|
|
|
|
A Flutter plugin that provides integration with the Linphone library for VoIP calls (audio and video) on Android and iOS platforms.
|
|
|
|
## Third-Party Licenses
|
|
|
|
This project depends on the Linphone SDK, developed by Belledonne Communications, which is dual-licensed under the GNU Affero General Public License v3 (AGPLv3) and a proprietary commercial license.
|
|
|
|
This wrapper library itself is licensed under the MIT License. However, it is designed to work with the Linphone SDK, and therefore **does not remove or replace the licensing requirements of Linphone**.
|
|
|
|
### Important
|
|
|
|
Any application using this plugin and linking against the Linphone SDK is subject to the terms of the AGPLv3, unless a commercial license for Linphone is obtained.
|
|
|
|
In practice, this means that applications using this plugin must comply with AGPLv3 requirements, which may include releasing the application's source code under a compatible license.
|
|
|
|
For proprietary or closed-source applications, you must obtain a commercial license for the Linphone SDK from Belledonne Communications.
|
|
|
|
## Description
|
|
|
|
This plugin wraps the native Linphone SDK (liblinphone) and exposes a Dart API for making SIP-based voice and video calls in Flutter applications.
|
|
|
|
## Features
|
|
|
|
- SIP account registration
|
|
- Audio and video calls
|
|
- Video streaming with local preview and remote view
|
|
- Call management (answer, hangup, toggle video/microphone)
|
|
- Registration and call state event streams
|
|
|
|
## Platform Support
|
|
|
|
| Platform | Status |
|
|
| -------- | --------- |
|
|
| Android | Supported |
|
|
| iOS | Supported |
|
|
|
|
## Requirements
|
|
|
|
- Flutter SDK >= 3.3.0
|
|
- Dart SDK >= 3.9.0-333.2.beta
|
|
- Linphone SDK (native dependency)
|
|
|
|
## Installation
|
|
|
|
Add this to your `pubspec.yaml`:
|
|
|
|
```yaml
|
|
dependencies:
|
|
liblinphone_flutter: ^0.0.3
|
|
```
|
|
|
|
Or if you want to go with git:
|
|
|
|
```yaml
|
|
dependencies:
|
|
liblinphone_flutter:
|
|
git:
|
|
url: https://git.nuark.xyz/nuark/liblinphone_flutter.git
|
|
ref: commit-hash
|
|
```
|
|
|
|
Then run:
|
|
|
|
```bash
|
|
flutter pub get
|
|
```
|
|
|
|
### Platform-Specific Setup
|
|
|
|
#### Android
|
|
|
|
Ensure you have the necessary permissions in your `AndroidManifest.xml`:
|
|
|
|
```xml
|
|
<uses-permission android:name="android.permission.INTERNET" />
|
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
|
<uses-permission android:name="android.permission.CAMERA" />
|
|
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
|
```
|
|
|
|
#### iOS
|
|
|
|
The plugin requires access to the camera and microphone. Add the following to your `Info.plist`:
|
|
|
|
```xml
|
|
<key>NSCameraUsageDescription</key>
|
|
<string>Camera access is required for video calls</string>
|
|
<key>NSMicrophoneUsageDescription</key>
|
|
<string>Microphone access is required for audio and video calls</string>
|
|
```
|
|
|
|
## Usage
|
|
|
|
### Basic Example
|
|
|
|
```dart
|
|
import 'package:liblinphone_flutter/liblinphone_flutter.dart';
|
|
|
|
final liblinphone = LiblinphoneFlutter();
|
|
|
|
// Initialize
|
|
await liblinphone.checkPermissions();
|
|
await liblinphone.initialize();
|
|
|
|
// Register to SIP server
|
|
await liblinphone.register(
|
|
'username',
|
|
'password',
|
|
'sip.server.com',
|
|
5060,
|
|
);
|
|
|
|
// Listen to registration events
|
|
liblinphone.registrationEvents.listen((state) {
|
|
print('Registration state: $state');
|
|
});
|
|
|
|
// Listen to call events
|
|
liblinphone.callEvents.listen((state) {
|
|
print('Call state: $state');
|
|
});
|
|
|
|
// Make a video call
|
|
await liblinphone.makeCall('sip:recipient@sip.server.com', true);
|
|
|
|
// Answer incoming call
|
|
await liblinphone.answerCall();
|
|
|
|
// Toggle video during call
|
|
await liblinphone.toggleVideo();
|
|
|
|
// Toggle microphone
|
|
await liblinphone.toggleMicrophone();
|
|
|
|
// Hangup
|
|
await liblinphone.hangupCall();
|
|
|
|
// Send DTMF tone during a call
|
|
await liblinphone.sendDtmf('5'); // Send tone '5'
|
|
await liblinphone.sendDtmf('#'); // Send tone '#'
|
|
await liblinphone.sendDtmf('*'); // Send tone '*'
|
|
|
|
// Unregister and cleanup
|
|
await liblinphone.unregister();
|
|
await liblinphone.stop();
|
|
```
|
|
|
|
### Video Views
|
|
|
|
For video calls, use the provided widgets to display local and remote video streams:
|
|
|
|
```dart
|
|
import 'package:liblinphone_flutter/widgets/local_view.dart';
|
|
import 'package:liblinphone_flutter/widgets/remote_view.dart';
|
|
|
|
// In your widget tree
|
|
Column(
|
|
children: [
|
|
// Remote video (full screen or large area)
|
|
Expanded(
|
|
child: RemoteView(),
|
|
),
|
|
// Local video preview (picture-in-picture)
|
|
SizedBox(
|
|
height: 150,
|
|
width: 100,
|
|
child: LocalView(),
|
|
),
|
|
],
|
|
)
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### Main Class: `LiblinphoneFlutter`
|
|
|
|
#### Methods
|
|
|
|
| Method | Description |
|
|
| ----------------------------------------------------------------- | -------------------------------------------------- |
|
|
| `Future<bool> checkPermissions()` | Checks and requests camera/microphone permissions |
|
|
| `Future<bool> initialize()` | Initializes the Linphone core |
|
|
| `Future<bool> register(username, password, serverIp, serverPort)` | Registers to a SIP server |
|
|
| `Future<bool> unregister()` | Unregisters from the SIP server |
|
|
| `Future<bool> makeCall(callTo, isVideoEnabled)` | Makes an outgoing call |
|
|
| `Future<bool> answerCall()` | Answers an incoming call |
|
|
| `Future<bool> hangupCall()` | Hangs up the current call |
|
|
| `Future<bool> inCall()` | Returns true if there is an active call |
|
|
| `Future<CallType> callType()` | Returns the type of the current call (audio/video) |
|
|
| `Future<bool> toggleVideo()` | Toggles video enabled state during a call |
|
|
| `Future<bool> toggleMicrophone()` | Toggles microphone muted state |
|
|
| `Future<bool> sendDtmf(tone)` | Sends a DTMF tone during a call (0-9, *, #, A-D) |
|
|
| `Future<bool> stop()` | Stops the Linphone core |
|
|
| `Future<void> syncCurrentState()` | Forces synchronization of current state |
|
|
|
|
#### Event Streams
|
|
|
|
| Stream | Type | Description |
|
|
| -------------------- | --------------------------- | -------------------------------- |
|
|
| `registrationEvents` | `Stream<RegistrationState>` | Emits registration state changes |
|
|
| `callEvents` | `Stream<CallState>` | Emits call state changes |
|
|
|
|
### Enums
|
|
|
|
#### `RegistrationState`
|
|
|
|
- `None` - Not registered
|
|
- `Progress` - Registration in progress
|
|
- `Ok` - Successfully registered
|
|
- `Cleared` - Registration cleared
|
|
- `Failed` - Registration failed
|
|
|
|
#### `CallState`
|
|
|
|
- `Idle` - No active call
|
|
- `IncomingReceived` - Incoming call received
|
|
- `OutgoingInit` - Outgoing call initialized
|
|
- `OutgoingProgress` - Outgoing call in progress
|
|
- `OutgoingRinging` - Remote party ringing
|
|
- `Connected` - Call connected
|
|
- `StreamsRunning` - Media streams running
|
|
- `Pausing` - Call pausing
|
|
- `Paused` - Call paused
|
|
- `Resuming` - Call resuming
|
|
- `Error` - Call error
|
|
- `End` - Call ended
|
|
- And other states...
|
|
|
|
#### `CallType`
|
|
|
|
- `Audio` - Audio-only call
|
|
- `Video` - Video call
|
|
- `Unknown` - Call type unknown
|
|
|
|
## License
|
|
|
|
This project is licensed under the MIT License.
|
|
|
|
## Links
|
|
|
|
- [Homepage](https://git.nuark.xyz/nuark/liblinphone_flutter)
|
|
- [Linphone Project](https://www.linphone.org/)
|