flutter_nmsip 2.1.2+108
flutter_nmsip: ^2.1.2+108 copied to clipboard
A Flutter plugin for SIP (Session Initiation Protocol) communication using PJSIP library
flutter_sip2 #
A Flutter plugin for SIP (Session Initiation Protocol) communication using PJSIP library.
Features #
- SIP Account Management: Create, register, and manage SIP accounts
- Audio/Video Calls: Make and receive audio and video calls
- Call Control: Answer, hangup, hold, mute, and transfer calls
- DTMF Support: Send DTMF tones during calls
- Background Processing: Handle calls even when the app is in background
- Event Streaming: Real-time events for call state changes
- Cross-platform: Android support (iOS support planned)
Installation #
Add this to your package's pubspec.yaml file:
dependencies:
flutter_sip2: ^0.0.1
Android Setup #
Permissions #
Add the following permissions to your android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.WRITE_CALL_LOG" />
Runtime Permissions #
Request runtime permissions in your app:
import 'package:permission_handler/permission_handler.dart';
Future<void> requestPermissions() async {
await Permission.microphone.request();
await Permission.phone.request();
}
Usage #
Initialize the SIP Endpoint #
First, initialize the SIP endpoint:
import 'package:flutter_sip2/flutter_sip2.dart';
// Initialize the SIP endpoint
final state = await FlutterSip2.start();
print('SIP initialized with ${state['accounts'].length} accounts and ${state['calls'].length} calls');
Listen to Events #
Set up event listeners to handle SIP events:
FlutterSip2.eventStream.listen((event) {
switch (event['type']) {
case 'registration_changed':
handleRegistrationChanged(event['data']);
break;
case 'call_received':
handleCallReceived(event['data']);
break;
case 'call_changed':
handleCallChanged(event['data']);
break;
case 'call_terminated':
handleCallTerminated(event['data']);
break;
case 'connectivity_changed':
handleConnectivityChanged(event['data']['available']);
break;
}
});
Create a SIP Account #
final account = await FlutterSip2.createAccount({
'name': 'John Doe',
'username': '100',
'domain': 'pbx.example.com',
'password': 'password123',
'proxy': '192.168.1.100:5060', // optional
'transport': 'TCP', // optional, default is TCP
'regServer': 'pbx.example.com', // optional
'regTimeout': 3600, // optional, default is 3600
'regHeaders': { // optional
'X-Custom-Header': 'Value'
},
'regContactParams': ';unique-device-token-id=XXXXXXXXX' // optional
});
print('Account created: ${account.name}');
Register the Account #
await FlutterSip2.registerAccount(account, renew: true);
Make a Call #
final call = await FlutterSip2.makeCall(
account,
'destination@domain.com',
callSettings: {
'flag': 0,
'reqKeyframeMethod': 0,
'audCnt': 1,
'vidCnt': 0
},
msgData: {
'headers': {
'P-Asserted-Identity': 'Header example',
'X-UA': 'Flutter SIP2'
}
}
);
print('Call initiated: ${call.id}');
Handle Incoming Calls #
void handleCallReceived(Map<String, dynamic> data) {
final call = Call.fromMap(data['call']);
final account = Account.fromMap(data['account']);
print('Incoming call from: ${call.remoteNumber}');
// Show incoming call UI
showIncomingCallDialog(call, account);
}
void showIncomingCallDialog(Call call, Account account) {
// Show dialog with answer/decline buttons
showDialog(
context: context,
builder: (context) => AlertDialog(
title: Text('Incoming Call'),
content: Text('From: ${call.remoteNumber}'),
actions: [
TextButton(
onPressed: () async {
await FlutterSip2.declineCall(call);
Navigator.pop(context);
},
child: Text('Decline'),
),
TextButton(
onPressed: () async {
await FlutterSip2.answerCall(call);
Navigator.pop(context);
},
child: Text('Answer'),
),
],
),
);
}
Call Control #
// Answer a call
await FlutterSip2.answerCall(call);
// Hangup a call
await FlutterSip2.hangupCall(call);
// Hold a call
await FlutterSip2.holdCall(call);
// Unhold a call
await FlutterSip2.unholdCall(call);
// Mute a call
await FlutterSip2.muteCall(call);
// Unmute a call
await FlutterSip2.unmuteCall(call);
// Use speaker
await FlutterSip2.useSpeaker(call);
// Use earpiece
await FlutterSip2.useEarpiece(call);
// Send DTMF
await FlutterSip2.dtmfCall(call, '123');
// Transfer a call
await FlutterSip2.xferCall(call, 'transfer@domain.com');
// Redirect a call
await FlutterSip2.redirectCall(call, 'redirect@domain.com');
Account Management #
// Delete an account
await FlutterSip2.deleteAccount(account);
// Update STUN servers
await FlutterSip2.updateStunServers(account.id, [
'stun1.example.com:3478',
'stun2.example.com:3478'
]);
// Change service configuration
await FlutterSip2.changeServiceConfiguration({
'userAgent': 'My SIP App',
'stunServers': ['stun.example.com:3478']
});
API Reference #
FlutterSip2 #
Static Methods
start([Map<String, dynamic>? configuration])- Initialize the SIP endpointcreateAccount(Map<String, dynamic> configuration)- Create a new SIP accountregisterAccount(Account account, {bool renew = true})- Register an accountdeleteAccount(Account account)- Delete an accountmakeCall(Account account, String destination, {Map<String, dynamic>? callSettings, Map<String, dynamic>? msgData})- Make a callanswerCall(Call call)- Answer an incoming callhangupCall(Call call)- Hangup a calldeclineCall(Call call)- Decline an incoming callholdCall(Call call)- Hold a callunholdCall(Call call)- Unhold a callmuteCall(Call call)- Mute a callunmuteCall(Call call)- Unmute a calluseSpeaker(Call call)- Use speaker for a calluseEarpiece(Call call)- Use earpiece for a calldtmfCall(Call call, String digits)- Send DTMF digitsxferCall(Call call, String destination)- Transfer a callredirectCall(Call call, String destination)- Redirect a callchangeCodecSettings(Map<String, dynamic> codecSettings)- Change codec settingsupdateStunServers(int accountId, List<String> stunServerList)- Update STUN serverschangeNetworkConfiguration(Map<String, dynamic> configuration)- Change network configurationchangeServiceConfiguration(Map<String, dynamic> configuration)- Change service configuration
Properties
eventStream- Stream of SIP events
Account #
Represents a SIP account with registration status.
Properties
id- Account IDuri- Account URIname- Account nameusername- Usernamedomain- Domainpassword- Passwordproxy- Proxy server (optional)transport- Transport protocol (optional)registration- Registration status
Call #
Represents a SIP call with current state and information.
Properties
id- Call IDaccountId- Account IDstate- Call statestateText- Call state textremoteNumber- Remote numberremoteName- Remote nameheld- Whether call is heldmuted- Whether call is mutedspeaker- Whether speaker is active
Methods
getId()- Get call IDgetAccountId()- Get account IDgetState()- Get call stategetRemoteNumber()- Get remote numbergetRemoteName()- Get remote nameisHeld()- Check if call is heldisMuted()- Check if call is mutedisSpeaker()- Check if speaker is activeisTerminated()- Check if call is terminatedgetTotalDuration()- Get total call durationgetConnectDuration()- Get connected durationgetFormattedTotalDuration()- Get formatted total durationgetFormattedConnectDuration()- Get formatted connected duration
Events #
The plugin emits the following events:
registration_changed- Account registration status changedcall_received- Incoming call receivedcall_changed- Call state changedcall_terminated- Call terminatedcall_screen_locked- Call screen locked (Android only)message_received- SIP message receivedconnectivity_changed- Network connectivity changed
Error Handling #
The plugin throws FlutterSip2Exception for errors:
try {
await FlutterSip2.createAccount(configuration);
} on FlutterSip2Exception catch (e) {
print('SIP error: ${e.code} - ${e.message}');
}
Background Processing #
The plugin supports background processing on Android. Calls can be received and handled even when the app is in the background.
Contributing #
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments #
This plugin is based on the react-native-sip2 library and uses the PJSIP library for SIP functionality.