Live Streaming Video Call Chat Audio Call Chatbot Call SDK Video Call SDK
Live video streaming service has revolutionized how businesses communicate with their customers. Companies have realized the potential of using live streaming services to engage and maintain an open relationship with their audience.
Get StartedWelcome to Live Chat
Please fill the details below before chatting with us
Customer Support
to start live chat.
is now online.
Your chat has ended
Ask more question by starting a new chat
Simply Practical
Call our API in a single line. We have been working hard to ensure the utmost practicality and ease.
import 'package:flutter/material.dart'; import 'package:nusa/newuniverse.dart'; class Home extends StatefulWidget { @override StatecreateState() { return new HomeState(); } } class HomeState extends State { final _channelController = TextEditingController(); bool _validateError = false; @override void initState() { super.initState(); _initialize(); } Future _initialize() async { _initNusa(); _addNusaEvent(); } Future _initNusa() async { // Change initiation with your credential here.. await Nusa.init('abcd_1234', 'tesa'); Nusa.bind(); } Future _addNusaEvent() async { Nusa.onAudioCallReceiver = (String originator, int state, String message) { Navigator.push( context, MaterialPageRoute( builder: (context) => SmartAudioCall(destination: originator, isInitiator: false))); }; Nusa.onVideoCallReceiver = (String originator, int state, String message) { Navigator.push( context, MaterialPageRoute(builder: (context) => VideoCall())); }; Nusa.onMessageCallback = (int messageId, int contentType, int status) { print( 'onMessageCallback -> messageId: $messageId, contentType: $contentType, status: $status'); Nusa.getMessage(messageId).then((f) { print('getMessage: $f'); }); }; Nusa.onMessageReceiver = (int messageId) { print('onMessageReceiver -> messageId: $messageId'); Nusa.getMessage(18109917689132).then((f) { print('getMessage: $f'); }); }; Nusa.onForumCallback = (String name, String message) { print('onForumCallback: $name/$message'); }; } @override void dispose() { _channelController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Nusa Example'), ), floatingActionButton: new Builder(builder: (BuildContext context) { return new FloatingActionButton( onPressed: () { Nusa.getForumDetail('5YfqTiDbKVQu').then((f) { print('f: $f'); }); }, child: new Icon(Icons.info), ); }), body: Center( child: Container( padding: EdgeInsets.symmetric(horizontal: 8), height: 400, child: Column( children: [ Row(children: []), Row(children: [ Expanded( child: TextField( controller: _channelController, decoration: InputDecoration( errorText: _validateError ? 'Destination is mandatory' : null, border: UnderlineInputBorder( borderSide: BorderSide(width: 1)), hintText: 'Destination'), )) ]), Padding( padding: EdgeInsets.symmetric(vertical: 8), child: Row( children: [ Expanded( child: RaisedButton( onPressed: () => _onInitiate(true), child: Text('Initiate'), color: Colors.blueAccent, textColor: Colors.white, ), ) ], )), Padding( padding: EdgeInsets.symmetric(vertical: 8), child: Row( children: [ Expanded( child: RaisedButton( onPressed: () => _onInitiate(false), child: Text('Join'), color: Colors.blueAccent, textColor: Colors.white, ), ) ], )) ], )), )); } _onInitiate(bool isInitiator) async { setState(() { _channelController.text.isEmpty ? _validateError = true : _validateError = false; }); if (_channelController.text.isNotEmpty) { // Common Live Streaming Navigator.push(context, MaterialPageRoute( builder: (context) => LiveStreaming( title: 'TEST', destination: isInitiator ? _channelController.text : null))); /* Use code below for Smart Live Streaming */ // Navigator.push(context, MaterialPageRoute( // builder: (context) => SmartLiveStreaming( // title: 'TEST', // destination: _channelController.text))); } } void _showToast(BuildContext context, String status) { final scaffold = Scaffold.of(context); scaffold.showSnackBar( SnackBar( content: Text('User Status : ' + status), action: SnackBarAction( label: 'Close', onPressed: scaffold.hideCurrentSnackBar), ), ); } }
import 'package:flutter/material.dart'; import 'package:nusa/nusa.dart'; import 'dart:async'; import 'live_streaming.dart'; class ListLiveStreaming extends StatefulWidget { final String destination; const ListLiveStreaming({Key key, this.destination}) : super(key: key); @override ListLiveStreamingState createState() => ListLiveStreamingState(); } class ListLiveStreamingState extends State{ final _biggerfont = const TextStyle(fontSize: 18.0); List message = []; @override void initState() { super.initState(); initialize(); } void initialize() { _bindNusa(); _addNusaEvent(); } Future _bindNusa() async { Nusa.bind(); } void _addNusaEvent() { Nusa.onError = (dynamic code) { print('onError $code'); }; Nusa.onFailed = (dynamic code) { print('onFailed $code'); }; Nusa.onSuccess = () async { List hehe; print('onSuccess'); hehe = await Nusa.listLiveStreaming(); for(String s in hehe){ message.add(s); } print("Message: " + message.toString()); setState(() { }); }; } @override Widget build(BuildContext context){ return Scaffold( appBar: AppBar( title: Text('List Live Streaming'), ), body: _buildList(), ); } Widget _buildList() { return ListView.separated( padding: const EdgeInsets.all(16.0), itemBuilder: (context, i) { return _buildRow(message[i]); }, itemCount: message.length, separatorBuilder: (context, i) => const Divider(), ); } Widget _buildRow(String name){ return ListTile( onTap: () { Navigator.push( context, MaterialPageRoute( builder: (context) => LiveStreaming( destination: name, ))); }, title: Text( name, style: _biggerfont, ), ); } }
import 'package:flutter/material.dart'; import 'package:nusa/nusa.dart'; import 'package:nusa/widget/camera.dart'; import 'package:nusa/widget/remote.dart'; import 'dart:async'; class LiveStreaming extends StatefulWidget { final String title; final String destination; const LiveStreaming({Key key, this.title, this.destination}) : super(key: key); @override StatecreateState() => _LiveStreamingState(); } class _LiveStreamingState extends State { bool muted = false, camera = false; final _infoStrings = []; @override void initState() { super.initState(); initialize(); } @override void dispose() { if (widget.destination == null) { Nusa.endLiveStreaming(); } else { Nusa.leftLiveStreaming(widget.destination); } super.dispose(); } void initialize() { _bindNusa(); _addNusaEvent(); } Future _bindNusa() async { Nusa.bind(); } void _addNusaEvent() { Nusa.onError = (dynamic code) { print('onError $code'); }; Nusa.onFailed = (dynamic code) { print('onFailed $code'); }; Nusa.onSuccess = () async { print('onSuccess'); Future.delayed(Duration(seconds: 1), () { if(widget.destination == null) Nusa.startLiveStreaming(widget.title, CameraInfo.CAMERA_FACING_FRONT); else Nusa.joinLiveStreaming(widget.destination); }); }; if (widget.destination == null) { Nusa.onStartLiveStreamingCallback = (String destination, int state, String message) { if (mounted) { setState(() { String info = 'onStart: $destination:$state:$message'; _infoStrings.add(info); }); } }; } else { Nusa.onJoinLiveStreamingCallback = (String destination, int state, String message) { if (mounted) { setState(() { String info = 'onJoin: $destination:$state:$message'; _infoStrings.add(info); }); } }; } } Widget _view() { return Container( child: widget.destination == null ? Camera() : Remote(), ); } Widget _toolbar() { return Container( alignment: Alignment.topRight, child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ IconButton( onPressed: () { setState(() { camera = !camera; }); Nusa.changeCamera(camera); }, icon: Icon( Icons.switch_camera, color: Colors.white, ), ) ], ), ); } Widget _panel() { return Container( padding: EdgeInsets.symmetric(vertical: 48), alignment: Alignment.bottomCenter, child: FractionallySizedBox( heightFactor: 0.5, child: Container( padding: EdgeInsets.symmetric(vertical: 48), child: ListView.builder( physics: NeverScrollableScrollPhysics(), reverse: true, itemCount: _infoStrings.length, itemBuilder: (BuildContext context, int index) { if (_infoStrings.length == 0) { return null; } return Padding( padding: EdgeInsets.symmetric(vertical: 3, horizontal: 10), child: Row(mainAxisSize: MainAxisSize.min, children: [ Flexible( child: Container( padding: EdgeInsets.symmetric( vertical: 2, horizontal: 5), decoration: BoxDecoration( color: Colors.yellowAccent, borderRadius: BorderRadius.circular(5)), child: Text(_infoStrings[index], style: TextStyle(color: Colors.blueGrey)))) ])); })), )); } @override Widget build(BuildContext context) { return Stack( children: [ _view(), Scaffold( appBar: AppBar( leading: FlatButton( onPressed: () => Navigator.of(context).pop(), child: Text('END', style: TextStyle(color: Colors.white)), padding: EdgeInsets.all(0.0)), backgroundColor: Colors.transparent, title: Text(widget.title ?? ''), actions: [ Row( mainAxisSize: MainAxisSize.min, children: [ Container( padding: EdgeInsets.all(1), child: Text('LIVE'), color: Colors.redAccent, ), Container(width: 6), Icon(Icons.remove_red_eye), Container(width: 6), Text('2K'), Container(width: 6), ], ) ], centerTitle: true, elevation: 0.0, ), backgroundColor: Colors.transparent, body: Center( child: Stack( children: [_panel(), _toolbar()], )), ), ], ); } }
import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:nusa/newuniverse.dart'; import 'package:nusa/widget/camera.dart'; import 'package:nusa/widget/remote.dart'; import 'dart:async'; class SmartLiveStreaming extends StatefulWidget { final String title; final String destination; final bool isInitiator; const SmartLiveStreaming( {Key key, this.title, this.destination, this.isInitiator = true}) : super(key: key); @override StatecreateState() => _SmartLiveStreamingState(); } class _SmartLiveStreamingState extends State { bool muted = false, camera = false; final _infoStrings = []; int count = 0; String originator = ""; @override void initState() { super.initState(); initialize(); } @override void dispose() { if (widget.isInitiator) { Nusa.endLiveStreaming(); } else { Nusa.leftLiveStreaming(widget.destination); } super.dispose(); } void initialize() { _bindNusa(); _addNusaEvent(); } Future _bindNusa() async { Nusa.bind(); } void _addNusaEvent() { Nusa.onError = (dynamic code) { print('onError $code'); }; Nusa.onFailed = (dynamic code) { print('onFailed $code'); }; Nusa.onSuccess = () async { print('onSuccess'); Future.delayed(Duration(seconds: 1), () { if (widget.isInitiator) { Nusa.startLiveStreaming(widget.title, CameraInfo.CAMERA_FACING_FRONT); Nusa.whiteboardInit(widget.destination); } else { Nusa.joinLiveStreaming(widget.destination); Nusa.whiteboardJoin(widget.destination); } }); }; if (widget.isInitiator) { Nusa.onStartLiveStreamingCallback = (String destination, int state, String message) { if (mounted) { setState(() { String info = 'onStart: $destination:$state:$message'; _infoStrings.add(info); originator = message.split(",")[0]; print("originator $originator"); }); } }; } else { Nusa.onJoinLiveStreamingCallback = (String destination, int state, String message) { if (mounted) { setState(() { String info = 'onJoin: $destination:$state:$message'; _infoStrings.add(info); originator = message.split(",")[0]; print("originator $originator"); }); } }; } } Widget _view() { return Container( child: widget.isInitiator ? Camera() : Remote(), ); } Widget _toolbar() { return Container( alignment: Alignment.topRight, child: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ IconButton( onPressed: () { setState(() { camera = !camera; }); Nusa.changeCamera(camera); }, icon: Icon( Icons.switch_camera, color: Colors.white, ), ),IconButton( onPressed: () { Nusa.getLSViewerInfo(originator).then((value){ setState(() { print("Viewer LS $value"); var data = json.decode(value); count = data['count']; }); }); }, icon: Icon( Icons.supervised_user_circle, color: Colors.white, ), ) ], ), ); } Widget _panel() { return Container( padding: EdgeInsets.symmetric(vertical: 48), alignment: Alignment.bottomCenter, child: FractionallySizedBox( heightFactor: 0.5, child: Container( padding: EdgeInsets.symmetric(vertical: 48), child: ListView.builder( physics: NeverScrollableScrollPhysics(), reverse: true, itemCount: _infoStrings.length, itemBuilder: (BuildContext context, int index) { if (_infoStrings.length == 0) { return null; } return Padding( padding: EdgeInsets.symmetric(vertical: 3, horizontal: 10), child: Row(mainAxisSize: MainAxisSize.min, children: [ Flexible( child: Container( padding: EdgeInsets.symmetric( vertical: 2, horizontal: 5), decoration: BoxDecoration( color: Colors.yellowAccent, borderRadius: BorderRadius.circular(5)), child: Text(_infoStrings[index], style: TextStyle(color: Colors.blueGrey)))) ])); })), )); } @override Widget build(BuildContext context) { return Stack( children: [ _view(), Scaffold( appBar: AppBar( leading: FlatButton( onPressed: () => Navigator.of(context).pop(), child: Text('END', style: TextStyle(color: Colors.white)), padding: EdgeInsets.all(0.0)), backgroundColor: Colors.transparent, title: Text(widget.title ?? ''), actions: [ Row( mainAxisSize: MainAxisSize.min, children: [ Container( padding: EdgeInsets.all(1), child: Text('LIVE'), color: Colors.redAccent, ), Container(width: 6), Icon(Icons.remove_red_eye), Container(width: 6), Text('2K'), Container(width: 6), ], ) ], centerTitle: true, elevation: 0.0, ), backgroundColor: Colors.transparent, body: Center( child: Stack( children: [ _panel(), Board( backgroundColor: Colors.transparent, penColor: Colors.white), _toolbar() ], )), ), ], ); } }
//repository repositories { google() jcenter() maven { url "http://192.168.0.6:8040/artifactory/libs-release-local" credentials { username = "${artifactory_username}" password = "${artifactory_password}" } } } //dependencies dependencies { implementation 'io.newuniverse:api:1.0.0' }
# Project-wide Gradle settings. # IDE (e.g. Android Studio) users: # Gradle settings configured through the IDE *will override* # any settings specified in this file. # For more details on how to configure your build environment visit # http://www.gradle.org/docs/current/userguide/build_environment.html # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. org.gradle.jvmargs=-Xmx1536m # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects # org.gradle.parallel=true # AndroidX package structure to make it clearer which packages are bundled with the # Android operating system, and which are packaged with your app's APK # https://developer.android.com/topic/libraries/support-library/androidx-rn android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official artifactory_username=universe artifactory_password=AP6yjFzMDSCUqAX2f2inpXoTUog
package io.newuniverse.luna import android.Manifest import android.content.Intent import android.content.pm.PackageManager import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.core.app.ActivityCompat import androidx.core.content.ContextCompat import io.newuniverse.nusdk.core.NuSDK import io.newuniverse.nusdk.livestreaming.LiveStreamingActivity import kotlinx.android.synthetic.main.audio_call_example.start import kotlinx.android.synthetic.main.live_streaming_example.* class LiveStreamingExample : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.live_streaming_example) NuSDK.init("abcd_1234", "yayandw") bind() start.setOnClickListener { val intent = Intent(this, LiveStreamingActivity::class.java) startActivity(intent) } join.setOnClickListener { val intent = Intent(this, LiveStreamingActivity::class.java) .putExtra("Destination", "tesa") startActivity(intent) } } private var permissions = arrayOf( Manifest.permission.READ_PHONE_STATE, Manifest.permission.RECORD_AUDIO, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.MODIFY_AUDIO_SETTINGS ) private fun isAllowPermission(): Boolean { for (permission in permissions) { if (ContextCompat.checkSelfPermission( this, permission ) != PackageManager.PERMISSION_GRANTED ) { ActivityCompat.requestPermissions(this, permissions, 1) return false } } return true } override fun onRequestPermissionsResult( requestCode: Int, permissions: Array, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (!isAllowPermission()) { finish() return } bind() } private fun bind() { if (ActivityCompat.checkSelfPermission( this, Manifest.permission.READ_PHONE_STATE ) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission( this, Manifest.permission.WRITE_EXTERNAL_STORAGE ) != PackageManager.PERMISSION_GRANTED ) { ActivityCompat.requestPermissions(this, permissions, 1) return } NuSDK.bind(this, object : NuSDK.BindListener { override fun failed(var1: String?) { } override fun success() { } }) } }