工作笔记:linphone-sip视频通话使用说明

linphone-sip通话使用说明

aar版本:liblinphone-sdk-v4.aar

官方Demo:Files · master · BC / public / linphone-android · GitLab:

注:记得把资源文件一起拷贝进去
在这里插入图片描述
运行效果
在这里插入图片描述
在这里插入图片描述

添加依赖

repositories {
    flatDir {
        dirs 'libs' // aar用到
    }
}
dependencies {
    api fileTree(dir: 'libs', include: '*.jar')
    implementation(name: 'liblinphone-sdk-v4', ext: 'aar')
}

添加权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.linphone">

    <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.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.CAMERA" />
    <!--悬浮窗权限-->
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <!--唤醒权限-->
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <!--免提权限-->
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Linphone">

        <activity android:name=".SipMainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".VideoActivity"/>
        <service android:name=".LinphoneMiniManager"/>
    </application>

</manifest>

使用示例

SipMainActivity

package com.example.linphone;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.example.linphone.tools.ActivityInterface;

import org.linphone.core.Call;
import org.linphone.core.TransportType;

/**
 * author : 吴明辉
 * e-mail : 1412378121@qq.com
 * date   : 2022/3/2611:23
 * git    : https://gitee.com/yunianvh
 * desc   : AccountBuilder接电话时用到
 */
public class SipMainActivity extends AppCompatActivity {
    private static final String TAG = SipMainActivity.class.getSimpleName();
    private TextView id_text_status, id_text_code, id_call_stateinfo, id_text_version;
    private EditText id_etext_regtext, id_etext_dail, id_etext_regpwd, id_etext_ipport, id_etext_type;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sipmain);
        id_etext_regtext = (EditText) this.findViewById(R.id.id_etext_regtext);
        id_etext_dail = (EditText) this.findViewById(R.id.id_etext_dail);
        id_etext_regpwd = (EditText) this.findViewById(R.id.id_etext_regpwd);
        id_text_status = (TextView) this.findViewById(R.id.id_text_status);
        id_call_stateinfo = (TextView) this.findViewById(R.id.id_call_stateinfo);
        id_etext_ipport = (EditText) this.findViewById(R.id.id_etext_ipport);
        id_text_version = (TextView) this.findViewById(R.id.id_text_version);
        id_text_code = (TextView) findViewById(R.id.id_text_code);
        id_etext_type = (EditText) findViewById(R.id.id_etext_type);
        //权限

        //开始启动linphone服务
        startService(new Intent(this, LinphoneMiniManager.class));

        //延时2秒启动监听,避免服务未启动设置监听方法出现异常
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                LinphoneMiniManager.getInstance().setActivityInterfaceListener(new ActivityInterface() {
                    @Override
                    public void onLinphone(String cmd, String msg) {
                        Log.e(TAG, "onLinphone监听返回 cmd-->" + cmd + " msg-->" + msg);
                        switch (cmd) {
                            case "reg_state":
                                id_text_status.setText(msg);
                                break;
                            case "show_code":
                                id_text_code.setText(msg);
                                break;
                            case "show_callinfo":
                                id_call_stateinfo.setText(msg);
                                if (msg.startsWith("Incoming CallSession"))
                                    LinphoneMiniManager.getInstance().liLinJie();
                                break;
                            case "show_version":
                                id_text_version.setText(msg);
                                break;
                            default:
                                break;
                        }
                    }
                });
            }
        }, 2000);
    }

    /**
     * 注册
     *
     * @param view
     */
    public void reg(View view) {
        if (!LinphoneMiniManager.isReady()) {
            Toast.makeText(SipMainActivity.this, "Service没准备好", Toast.LENGTH_SHORT).show();
            return;
        }
        LinphoneMiniManager instance = LinphoneMiniManager.getInstance();
        String[] split = id_etext_ipport.getText().toString().split(":");
        String host = split[0], port = split[1];
        try {
            String password = id_etext_regpwd.getText().toString();
            String type = id_etext_type.getText().toString();
            TransportType transport = TransportType.Udp;
            if (type.indexOf("tcp") != -1) {
                transport = TransportType.Tcp;
                Toast.makeText(SipMainActivity.this, "tcp注册", Toast.LENGTH_SHORT).show();
            } else if (type.indexOf("tls") != -1) {
                transport = TransportType.Tls;
                Toast.makeText(SipMainActivity.this, "tls注册", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(SipMainActivity.this, "udp注册", Toast.LENGTH_SHORT).show();
            }
            instance.lilin_reg(host + ":" + port, id_etext_regtext.getText().toString(), password, transport);
            // instance.lilin_reg("192.168.10.146","1004","12345","5090");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 语音拨打
     *
     * @param view
     */
    public void boda(View view) {
        String[] split = id_etext_ipport.getText().toString().split(":");
        String host = split[0], port = split[1];
        Log.e(TAG, "语音拨打");
        if (!LinphoneMiniManager.isReady()) {
            Toast.makeText(SipMainActivity.this, "Service没准备好", Toast.LENGTH_SHORT).show();
            return;
        }
        LinphoneMiniManager instance = LinphoneMiniManager.getInstance();
        instance.lilin_call(id_etext_dail.getText().toString(), id_etext_ipport.getText().toString(), false);
    }

    /**
     * 挂断电话
     *
     * @param view
     */
    public void guaduan(View view) {
        if (!LinphoneMiniManager.isReady()) {
            Toast.makeText(SipMainActivity.this, "Service没准备好", Toast.LENGTH_SHORT).show();
            return;
        }
        LinphoneMiniManager instance = LinphoneMiniManager.getInstance();
        instance.hangUp();
    }

    /**
     * 接电话
     *
     * @param view
     */
    public void jie(View view) {
        if (!LinphoneMiniManager.isReady()) {
            Toast.makeText(SipMainActivity.this, "Service没准备好", Toast.LENGTH_SHORT).show();
            return;
        }
        LinphoneMiniManager instance = LinphoneMiniManager.getInstance();
        instance.liLinJie();
        Call ccall = instance.getLC().getCurrentCall();
        if (ccall != null && ccall.getRemoteParams().videoEnabled()) {
            startActivity(new Intent(SipMainActivity.this, VideoActivity.class));
        }
    }

    /**
     * 视频拨打
     *
     * @param view
     */
    public void videoda(View view) {
        // Toast.makeText(SipMainActivity.this,"无视频",Toast.LENGTH_SHORT    ).show();
        if (!LinphoneMiniManager.isReady()) {
            Toast.makeText(SipMainActivity.this, "Service没准备好", Toast.LENGTH_SHORT).show();
            return;
        }
        LinphoneMiniManager instance = LinphoneMiniManager.getInstance();
        instance.lilin_call(id_etext_dail.getText().toString(), id_etext_ipport.getText().toString(), true);
        startActivity(new Intent(SipMainActivity.this, VideoActivity.class));
    }

    /**
     * 是否扩音
     *
     * @param view
     */
    public void kuoyin(View view) {
        if (!LinphoneMiniManager.isReady()) {
            Toast.makeText(SipMainActivity.this, "Service没准备好", Toast.LENGTH_SHORT).show();
            return;
        }
        LinphoneMiniManager instance = LinphoneMiniManager.getInstance();
        instance.lilin_enkuo();

    }

    public void senddtmf(View view) {
        LinphoneMiniManager instance = LinphoneMiniManager.getInstance();
        instance.getLC().setUseInfoForDtmf(true);
        Call currentCall = instance.getLC().getCurrentCall();
        if (currentCall != null) {
            char a = 2;
            currentCall.sendDtmf(a);
            Toast.makeText(SipMainActivity.this, "senddtmf", Toast.LENGTH_SHORT).show();
        }
    }

}

VideoActivity

package com.example.linphone;

import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceView;

import androidx.appcompat.app.AppCompatActivity;

import org.linphone.core.Call;
import org.linphone.core.Core;
import org.linphone.core.VideoDefinition;
import org.linphone.mediastream.video.AndroidVideoWindowImpl;

/**
 * author : 吴明辉
 * e-mail : 1412378121@qq.com
 * date   : 2022/3/2611:23
 * git    : https://gitee.com/yunianvh
 * desc   : AccountBuilder接电话时用到
 */
public class VideoActivity extends AppCompatActivity {

    private static final String TAG = VideoActivity.class.getSimpleName();
    private SurfaceView mVideoView, mCaptureView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_sip_video);

        init();

        new AndroidVideoWindowImpl(mVideoView, mCaptureView, new AndroidVideoWindowImpl.VideoWindowListener() {
            @Override
            public void onVideoRenderingSurfaceReady(AndroidVideoWindowImpl vw, SurfaceView surface) {
                Log.e(TAG, "onVideoRenderingSurfaceReady---video_ready");
                mVideoView = surface;
                LinphoneMiniManager.getInstance().getLC().setNativeVideoWindowId(vw);
            }

            @Override
            public void onVideoRenderingSurfaceDestroyed(AndroidVideoWindowImpl vw) {

            }

            @Override
            public void onVideoPreviewSurfaceReady(AndroidVideoWindowImpl vw, SurfaceView surface) {
                Log.e(TAG, "onVideoPreviewSurfaceReady-----");
                mCaptureView = surface;
                LinphoneMiniManager.getInstance().getLC().setNativePreviewWindowId(mCaptureView);
                //resizePreview();
            }

            @Override
            public void onVideoPreviewSurfaceDestroyed(AndroidVideoWindowImpl vw) {

            }
        });

        resizePreview();
    }

    private void resizePreview() {
        Core lc = LinphoneMiniManager.getInstance().getLC();
        if (lc.getCallsNb() > 0) {
            Call call = lc.getCurrentCall();
            if (call == null) {
                call = lc.getCalls()[0];
            }
            if (call == null) {
                return;
            }

            DisplayMetrics metrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(metrics);
            int screenHeight = metrics.heightPixels;
            int maxHeight = screenHeight / 4; // Let's take at most 1/4 of the screen for the camera preview

            VideoDefinition videoSize = call.getCurrentParams().getSentVideoDefinition(); // It already takes care of rotation
            if (videoSize.getWidth() == 0 || videoSize.getHeight() == 0) {
                Log.w(TAG, "Couldn't get sent video definition, using default video definition");
                videoSize = lc.getPreferredVideoDefinition();
            }
            int width = videoSize.getWidth();
            int height = videoSize.getHeight();
            Log.d(TAG, "Video height is " + height + ", width is " + width);
            width = width * maxHeight / height;
            height = maxHeight;
            if (mVideoView == null) {
                Log.e(TAG, "mCaptureView is null !");
                return;
            }
            mVideoView.getHolder().setFixedSize(metrics.widthPixels, metrics.heightPixels);
            Log.d(TAG, "Video preview size set to " + width + "x" + height);
        }
    }

    private void init() {
        mVideoView = (SurfaceView) findViewById(R.id.videoSurface);
        mCaptureView = (SurfaceView) findViewById(R.id.videoCaptureSurface);
    }
}

核心代码

package com.example.linphone;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.os.HandlerThread;
import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import com.example.linphone.tools.AccountBuilder;
import com.example.linphone.tools.ActivityInterface;
import com.example.linphone.tools.LinphoneMiniUtils;

import org.linphone.core.AVPFMode;
import org.linphone.core.Address;
import org.linphone.core.AuthInfo;
import org.linphone.core.AuthMethod;
import org.linphone.core.Call;
import org.linphone.core.CallLog;
import org.linphone.core.CallParams;
import org.linphone.core.CallStats;
import org.linphone.core.ChatMessage;
import org.linphone.core.ChatRoom;
import org.linphone.core.Config;
import org.linphone.core.ConfiguringState;
import org.linphone.core.Content;
import org.linphone.core.Core;
import org.linphone.core.CoreException;
import org.linphone.core.CoreListener;
import org.linphone.core.EcCalibratorStatus;
import org.linphone.core.Event;
import org.linphone.core.Factory;
import org.linphone.core.Friend;
import org.linphone.core.FriendList;
import org.linphone.core.GlobalState;
import org.linphone.core.InfoMessage;
import org.linphone.core.NatPolicy;
import org.linphone.core.PayloadType;
import org.linphone.core.PresenceModel;
import org.linphone.core.ProxyConfig;
import org.linphone.core.PublishState;
import org.linphone.core.RegistrationState;
import org.linphone.core.SubscriptionState;
import org.linphone.core.TransportType;
import org.linphone.core.Transports;
import org.linphone.core.VersionUpdateCheckResult;
import org.linphone.core.VideoDefinition;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
 * author : 吴明辉
 * e-mail : 1412378121@qq.com
 * date   : 2022/3/2611:23
 * git    : https://gitee.com/yunianvh
 * desc   : AccountBuilder接电话时用到
 */
public class LinphoneMiniManager extends Service implements CoreListener {
    public static final String TAG = LinphoneMiniManager.class.getSimpleName();
    private static LinphoneMiniManager mInstance;
    private Context mContext;
    private Core mLinPhoneCore;
    private ScheduledThreadPoolExecutor poolExecutor;
    private ScheduledFuture<?> future;
    private Factory lcFactory;
    private AudioManager mAudioManager;
    private ActivityInterface listener;

    public static boolean isReady() {
        return mInstance != null;
    }

    public static LinphoneMiniManager getInstance() {
        return mInstance;
    }

    public Core getLC() {
        return mLinPhoneCore;
    }

    /**
     * 设置回调监听,把注册,童话等状态回调出去
     *
     * @param listener
     */
    public void setActivityInterfaceListener(ActivityInterface listener) {
        this.listener = listener;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = this;
        lcFactory = Factory.instance();
        lcFactory.setDebugMode(true, "lilinaini 34>>");
        try {
            String basePath = mContext.getFilesDir().getAbsolutePath();
            copyAssetsFromPackage(basePath);
            mLinPhoneCore = lcFactory.createCore(basePath + "/.linphonerc", basePath + "/linphonerc", mContext);
            mLinPhoneCore.addListener(this);
          /*  getLC().setPreferredFramerate(15);
            getLC().setVideoPreset("custom");
            getLC().setUploadBandwidth(0);
            getLC().setDownloadBandwidth(0);*/
            startIterate();
            setUserAgent();
            mInstance = this;
            mLinPhoneCore.setNetworkReachable(true); // Let's assume it's true
            mAudioManager = ((AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE));
            mAudioManager.setSpeakerphoneOn(true);
            String[] dnsServer = new String[]{"8.8.8.8"};
            mLinPhoneCore.setDnsServers(dnsServer);
            mLinPhoneCore.enableAdaptiveRateControl(false);
            mLinPhoneCore.start();
            setSipPort(-1);

            String preferredVideoSize = getPreferredVideoSize();
            Log.e(TAG, preferredVideoSize);
            //getConfig().setString("video", "size", "qcif");
            //setPreferredVideoSize("cif");

            //初始化完成把linphone版本通过回调接口返回回去
            if (listener != null) listener.onLinphone("show_version", mLinPhoneCore.getVersion());
        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG, "LinphoneMiniManager创建错误");
        }
    }

    /**
     * 设置sip端口号
     *
     * @param port
     */
    public void setSipPort(int port) {
        Transports transports = getLC().getTransports();
        transports.setUdpPort(port);
        transports.setTcpPort(port);
        transports.setTlsPort(-1);
        getLC().setTransports(transports);
    }

    /**
     * 注册删除时候调用
     *
     * @param host
     * @param username
     * @param password
     */
    public void setTurn(String host, String username, String password) {
        if (getLC() == null) {
            return;
        }
        NatPolicy nat = getOrCreateNatPolicy();
        nat.setStunServer(host);
        nat.enableIce(true);
        nat.enableTurn(true);
        AuthInfo authInfo = getLC().findAuthInfo(null, nat.getStunServerUsername(), null);

        if (authInfo != null) {
            Log.e(TAG, "方式1");
            AuthInfo cloneAuthInfo = authInfo.clone();
            getLC().removeAuthInfo(authInfo);
            cloneAuthInfo.setUsername(username);
            cloneAuthInfo.setUserid(username);
            cloneAuthInfo.setPassword(password);
            getLC().addAuthInfo(cloneAuthInfo);
        } else {
            Log.e(TAG, "方式2");
            authInfo = Factory.instance().createAuthInfo(username, username, password, null, null, null);
            getLC().addAuthInfo(authInfo);
        }
        nat.setStunServerUsername(username);
        getLC().setNatPolicy(nat);
    }


    private NatPolicy getOrCreateNatPolicy() {
        if (mLinPhoneCore == null) {
            return null;
        }
        NatPolicy nat = mLinPhoneCore.getNatPolicy();
        if (nat == null) {
            nat = mLinPhoneCore.createNatPolicy();
        }
        return nat;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        endIterate();
    }

    private int iterateCount = 0;

    private final int iterateTime = 20;

    /**
     * 循环检查linphone状态
     */
    private void startIterate() {
        poolExecutor = new ScheduledThreadPoolExecutor(1, r -> {
            Thread thread = new Thread(r);
            thread.setName("linPhone保活线程" + System.currentTimeMillis());
            return thread;
        });
        future = poolExecutor.scheduleAtFixedRate(() -> {
            try {
                if (mLinPhoneCore != null) {
                    iterateCount++;
                    if (iterateCount % (10 * 1000 / iterateTime) == 0) {
                        iterateCount = 0;
                        ProxyConfig defaultProxyConfig = mLinPhoneCore.getDefaultProxyConfig();
                        if (defaultProxyConfig != null) {
                            RegistrationState state = defaultProxyConfig.getState();
                            if (state != null) {
                                Log.e(TAG, Thread.currentThread().getName() + "状态:" + state.toString() + ">>" + state.toInt());
                            }
                        }
                    }
                    mLinPhoneCore.iterate();
                }
            } catch (Exception e) {
                Log.e(TAG, Thread.currentThread().getName() + "异常,重启线程");
                endIterate();
                startIterate();
            }
        }, 0, iterateTime, TimeUnit.MILLISECONDS);
    }

    /**
     * 销毁循环检查linphone状态的线程
     */
    private void endIterate() {
        if (future != null) {
            future.cancel(true);
            future = null;
        }
        if (poolExecutor != null) {
            poolExecutor.shutdown();
            poolExecutor = null;
        }
    }

    /**
     * 把资源文件复制到指定目录
     *
     * @param basePath
     */
    private void copyAssetsFromPackage(final String basePath) {
        threadPool.execute(() -> {
            try {
                LinphoneMiniUtils.copyIfNotExist(mContext, R.raw.linphonerc_default, basePath + "/.linphonerc");
                LinphoneMiniUtils.copyFromPackage(mContext, R.raw.linphonerc_factory, new File(basePath + "/linphonerc").getName());
                LinphoneMiniUtils.copyIfNotExist(mContext, R.raw.lpconfig, basePath + "/lpconfig.xsd");
                LinphoneMiniUtils.copyFromPackage(mContext, R.raw.assistant_create, new File(basePath + "/assistant_create.rc").getName());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    /**
     * 设置用户代理
     */
    private void setUserAgent() {
        try {
            String versionName = mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionName;
            if (versionName == null) {
                versionName = String.valueOf(mContext.getPackageManager().getPackageInfo(mContext.getPackageName(), 0).versionCode);
            }
            mLinPhoneCore.setUserAgent("LinphoneMiniAndroid", versionName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * -------------------------------------------linphone监听 开始----------------------------------------------------------------------------------------------
     *
     * @param core
     * @param globalState
     * @param s
     */
    @Override
    public void onGlobalStateChanged(Core core, GlobalState globalState, String s) {
        Log.e(TAG, ">onGlobalStateChanged " + s);
    }

    @Override
    public void onRegistrationStateChanged(Core core, ProxyConfig proxyConfig, RegistrationState registrationState, String smessage) {
        Log.e(TAG, "注册状态 onRegistrationStateChanged-->" + smessage);

        //把注册状态通过回调接口返回回去
        if (listener != null) listener.onLinphone("reg_state", smessage);

        if (smessage.contains("successful")) {
            String str = "音频:\n";
            PayloadType[] audioCodecs = mLinPhoneCore.getAudioPayloadTypes();
            for (PayloadType payloadType : audioCodecs) {
                str += payloadType.getMimeType() + "-" + payloadType.getNormalBitrate() + "-" + payloadType.enabled() + "\n";
            }
            str += "\n视频:";
            for (PayloadType payloadType1 : mLinPhoneCore.getVideoPayloadTypes()) {
                // if(payloadType1.getMimeType().equalsIgnoreCase("VP8")) {payloadType1.enable(false);}
                str += payloadType1.getMimeType() + "" + payloadType1.enabled() + "\n";
            }

            //把注册成功后音视频信息返回回去
            if (listener != null) listener.onLinphone("show_code", str);
        }
    }

    @Override
    public void onCallStateChanged(Core core, Call call, Call.State state, String s) {
        Log.e(TAG, "呼叫状态 onCallStateChanged-->" + call.getRemoteAddress().getUsername() + "  >" + call.getRemoteAddressAsString() + "  >" + s);
        //过滤呼叫状态
        if (s.startsWith("Incoming CallSession") || s.startsWith("Call released") || "Connected".equals(s)) {
            //把呼叫状态返回回去
            if (listener != null) listener.onLinphone("show_callinfo", s);
        }
    }

    @Override
    public void onNotifyPresenceReceived(Core core, Friend friend) {

    }

    @Override
    public void onNotifyPresenceReceivedForUriOrTel(Core core, Friend friend, String s, PresenceModel presenceModel) {

    }

    @Override
    public void onNewSubscriptionRequested(Core core, Friend friend, String s) {

    }

    @Override
    public void onAuthenticationRequested(Core core, AuthInfo authInfo, AuthMethod authMethod) {

    }

    @Override
    public void onCallLogUpdated(Core core, CallLog callLog) {

    }

    @Override
    public void onMessageReceived(Core core, ChatRoom chatRoom, ChatMessage chatMessage) {

    }

    @Override
    public void onMessageReceivedUnableDecrypt(Core core, ChatRoom chatRoom, ChatMessage chatMessage) {

    }

    @Override
    public void onIsComposingReceived(Core core, ChatRoom chatRoom) {
        Log.e(TAG, ">onIsComposingReceived " + chatRoom.getSubject());
    }

    @Override
    public void onDtmfReceived(Core core, Call call, int i) {
        Log.e(TAG, ">onDtmfReceived " + i + "收到");
    }

    @Override
    public void onReferReceived(Core core, String s) {
        Log.e(TAG, ">onReferReceived " + s);
    }

    @Override
    public void onCallEncryptionChanged(Core core, Call call, boolean b, String s) {

    }

    @Override
    public void onTransferStateChanged(Core core, Call call, Call.State state) {

    }

    @Override
    public void onBuddyInfoUpdated(Core core, Friend friend) {

    }

    @Override
    public void onCallStatsUpdated(Core core, Call call, CallStats callStats) {
    }

    @Override
    public void onInfoReceived(Core core, Call call, InfoMessage infoMessage) {
        Log.e(TAG, ">onInfoReceived " + infoMessage.getContent().toString());
    }

    @Override
    public void onSubscriptionStateChanged(Core core, Event event, SubscriptionState subscriptionState) {

    }

    @Override
    public void onNotifyReceived(Core core, Event event, String s, Content content) {

    }

    @Override
    public void onSubscribeReceived(Core core, Event event, String s, Content content) {

    }

    @Override
    public void onPublishStateChanged(Core core, Event event, PublishState publishState) {
        Log.e(TAG, ">onInfoReceived " + publishState);
    }

    @Override
    public void onConfiguringStatus(Core core, ConfiguringState configuringState, String s) {
    }

    @Override
    public void onNetworkReachable(Core core, boolean b) {

    }

    @Override
    public void onLogCollectionUploadStateChanged(Core core, Core.LogCollectionUploadState logCollectionUploadState, String s) {

    }

    @Override
    public void onLogCollectionUploadProgressIndication(Core core, int i, int i1) {

    }

    @Override
    public void onFriendListCreated(Core core, FriendList friendList) {

    }

    @Override
    public void onFriendListRemoved(Core core, FriendList friendList) {

    }

    @Override
    public void onCallCreated(Core core, Call call) {
        Log.e(TAG, ">onCallCreated " + call + "" + call.getRemoteAddressAsString());
    }

    @Override
    public void onVersionUpdateCheckResultReceived(Core core, VersionUpdateCheckResult versionUpdateCheckResult, String s, String s1) {

    }

    @Override
    public void onChatRoomStateChanged(Core core, ChatRoom chatRoom, ChatRoom.State state) {

    }

    @Override
    public void onQrcodeFound(Core core, String s) {

    }

    @Override
    public void onEcCalibrationResult(Core core, EcCalibratorStatus ecCalibratorStatus, int i) {

    }

    @Override
    public void onEcCalibrationAudioInit(Core core) {

    }

    @Override
    public void onEcCalibrationAudioUninit(Core core) {

    }
    /**
     * -------------------------------------------linphone监听 结束----------------------------------------------------------------------------------------------
     */

    /**
     * -------------------------------------------linphone公开方法 开始----------------------------------------------------------------------------------------------
     * 注册
     *
     * @param host
     * @param username
     * @param password
     * @param transport
     * @throws Exception
     */
    public void lilin_reg(String host, String username, String password, TransportType transport) throws Exception {
        if (mLinPhoneCore == null) {
            return;
        }
        Log.e(TAG, "lilin_reg 开始注册-->host: " + host + " username-->" + username + " password-->" + password + " transport-->" + transport);
        for (ProxyConfig linphoneProxyConfig : mLinPhoneCore.getProxyConfigList()) {
            mLinPhoneCore.removeProxyConfig(linphoneProxyConfig);
        }
        for (AuthInfo x : mLinPhoneCore.getAuthInfoList()) {
            mLinPhoneCore.removeAuthInfo(x);
        }

        AccountBuilder builder = new AccountBuilder(mLinPhoneCore)
                .setUsername(username)
                .setDomain(host)
                .setHa1(null)
                .setUserid(username)
                .setDisplayName("")//显示名
                .setPassword(password);

        builder.setAvpfEnabled(false);

        String prefix = null;
        if (prefix != null) {
            builder.setPrefix(prefix);
        }
        String forcedProxy = "";//"39.108.0.211:11889";
        if (!TextUtils.isEmpty(forcedProxy)) {
            builder.setServerAddr(forcedProxy).setOutboundProxyEnabled(true);// .setAvpfRrInterval(5);
        }

        if (transport != null) {
            builder.setTransport(transport);
        }

        try {
            builder.saveNewAccount();
        } catch (CoreException e) {
            Log.e(TAG, ">tishi >>>>" + e.getMessage());
        }
    }

    /**
     * 初始化sip电话线程池
     */
    private final ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 10, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(1), new ThreadFactory() {
        @Override
        public Thread newThread(Runnable runnable) {
            Thread thread = new Thread(runnable);
            thread.setName("sip电话线程池");
            return thread;
        }
    });

    /**
     * 打电话
     *
     * @param username
     * @param host
     * @param isVideoCall
     */
    public void lilin_call(final String username, final String host, final boolean isVideoCall) {
        threadPool.execute(() -> {
            if (mLinPhoneCore == null) {
                return;
            }
            Log.e(TAG, "lilin_call打电话  username-->" + username + " host-->" + host + " isVideoCall-->" + isVideoCall);
            Address address = mLinPhoneCore.interpretUrl(username + "@" + host);
            address.setDisplayName(username);
            CallParams params = mLinPhoneCore.createCallParams(null);
            //params.enableLowBandwidth(true);
            //params.setAudioBandwidthLimit(0);
            params.enableVideo(isVideoCall);
            Call call = mLinPhoneCore.inviteAddressWithParams(address, params);
            if (call == null) {
                Log.e(TAG, "lilin error  Could not place call to " + username);
            }
        });
    }

    /**
     * 终止所有Calls
     */
    public void hangUp() {
        if (mLinPhoneCore == null) {
            return;
        }
        mLinPhoneCore.terminateAllCalls();
    }

    /**
     * 开启扩音或关闭
     */
    public void lilin_enkuo() {
        if (mAudioManager == null) {
            return;
        }
        mAudioManager.setSpeakerphoneOn(mAudioManager.isSpeakerphoneOn() ? false : true);
    }

    /**
     * 接电话
     */
    public void liLinJie() {
        threadPool.execute(() -> {
            if (mLinPhoneCore == null) return;
            Log.e(TAG, "liLinJie: 接电话");
            Call currentCall = mLinPhoneCore.getCurrentCall();
            if (currentCall != null) {
                CallParams params = mLinPhoneCore.createCallParams(currentCall);
                CallParams remoteParams = currentCall.getRemoteParams();
                if (remoteParams != null && remoteParams.videoEnabled()) {
                    params.enableVideo(false);
                    Log.e(Thread.currentThread().getName(), "视频通话  模式" + getLC().getVideoPreset() + "fps" + getLC().getPreferredFramerate() + "带宽" + getLC().getUploadBandwidth() + "分辨率" + getLC().getPreferredVideoDefinition().getHeight());
                } else {
                    Log.e(Thread.currentThread().getName(), "音频通话通话");
                }
                currentCall.acceptWithParams(params);
            }
        });
    }

    /**
     * 获取Config配置
     *
     * @return
     */
    public Config getConfig() {
        Core core = getLC();
        if (core != null) {
            return core.getConfig();
        }

        if (!LinphoneMiniManager.isReady()) {
            File linphonerc = new File(mContext.getFilesDir().getAbsolutePath() + "/.linphonerc");
            if (linphonerc.exists()) {
                return Factory.instance().createConfig(linphonerc.getAbsolutePath());
            } else if (mContext != null) {
                InputStream inputStream = mContext.getResources().openRawResource(R.raw.linphonerc_default);
                InputStreamReader inputreader = new InputStreamReader(inputStream);
                BufferedReader buffreader = new BufferedReader(inputreader);
                StringBuilder text = new StringBuilder();
                String line;
                try {
                    while ((line = buffreader.readLine()) != null) {
                        text.append(line);
                        text.append('\n');
                    }
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
                return Factory.instance().createConfigFromString(text.toString());
            }
        } else {
            return Factory.instance().createConfig(mContext.getFilesDir().getAbsolutePath() + "/.linphonerc");
        }
        return null;
    }

    public String getPreferredVideoSize() {
        return getConfig().getString("video", "size", "qvga");
    }

    public void setPreferredVideoSize(String preferredVideoSize) {
        if (getLC() == null) {
            return;
        }
        VideoDefinition preferredVideoDefinition = Factory.instance().createVideoDefinitionFromName(preferredVideoSize);
        getLC().setPreferredVideoDefinition(preferredVideoDefinition);
    }
    /**
     * -------------------------------------------linphone公开方法 结束----------------------------------------------------------------------------------------------
     */
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
用户点击 用户点击 linphone linphone linphone linphone 的图标后就开始了 的图标后就开始了 的图标后就开始了 的图标后就开始了 的图标后就开始了 linphone linphone linphone linphone 软件,这时 软件,这时 软件,这时 软件,这时 软件,这时 linphoneActivity linphoneActivity linphoneActivity linphoneActivity linphoneActivity linphoneActivity linphoneActivity开始运行,它 开始运行,它 开始运行,它 开始运行,它 使 linphoneService linphoneService linphoneService linphoneService linphoneServicelinphoneServicelinphoneService 开始,并做一些 开始,并做一些 开始,并做一些 开始,并做一些 linphone linphone linphone linphone 帐号密码的登录操作同时引导用户进行环境变 帐号密码的登录操作同时引导用户进行环境变 帐号密码的登录操作同时引导用户进行环境变 帐号密码的登录操作同时引导用户进行环境变 帐号密码的登录操作同时引导用户进行环境变 帐号密码的登录操作同时引导用户进行环境变 帐号密码的登录操作同时引导用户进行环境变 帐号密码的登录操作同时引导用户进行环境变 帐号密码的登录操作同时引导用户进行环境变 帐号密码的登录操作同时引导用户进行环境变 量的设置( 量的设置( LinphonePreferencesActivity LinphonePreferencesActivity LinphonePreferencesActivityLinphonePreferencesActivity LinphonePreferencesActivityLinphonePreferencesActivityLinphonePreferencesActivityLinphonePreferencesActivity LinphonePreferencesActivity LinphonePreferencesActivity LinphonePreferencesActivity LinphonePreferencesActivity)。 环境变量都储存在 环境变量都储存在 环境变量都储存在 环境变量都储存在 sharedPreferencessharedPreferences sharedPreferencessharedPreferences sharedPreferencessharedPreferencessharedPreferencessharedPreferences sharedPreferences 中,它是整个工程共享的一变量池。这些环境有 中,它是整个工程共享的一变量池。这些环境有 中,它是整个工程共享的一变量池。这些环境有 中,它是整个工程共享的一变量池。这些环境有 中,它是整个工程共享的一变量池。这些环境有 中,它是整个工程共享的一变量池。这些环境有 中,它是整个工程共享的一变量池。这些环境有 中,它是整个工程共享的一变量池。这些环境有 中,它是整个工程共享的一变量池。这些环境有 中,它是整个工程共享的一变量池。这些环境有 中,它是整个工程共享的一变量池。这些环境有 中,它是整个工程共享的一变量池。这些环境有 中,它是整个工程共享的一变量池。这些环境有 中,它是整个工程共享的一变量池。这些环境有 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自动启回校正网络 音频和视编码设置选择,帐号密服务器自

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

玉念聿辉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值