Tổng quan về Stringee Call API

Chuẩn bị

Trước khi bạn có thể dùng Stringee Call API để tạo và nhận cuộc gọi video, bạn cần :

  1. Tạo tài khoản Stringee miễn phí tại đây.

  2. Tạo project trên Stringee Dashboard.

Stringee create project

  1. Cấu hình answer_url
  • Để hiểu rõ hơn về answer_url, bạn xem tại đây .Bạn có thể tham khảo cách tạo answer_url tại đây

  • Để có thể thực hiệc cuộc gọi ban cần cấu hình answer_url vào project của bạn như sau:

Stringee project answer_url

Nếu bạn chưa có sẵn answer_url, bạn có thể sử dụng Project's answer_url sau để đẩy nhanh quá trình:


  

https://developer.stringee.com/scco_helper/simple_project_answer_url?record=false&appToPhone=auto&recordFormat=mp3

  

(Source code: https://github.com/stringeecom/server-samples/blob/master/answer_url/php/project_answer_url.php)

Khi xây dựng ứng dụng, bạn nên có answer_url của riêng mình.

Tích hợp stringee-react-native

Chuẩn bị

  1. Tạo một project React Native.

  2. Tạo một CallScreen để hiển thị màn hình của cuộc gọi.

Cài đặt stringee-react-native

  1. Ở terminal, chuyển đường dẫn tới React Native Project

  2. Chạy lệh $ npm install stringee-react-native --save

Cài đặt với từng môi trường

Android

  1. Mở file build.gradle và thêm các dòng sau:

  

buildscript {

  

repositories {

  

...

  

mavenCentral()

  

}

  

}

  

...

  

allprojects {

  

repositories {

  

...

  

mavenCentral()

  

}

  

}

  
  1. Mở file app/build.gradle và thêm các dòng sau:

  

android {

  

...

  

compileOptions {

  

sourceCompatibility JavaVersion.VERSION_1_8

  

targetCompatibility JavaVersion.VERSION_1_8

  

}

  

}

  

dependencies {

  

...

  

implementation 'com.android.volley:volley:1.2.1'

  

}

  
  1. Permissions

Với Android Stringee yêu cầu một số permissions, mở file AndroidManifest.xml và thêm các dòng sau:


  

/// permission cho việc kết nối internet

  

<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" />

  

  

// permission cho cuộc gọi

  

<uses-permission android:name="android.permission.RECORD_AUDIO" />

  

<uses-permission android:name="android.permission.CAMERA" />

  

<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

  

<uses-permission android:name="android.permission.BLUETOOTH" />

  

<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> // permission này mới thêm trên android sdk version 31

  

Ghi chú:

  • Bạn bắt buộc phải cấp đủ quyền trước khi thực hiện cuộc gọi, trước khi thực hiện cuộc gọi bàn bắt buộc yêu cầu các quyền sau: RECORD_AUDIO, CAMERA

  • Với việc sử dụng class StringeeAudioManager bạn cần cấp thêm quyền BLUETOOTH_CONNECT đối với android sdk version 31 trở lên

  1. ProGuard
  • Tạo file proguard-rules.pro trong thư mục app và thêm:

  

-dontwarn org.webrtc.**

  

-keep class org.webrtc.** { *; }

  

-dontwarn org.apache.http.**

  

-keep class com.stringee.** { *; }

  
  • Thêm các dòng sau trong app/buidl.gradle:

  

android {

  

...

  

buildTypes {

  

...

  

release {

  

...

  

useProguard true

  

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

  

}

  

}

  

}

  

iOS

  1. Vào thư mục iOS và chạy lệnh pod install

  2. Thêm quyền truy cập camera và microphone vào file Info.split


<key>NSCameraUsageDescription</key>

    <string>$(PRODUCT_NAME) uses Camera</string>

<key>NSMicrophoneUsageDescription</key>

    <string>$(PRODUCT_NAME) uses Microphone</string>

Kết nối Stringee server

Để kết nối đến Stringee Server, bạn cần có access_token. Trong quá trình xây dựng ứng dụng, access_token nên được tạo ra từ server của bạn, bạn có thể tìm hiểu thêm về authentication ở đây: Client authentication, và code mẫu tạo access_token: https://github.com/stringeecom/server-samples/tree/master/access_token.

Để tiết kiệm thời gian, chúng tôi sẽ hard code access_token ở trong ứng dụng:

  1. Khởi tạo một biến để chứa access_token.
const token = "access_token";
  1. Lấy access_token và hard code dữ liệu :

Để làm điều đó, chúng tôi đã cung cấp sẵn tool để sinh ra access_token, bạn truy cập vào Dashboard -> Tools -> Generate Access token và sinh access_token của bạn.

Tiếp theo, chúng ta sẽ kết nối đến Stringee Server. Bạn cần phải kết nối được đến Stringee Server trước thì mới có thể thực hiện được cuộc gọi.

  1. Khởi tạo StringeeClient.
import { StringeeClient } from 'stringee-react-native'
...

const Home = () => {

    const client = useRef();

    useEffect(() => {

        client.current.connect(userToken)

    }, [])

    const setupStringeeClient = () => {
        <StringeeClient
            ref={client}
        />
    }
}

  
  1. Lắng nghe sự kiện từ StringeeClient để giao tiếp với Stringee Server trong eventHandlers của bạn:
const setupStringeeClient = () => {

    const clientDidConnect = (data) => {

    console.log(data)

    setUserId(data.userId);

}

const clientDidDisConnect = (data) => {

    console.log("clientDidDisConnect", data);

}

const clientDidFailWithError = (data) => {

    console.log("clientDidFailWithError", data);

}

const clientRequestAccessToken = (data) => {

    console.log("clientRequestAccessToken", data);

}

const callIncomingCall2 = (data) => {

    console.log("onIncomingCall2", data);

}

const eventHandlers = {

    onConnect: clientDidConnect,

    onDisConnect: clientDidDisConnect,

    onFailWithError: clientDidFailWithError,

    onRequestAccessToken: clientRequestAccessToken,

    onIncomingCall2: callIncomingCall2,
}

const setupStringeeClient = () => {
    <StringeeClient
        ref={client}
        eventHandlers = {eventHandlers}
    />
}

Xử lý logic cuộc gọi

Sau khi kết nối đến Stringee Server, bạn cần thực hiện các bước sau:

  1. Khởi tạo đối tượng StringeeCall2 vào màn hình cuộc gọi và tiền xử lý cuộc gọi:

    import { StringeeCall2, StringeeVideoView } from 'stringee-react-native'
    ...
    
    const Call = ({ route }) => {
    
        const call = useRef();
    
        const setupStringeeCall2 = () => {
            return (
                <StringeeCall2
                    ref={call}
                    clientId={route.params.clientId}
                />
            )
        }
    }
    
  2. Lắng nghe sự kiện của cuộc gọi trong eventHandlers:

    
    const setupStringeeCall2 = () => {
        const callDidChangeSignalingState = (data) => {
        console.log('callDidChangeSignalingState', data);
            switch (data.code) {
                case 0:
                    break;
                case 1:
                    break;
                case 2:
                    setCallState(CallState.CALLING)
                    break;
                case 3:
                    navigation.goBack()
                    break;
                case 4:
                    navigation.goBack()
                    break;
            }
        }
    const callDidChangeMediaState = (data) => {
        console.log('callDidChangeMediaState', data);
    }
    const callDidReceiveLocalStream = (data) => {
        console.log('callDidReceiveLocalStream', data);
        setLocalStream(true)
    }
    const callDidReceiveRemoteStream = (data) => {
        console.log('callDidReceiveRemoteStream', data);
            setRemoteStream(true)
        }
        const didReceiveDtmfDigit = (data) => {
            console.log('didReceiveDtmfDigit', data);
        }
        const didReceiveCallInfo = (data) => {
            console.log('didReceiveCallInfo', data);
        }
        const didHandleOnAnotherDevice = (data) => {
            console.log('didHandleOnAnotherDevice', data);
        }
        const didAudioDeviceChange = (data) => {
            console.log('didAudioDeviceChange', data)
        }
        const callEvents = {
            onChangeSignalingState: callDidChangeSignalingState,
            onChangeMediaState: callDidChangeMediaState,
            onReceiveLocalStream: callDidReceiveLocalStream,
            onReceiveRemoteStream: callDidReceiveRemoteStream,
            onReceiveDtmfDigit: didReceiveDtmfDigit,
            onReceiveCallInfo: didReceiveCallInfo,
            onHandleOnAnotherDevice: didHandleOnAnotherDevice,
            onAudioDeviceChange: didAudioDeviceChange
        }
    
  • Khi tạo/trả lời cuộc gọi thành công, cuộc gọi sẽ đi qua rất nhiều trạng thái như là: calling, ringing, answered, ended, busy. Mỗi lần trạng thái của cuộc gọi thay đổi, bạn sẽ nhận được event onChangeSignalingState.

  • Khi media stream của cuộc gọi đã kết nối hoặc mất kết nối, bạn sẽ nhận được event onChangeMediaState.

  • Khi cuộc gọi được xử lý trên thiết bị khác, bạn sẽ nhận được event onHandleOnAnotherDevice.

Tạo cuộc gọi đi

  1. Tạo một call object và đưa tới màn hình cuộc gọi.

    
    const makeCall = () => {
    
        navigation.navigate('Call', {
    
            clientId: client.current.getId(),
    
            callObj: {
                from: userId,
                to: toUserID,
                isVideoCall: true,
                videoResolution: 'NORMAL'
            }
        });
    }
    
  2. Bắt đầu cuộc gọi ở màn hình call

    
    useEffect(() => {
    
        if (route.params.callObj) {
    
            call.current.makeCall(JSON.stringify(route.params.callObj), (status, code, message, callId) =>{
                console.log('makeCall', status, code, message);
                setCallId(callId)
            })
        }
    
    })
    

Trả lời cuộc gọi

  1. Bạn sẽ nhận được event onIncomingCall2 từ eventHandlers của StringeeClient đưa object nhận được tới màn hình call

    
    const callIncomingCall2 = (data) => {
    
        console.log("onIncomingCall2", data);
    
        navigation.navigate('Call', { incomingCall: data, clientId: client.current.getId() })
    }
    
  2. Ở màn hình call thực hiện khởi tạo cuộc gọi

    
    useEffect(() => {
        if (route.params.incomingCall) {
            call.current.initAnswer(route.params.incomingCall.callId, (status, code, message) => {
                console.log('initAnswer', status, code, message);
                setCallId(route.params.incomingCall.callId);
            })
        }
    })
    
  3. Tiếp nhận hoặc từ chối cuộc gọi

    
    // trả lời cuộc gọi
    
    call.current.answer(callId, (status, code, message) => {
        if (status) {
            setCallState(CallState.CALLING)
        } else {
            console.log('answer', status, code, message);
            navigation.goBack();
        }
    })
    
    // từ chối cuộc gọi
    
    call.current.reject(callId, (status, code, message) => {
    
        navigation.goBack()
    
        console.log('reject', status, code, message);
    
    })
    

Hiển thị video

stringee-react-native cung cấp component StringeeVideoView để hiển thị video.

    {remoteStream && <StringeeVideoView
        style={styles.remoteView}
        callId={callId}
        local={false}
    />}

      

    {localStream && <StringeeVideoView
        callId={callId}
        local={true}
        style={styles.localView}
    />}

Ngừng cuộc gọi

Ngừng cuộc gọi và giải phóng tài nguyên của cuộc gọi:

```
call.current.hangup(callId, (status, code, message) => {
    console.log('hangup', status, code, message);
    navigation.goBack()
})

```

Chạy app

Bây giờ ứng dụng của bạn có thể chạy được trên thiết bị. Bạn có thể tham khảo sample phiên bản đầy đủ ở đây: https://github.com/stringeecom/react-native-samples

Xem thêm: Hướng dẫn xây dựng ứng dụng gọi video 1-1 trên nền tảng Android với Stringee Call API

Xem thêm: Hướng dẫn viết ứng dụng gọi video 1-1 trên nền tảng iOS với Stringee Call API