siprix_voip_sdk 1.0.13 copy "siprix_voip_sdk: ^1.0.13" to clipboard
siprix_voip_sdk: ^1.0.13 copied to clipboard

Siprix VoIP SDK plugin for embedding voice-over-IP (VoIP) audio/video calls based on SIP/RTP protocols into Flutter applications.

example/lib/main.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';

import 'package:shared_preferences/shared_preferences.dart';

//import 'package:firebase_core/firebase_core.dart';
//import 'package:firebase_messaging/firebase_messaging.dart';

import 'package:siprix_voip_sdk/accounts_model.dart';
import 'package:siprix_voip_sdk/messages_model.dart';
import 'package:siprix_voip_sdk/network_model.dart';
import 'package:siprix_voip_sdk/cdrs_model.dart';
import 'package:siprix_voip_sdk/devices_model.dart';
import 'package:siprix_voip_sdk/logs_model.dart';
import 'package:siprix_voip_sdk/subscriptions_model.dart';
import 'package:siprix_voip_sdk/siprix_voip_sdk.dart';

import 'accouns_model_app.dart';
import 'calls_model_app.dart';
import 'subscr_model_app.dart';

import 'account_add.dart';
import 'call_add.dart';
import 'subscr_add.dart';
import 'settings.dart';
import 'home.dart';

void main() async {
  //Wait while Firebase initialized
  //await _initializeFCM();
  debugPrint('main');

  //Create models
  LogsModel logsModel = LogsModel(true);//Set 'false' when logs won't rendering on UI
  CdrsModel cdrsModel = CdrsModel();//List of recent calls (Call Details Records)

  DevicesModel devicesModel = DevicesModel(logsModel);//List of devices
  NetworkModel networkModel = NetworkModel(logsModel);//Network state details
  AppAccountsModel accountsModel = AppAccountsModel(logsModel);//List of accounts
  MessagesModel messagesModel = MessagesModel(accountsModel, logsModel);
  AppCallsModel callsModel = AppCallsModel(accountsModel, logsModel, cdrsModel);//List of calls
  SubscriptionsModel subscrModel = SubscriptionsModel<AppBlfSubscrModel>(accountsModel, AppBlfSubscrModel.fromJson, logsModel);//List of subscriptions

  //Run app
  runApp(
    MultiProvider(providers:[
      ChangeNotifierProvider(create: (context) => accountsModel),
      ChangeNotifierProvider(create: (context) => networkModel),
      ChangeNotifierProvider(create: (context) => devicesModel),
      ChangeNotifierProvider(create: (context) => messagesModel),
      ChangeNotifierProvider(create: (context) => subscrModel),
      ChangeNotifierProvider(create: (context) => callsModel),
      ChangeNotifierProvider(create: (context) => cdrsModel),
      ChangeNotifierProvider(create: (context) => logsModel),
    ],
    child: const MyApp(),
  ));
}

/*
Future<void> _initializeFCM() async {
  if(!Platform.isAndroid)  return;

  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(//options: DefaultFirebaseOptions.currentPlatform,);
    options: const FirebaseOptions(
      apiKey: '...',            //Your apiKey here
      appId: '...',             //Your appId here
      messagingSenderId: '...', //Your senderId here
      projectId: '...',         //Your projectId here
      storageBucket: '...',     //Your storageBucket here
    )
  );
  debugPrint('Firebase.initializeApp');

  FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
}

@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
  WidgetsFlutterBinding.ensureInitialized();

  await Firebase.initializeApp(
     options: const FirebaseOptions(
      apiKey: '...',            //Your apiKey here
      appId: '...',             //Your appId here
      messagingSenderId: '...', //Your senderId here
      projectId: '...',         //Your projectId here
      storageBucket: '...',     //Your storageBucket here
    )
  );

  //!!! This code is working in the background isolate!
  //!!! When this method triggerer app is working in background (activity may not exist) or completely stopped
  //!!! Code below initializes Siprix, adds saved accounts and refreshes registration (makes app ready to receive incoming call)

  debugPrint("[!!!] Handling a background message id:'${message.messageId}' data:'${message.data}'");

  try{
    debugPrint("Initialize siprix");
    _MyAppState._initializeSiprix();

    debugPrint("Read and add accounts");
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String accJsonStr = prefs.getString('accounts') ?? '';
    if(accJsonStr.isNotEmpty) {
      AppAccountsModel tmpAccsModel = AppAccountsModel();
      tmpAccsModel.loadFromJson(accJsonStr);
      tmpAccsModel.refreshRegistration();
    }
  } on Exception catch (err) {
      debugPrint('Error: ${err.toString()}');
  }
}
*/

class MyApp extends StatefulWidget {
  const MyApp({super.key});
  static String _ringtonePath="";

  @override
  State<MyApp> createState() => _MyAppState();

  /// Returns ringtone's path saved on device
  static String getRingtonePath() => _ringtonePath;

  /// Write ringtone file from asset to device
  void writeRingtoneAsset() async {
    _ringtonePath = await writeAssetAndGetFilePath("ringtone.mp3");
  }

  /// Write file from assest to device and returns path to it
  static Future<String> writeAssetAndGetFilePath(String assetsFileName) async {
    var homeFolder = await SiprixVoipSdk().homeFolder();
    var filePath = '$homeFolder$assetsFileName';

    var file = File(filePath);
    var exists = file.existsSync();
    debugPrint("writeAsset: '$filePath' exists:$exists");
    if (exists) return filePath;

    final byteData = await rootBundle.load('assets/$assetsFileName');
    await file.create(recursive: true);
    file.writeAsBytes(byteData.buffer.asUint8List(), flush: true);
    return filePath;
  }

  ///returns path to folder when app stores recorded files
  static Future<String> getRecFilePath(String recFileName) async {
    var homeFolder = await SiprixVoipSdk().homeFolder();
    var filePath = '$homeFolder$recFileName';
    return filePath;
  }
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();

    _initializeSiprix(context.read<LogsModel>());
    widget.writeRingtoneAsset();//after initialize Siprix as uses its 'homeFolder'
    _readSavedState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      routes: <String, WidgetBuilder>{
        CallAddPage.routeName: (BuildContext context) => const CallAddPage(true),
        SettingsPage.routeName: (BuildContext context) => const SettingsPage(),
        AccountPage.routeName: (BuildContext context) => const AccountPage(),
        SubscrAddPage.routeName: (BuildContext context) => const SubscrAddPage(),
      },
      home: const HomePage(),
      title: 'Siprix VoIP app',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
        visualDensity: VisualDensity.adaptivePlatformDensity,
        useMaterial3: true,
      ),
    );
  }

  static void _initializeSiprix([LogsModel? logsModel]) async {
    debugPrint('_initializeSiprix');
    InitData iniData = InitData();
    iniData.license  = "...license-credentials...";
    iniData.logLevelFile = LogLevel.debug;
    iniData.logLevelIde = LogLevel.info;
    //- uncomment if required -//
    //iniData.listenTelState = true;
    //iniData.singleCallMode = false;
    //iniData.tlsVerifyServer = false;
    //iniData.enableCallKit = true;
    //iniData.enablePushKit = true;
    await SiprixVoipSdk().initialize(iniData, logsModel);

    //Set video params (if required)
    //VideoData vdoData = VideoData();
    //vdoData.noCameraImgPath = await MyApp.writeAssetAndGetFilePath("noCamera.jpg");
    //vdoData.bitrateKbps = 800;
    //SiprixVoipSdk().setVideoParams(vdoData);
  }

  void _readSavedState() {
    debugPrint('_readSavedState');
    SharedPreferences.getInstance().then((prefs) {
      String accJsonStr = prefs.getString('accounts') ?? '';
      String subsJsonStr = prefs.getString('subscriptions') ?? '';
      String cdrsJsonStr = prefs.getString('cdrs') ?? '';
      String msgsJsonStr = prefs.getString('msgs') ?? '';
      _loadModels(accJsonStr, cdrsJsonStr, subsJsonStr, msgsJsonStr);
    });
  }

  void _loadModels(String accJsonStr, String cdrsJsonStr, String subsJsonStr, String msgsJsonStr) {
    //Accounts
    AppAccountsModel accsModel = context.read<AppAccountsModel>();
    accsModel.onSaveChanges = _saveAccountChanges;

    //Subscriptions
    SubscriptionsModel subs = context.read<SubscriptionsModel>();
    subs.onSaveChanges = _saveSubscriptionChanges;

    MessagesModel msgs = context.read<MessagesModel>();
    msgs.onSaveChanges = _saveMessagesChanges;

    //CDRs (Call Details Records)
    CdrsModel cdrs = context.read<CdrsModel>();
    cdrs.onSaveChanges = _saveCdrsChanges;

    //Load accounts, then other models
    accsModel.loadFromJson(accJsonStr).then((val)  {
      subs.loadFromJson(subsJsonStr);
      cdrs.loadFromJson(cdrsJsonStr);
      msgs.loadFromJson(msgsJsonStr);
    });

    //Assign contact name resolver
    context.read<AppCallsModel>().onResolveContactName = _resolveContactName;

    //Load devices
    context.read<DevicesModel>().load();
  }

  void _saveCdrsChanges(String cdrsJsonStr) {
    SharedPreferences.getInstance().then((prefs) {
      prefs.setString('cdrs', cdrsJsonStr);
    });
  }

  void _saveAccountChanges(String accountsJsonStr) {
    SharedPreferences.getInstance().then((prefs) {
      prefs.setString('accounts', accountsJsonStr);
    });
  }

  void _saveSubscriptionChanges(String subscrJsonStr) {
    SharedPreferences.getInstance().then((prefs) {
      prefs.setString('subscriptions', subscrJsonStr);
    });
  }

  void _saveMessagesChanges(String msgsJsonStr) {
    SharedPreferences.getInstance().then((prefs) {
      prefs.setString('msgs', msgsJsonStr);
    });
  }

  String _resolveContactName(String phoneNumber) {
    return ""; //TODO add own implementation
    //if(phoneNumber=="100") { return "MyFriend100"; } else
    //if(phoneNumber=="101") { return "MyFriend101"; }
    //else                  { return "";        }
  }
}




/*
//=======================================//
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

import 'package:siprix_voip_sdk/accounts_model.dart';
import 'package:siprix_voip_sdk/calls_model.dart';
import 'package:siprix_voip_sdk/logs_model.dart';
import 'package:siprix_voip_sdk/siprix_voip_sdk.dart';

void main() async {  
  AccountsModel accountsModel = AccountsModel();
  CallsModel callsModel = CallsModel(accountsModel);
  runApp(
    MultiProvider(providers:[
      ChangeNotifierProvider(create: (context) => accountsModel),      
      ChangeNotifierProvider(create: (context) => callsModel),      
    ],
    child: const MyApp(),
  ));
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});  

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    _initializeSiprix();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Siprix VoIP app',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
        visualDensity: VisualDensity.adaptivePlatformDensity,        
      ),
      home: Scaffold(body:buildBody())
    );
  }

  Widget buildBody() {
    final accounts = context.watch<AppAccountsModel>();
    final calls = context.watch<AppCallsModel>();
    return Column(children: [
      ListView.separated(
        shrinkWrap: true,        
        itemCount: accounts.length,
        separatorBuilder: (BuildContext context, int index) => const Divider(height: 1),
        itemBuilder: (BuildContext context, int index) {
          AccountModel acc = accounts[index];
          return 
            ListTile(title: Text(acc.uri, style: Theme.of(context).textTheme.titleSmall),
                subtitle: Text(acc.regText),
                tileColor: Colors.blue
            ); 
        },
      ),
      ElevatedButton(onPressed: _addAccount, child: const Icon(Icons.add_card)),
      const Divider(height: 1),
      ListView.separated(
        shrinkWrap: true,
        itemCount: calls.length,        
        separatorBuilder: (BuildContext context, int index) => const Divider(height: 1),
        itemBuilder: (BuildContext context, int index) {
          CallModel call = calls[index];
          return 
            ListTile(title: Text(call.nameAndExt, style: Theme.of(context).textTheme.titleSmall),
              subtitle: Text(call.state.name), tileColor: Colors.amber,
              trailing: IconButton(
                onPressed: (){ call.bye(); },
                icon: const Icon(Icons.call_end))
            );
        },
      ),
      ElevatedButton(onPressed: _addCall, child: const Icon(Icons.add_call)),
      const Spacer(),
    ]);
  }

  void _initializeSiprix([LogsModel? logsModel]) async {
    InitData iniData = InitData();
    iniData.license  = "...license-credentials...";
    iniData.logLevelFile = LogLevel.info;    
    SiprixVoipSdk().initialize(iniData, logsModel);
  }

  void _addAccount() {
    AccountModel account = AccountModel();
    account.sipServer = "192.168.0.122";
    account.sipExtension = "1016";
    account.sipPassword = "12345";
    account.expireTime = 300;
    context.read<AppAccountsModel>().addAccount(account)
      .catchError(showSnackBar);
  }

  void _addCall() {
    final accounts = context.read<AppAccountsModel>();
    if(accounts.selAccountId==null) return;

    CallDestination dest = CallDestination("1012", accounts.selAccountId!, false);

    context.read<AppCallsModel>().invite(dest)
      .catchError(showSnackBar);
  }

  void showSnackBar(dynamic err) {
    ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(err)));
  }
}
*/
copied to clipboard
5
likes
150
points
283
downloads

Publisher

verified publishersiprix-voip.com

Weekly Downloads

2024.09.17 - 2025.04.01

Siprix VoIP SDK plugin for embedding voice-over-IP (VoIP) audio/video calls based on SIP/RTP protocols into Flutter applications.

Homepage
Repository (GitHub)
View/report issues

Topics

#sip #voip #call

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

flutter, intl, siprix_voip_sdk_android, siprix_voip_sdk_ios, siprix_voip_sdk_linux, siprix_voip_sdk_macos, siprix_voip_sdk_platform_interface, siprix_voip_sdk_windows

More

Packages that depend on siprix_voip_sdk