中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

無錫網(wǎng)站建設(shè)技術(shù)搜索引擎營銷分類

無錫網(wǎng)站建設(shè)技術(shù),搜索引擎營銷分類,重慶網(wǎng)站快速排名優(yōu)化,如何選擇大連網(wǎng)站建設(shè)1.Linphone簡介 1.1 簡介 LinPhone是一個遵循GPL協(xié)議的開源網(wǎng)絡(luò)電話或者IP語音電話(VOIP)系統(tǒng),其主要如下。使用linphone,開發(fā)者可以在互聯(lián)網(wǎng)上隨意的通信,包括語音、視頻、即時文本消息。linphone使用SIP協(xié)議&#…

?

1.Linphone簡介

1.1 簡介

LinPhone是一個遵循GPL協(xié)議的開源網(wǎng)絡(luò)電話或者IP語音電話(VOIP)系統(tǒng),其主要如下。使用linphone,開發(fā)者可以在互聯(lián)網(wǎng)上隨意的通信,包括語音、視頻、即時文本消息。linphone使用SIP協(xié)議,是一個標(biāo)準(zhǔn)的開源網(wǎng)絡(luò)電話系統(tǒng),能將linphone與任何基于SIP的VoIP運(yùn)營商連接起來,包括我們自己開發(fā)的免費(fèi)的基于SIP的Audio/Video服務(wù)器。

LinPhone是一款自由軟件(或者開源軟件),你可以隨意的下載和在LinPhone的基礎(chǔ)上二次開發(fā)。LinPhone是可用于Linux, Windows, MacOSX 桌面電腦以及Android, iPhone, Blackberry移動設(shè)備。

學(xué)習(xí)LinPhone的源碼,開源從以下幾個部分著手: Java層框架實(shí)現(xiàn)的SIP三層協(xié)議架構(gòu): 傳輸層,事務(wù)層,語法編解碼層; linphone動態(tài)庫C源碼實(shí)現(xiàn)的SIP功能: 注冊,請求,請求超時,邀請會話,掛斷電話,邀請視頻,收發(fā)短信... linphone動態(tài)庫C源碼實(shí)現(xiàn)的音視頻編解碼功能; Android平臺上的音視頻捕獲,播放功能;

1.2 基本使用

如果是Android系統(tǒng)用戶,可以從谷歌應(yīng)用商店安裝或者從這個鏈接下載Linphone 。安裝完成后,點(diǎn)擊左上角的菜單按鈕,選擇進(jìn)入助手界面。在助手界面,可以設(shè)定SIP賬戶或者Linphone賬號,如下圖:

2.基于linphone android sdk開發(fā)linphone

引入sdk依賴?

dependencies {
? ? //linphone
? ? debugImplementation "org.linphone:linphone-sdk-android-debug:5.0.0"
? ? releaseImplementation "org.linphone:linphone-sdk-android:5.0.0"
}?

為了方便調(diào)用,我們需要對Linphone進(jìn)行簡單的封裝。首先,按照官方文檔的介紹,創(chuàng)建一個CoreManager類,此類是sdk里面的管理類,用來控制來電鈴聲和啟動CoreService,無特殊需求不需調(diào)用。需要注意的是,啟動來電鈴聲需要導(dǎo)入media包,否則不會有來電鈴聲,如下

implementation 'androidx.media:media:1.2.0'

基本代碼開發(fā):?

package com.matt.linphonelibrary.coreimport android.annotation.SuppressLint
import android.content.Context
import android.os.Handler
import android.os.Looper
import android.telephony.PhoneStateListener
import android.telephony.TelephonyManager
import android.util.Log
import android.view.TextureView
import com.matt.linphonelibrary.R
import com.matt.linphonelibrary.callback.PhoneCallback
import com.matt.linphonelibrary.callback.RegistrationCallback
import com.matt.linphonelibrary.utils.AudioRouteUtils
import com.matt.linphonelibrary.utils.LinphoneUtils
import com.matt.linphonelibrary.utils.VideoZoomHelper
import org.linphone.core.*
import java.io.File
import java.util.*class LinphoneManager private constructor(private val context: Context) {private val TAG = javaClass.simpleNameprivate var core: Coreprivate var corePreferences: CorePreferencesprivate var coreIsStart = falsevar registrationCallback: RegistrationCallback? = nullvar phoneCallback: PhoneCallback? = nullinit {//日志收集Factory.instance().setLogCollectionPath(context.filesDir.absolutePath)Factory.instance().enableLogCollection(LogCollectionState.Enabled)corePreferences = CorePreferences(context)corePreferences.copyAssetsFromPackage()val config = Factory.instance().createConfigWithFactory(corePreferences.configPath,corePreferences.factoryConfigPath)corePreferences.config = configval appName = context.getString(R.string.app_name)Factory.instance().setDebugMode(corePreferences.debugLogs, appName)core = Factory.instance().createCoreWithConfig(config, context)}private var previousCallState = Call.State.Idleprivate val coreListener = object : CoreListenerStub() {override fun onGlobalStateChanged(core: Core, state: GlobalState?, message: String) {if (state === GlobalState.On) {}}//登錄狀態(tài)回調(diào)override fun onRegistrationStateChanged(core: Core,cfg: ProxyConfig,state: RegistrationState,message: String) {when (state) {RegistrationState.None -> registrationCallback?.registrationNone()RegistrationState.Progress -> registrationCallback?.registrationProgress()RegistrationState.Ok -> registrationCallback?.registrationOk()RegistrationState.Cleared -> registrationCallback?.registrationCleared()RegistrationState.Failed -> registrationCallback?.registrationFailed()}}//電話狀態(tài)回調(diào)override fun onCallStateChanged(core: Core,call: Call,state: Call.State,message: String) {Log.i(TAG, "[Context] Call state changed [$state]")when (state) {Call.State.IncomingReceived, Call.State.IncomingEarlyMedia -> {if (gsmCallActive) {Log.w(TAG,"[Context] Refusing the call with reason busy because a GSM call is active")call.decline(Reason.Busy)return}phoneCallback?.incomingCall(call)gsmCallActive = true//自動接聽if (corePreferences.autoAnswerEnabled) {val autoAnswerDelay = corePreferences.autoAnswerDelayif (autoAnswerDelay == 0) {Log.w(TAG, "[Context] Auto answering call immediately")answerCall(call)} else {Log.i(TAG,"[Context] Scheduling auto answering in $autoAnswerDelay milliseconds")val mainThreadHandler = Handler(Looper.getMainLooper())mainThreadHandler.postDelayed({Log.w(TAG, "[Context] Auto answering call")answerCall(call)}, autoAnswerDelay.toLong())}}}Call.State.OutgoingInit -> {phoneCallback?.outgoingInit(call)gsmCallActive = true}Call.State.OutgoingProgress -> {if (core.callsNb == 1 && corePreferences.routeAudioToBluetoothIfAvailable) {AudioRouteUtils.routeAudioToBluetooth(core, call)}}Call.State.Connected -> phoneCallback?.callConnected(call)Call.State.StreamsRunning -> {// Do not automatically route audio to bluetooth after first callif (core.callsNb == 1) {// Only try to route bluetooth / headphone / headset when the call is in StreamsRunning for the first timeif (previousCallState == Call.State.Connected) {Log.i(TAG,"[Context] First call going into StreamsRunning state for the first time, trying to route audio to headset or bluetooth if available")if (AudioRouteUtils.isHeadsetAudioRouteAvailable(core)) {AudioRouteUtils.routeAudioToHeadset(core, call)} else if (corePreferences.routeAudioToBluetoothIfAvailable && AudioRouteUtils.isBluetoothAudioRouteAvailable(core)) {AudioRouteUtils.routeAudioToBluetooth(core, call)}}}if (corePreferences.routeAudioToSpeakerWhenVideoIsEnabled && call.currentParams.videoEnabled()) {// Do not turn speaker on when video is enabled if headset or bluetooth is usedif (!AudioRouteUtils.isHeadsetAudioRouteAvailable(core) &&!AudioRouteUtils.isBluetoothAudioRouteCurrentlyUsed(core, call)) {Log.i(TAG,"[Context] Video enabled and no wired headset not bluetooth in use, routing audio to speaker")AudioRouteUtils.routeAudioToSpeaker(core, call)}}}Call.State.End, Call.State.Released, Call.State.Error -> {if (core.callsNb == 0) {when (state) {Call.State.End -> phoneCallback?.callEnd(call)Call.State.Released -> phoneCallback?.callReleased(call)Call.State.Error -> {val id = when (call.errorInfo.reason) {Reason.Busy -> R.string.call_error_user_busyReason.IOError -> R.string.call_error_io_errorReason.NotAcceptable -> R.string.call_error_incompatible_media_paramsReason.NotFound -> R.string.call_error_user_not_foundReason.Forbidden -> R.string.call_error_forbiddenelse -> R.string.call_error_unknown}phoneCallback?.error(context.getString(id))}}gsmCallActive = false}}}previousCallState = state}}/*** 啟動linphone*/fun start() {if (!coreIsStart) {coreIsStart = trueLog.i(TAG, "[Context] Starting")core.addListener(coreListener)core.start()initLinphone()val telephonyManager =context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManagerLog.i(TAG, "[Context] Registering phone state listener")telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE)}}/*** 停止linphone*/fun stop() {coreIsStart = falseval telephonyManager =context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManagerLog.i(TAG, "[Context] Unregistering phone state listener")telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE)core.removeListener(coreListener)core.stop()}/*** 注冊到服務(wù)器** @param username     賬號名* @param password      密碼* @param domain     IP地址:端口號*/fun createProxyConfig(username: String,password: String,domain: String,type: TransportType? = TransportType.Udp) {core.clearProxyConfig()val accountCreator = core.createAccountCreator(corePreferences.xmlRpcServerUrl)accountCreator.language = Locale.getDefault().languageaccountCreator.reset()accountCreator.username = usernameaccountCreator.password = passwordaccountCreator.domain = domainaccountCreator.displayName = usernameaccountCreator.transport = typeaccountCreator.createProxyConfig()}/*** 取消注冊*/fun removeInvalidProxyConfig() {core.clearProxyConfig()}/*** 撥打電話* @param to String* @param isVideoCall Boolean*/fun startCall(to: String, isVideoCall: Boolean) {try {val addressToCall = core.interpretUrl(to)addressToCall?.displayName = toval params = core.createCallParams(null)//啟用通話錄音
//            params?.recordFile = LinphoneUtils.getRecordingFilePathForAddress(context, addressToCall!!)//啟動低寬帶模式if (LinphoneUtils.checkIfNetworkHasLowBandwidth(context)) {Log.w(TAG, "[Context] Enabling low bandwidth mode!")params?.enableLowBandwidth(true)}if (isVideoCall) {params?.enableVideo(true)core.enableVideoCapture(true)core.enableVideoDisplay(true)} else {params?.enableVideo(false)}if (params != null) {core.inviteAddressWithParams(addressToCall!!, params)} else {core.inviteAddress(addressToCall!!)}} catch (e: Exception) {e.printStackTrace()}}/*** 接聽來電**/fun answerCall(call: Call) {Log.i(TAG, "[Context] Answering call $call")val params = core.createCallParams(call)//啟用通話錄音
//        params?.recordFile = LinphoneUtils.getRecordingFilePathForAddress(context, call.remoteAddress)if (LinphoneUtils.checkIfNetworkHasLowBandwidth(context)) {Log.w(TAG, "[Context] Enabling low bandwidth mode!")params?.enableLowBandwidth(true)}params?.enableVideo(isVideoCall(call))call.acceptWithParams(params)}/*** 謝絕電話* @param call Call*/fun declineCall(call: Call) {val voiceMailUri = corePreferences.voiceMailUriif (voiceMailUri != null && corePreferences.redirectDeclinedCallToVoiceMail) {val voiceMailAddress = core.interpretUrl(voiceMailUri)if (voiceMailAddress != null) {Log.i(TAG, "[Context] Redirecting call $call to voice mail URI: $voiceMailUri")call.redirectTo(voiceMailAddress)}} else {Log.i(TAG, "[Context] Declining call $call")call.decline(Reason.Declined)}}/*** 掛斷電話*/fun terminateCall(call: Call) {Log.i(TAG, "[Context] Terminating call $call")call.terminate()}fun micEnabled() = core.micEnabled()fun speakerEnabled() = core.outputAudioDevice?.type == AudioDevice.Type.Speaker/*** 啟動麥克風(fēng)* @param micEnabled Boolean*/fun enableMic(micEnabled: Boolean) {core.enableMic(micEnabled)}/*** 揚(yáng)聲器或聽筒* @param SpeakerEnabled Boolean*/fun enableSpeaker(SpeakerEnabled: Boolean) {if (SpeakerEnabled) {AudioRouteUtils.routeAudioToEarpiece(core)} else {AudioRouteUtils.routeAudioToSpeaker(core)}}/*** 是否是視頻電話* @return Boolean*/fun isVideoCall(call: Call): Boolean {val remoteParams = call.remoteParamsreturn remoteParams != null && remoteParams.videoEnabled()}/*** 設(shè)置視頻界面* @param videoRendering TextureView 對方界面* @param videoPreview CaptureTextureView 自己界面*/fun setVideoWindowId(videoRendering: TextureView, videoPreview: TextureView) {core.nativeVideoWindowId = videoRenderingcore.nativePreviewWindowId = videoPreview}/*** 設(shè)置視頻電話可縮放* @param context Context* @param videoRendering TextureView*/fun setVideoZoom(context: Context, videoRendering: TextureView) {VideoZoomHelper(context, videoRendering, core)}fun switchCamera() {val currentDevice = core.videoDeviceLog.i(TAG, "[Context] Current camera device is $currentDevice")for (camera in core.videoDevicesList) {if (camera != currentDevice && camera != "StaticImage: Static picture") {Log.i(TAG, "[Context] New camera device will be $camera")core.videoDevice = camerabreak}}//        val conference = core.conference
//        if (conference == null || !conference.isIn) {
//            val call = core.currentCall
//            if (call == null) {
//                Log.w(TAG, "[Context] Switching camera while not in call")
//                return
//            }
//            call.update(null)
//        }}//初始化一些操作private fun initLinphone() {configureCore()initUserCertificates()}private fun configureCore() {// 來電鈴聲core.isNativeRingingEnabled = false// 來電振動core.isVibrationOnIncomingCallEnabled = truecore.enableEchoCancellation(true) //回聲消除core.enableAdaptiveRateControl(true) //自適應(yīng)碼率控制}private var gsmCallActive = falseprivate val phoneStateListener = object : PhoneStateListener() {override fun onCallStateChanged(state: Int, phoneNumber: String?) {gsmCallActive = when (state) {TelephonyManager.CALL_STATE_OFFHOOK -> {Log.i(TAG, "[Context] Phone state is off hook")true}TelephonyManager.CALL_STATE_RINGING -> {Log.i(TAG, "[Context] Phone state is ringing")true}TelephonyManager.CALL_STATE_IDLE -> {Log.i(TAG, "[Context] Phone state is idle")false}else -> {Log.i(TAG, "[Context] Phone state is unexpected: $state")false}}}}//設(shè)置存放用戶x509證書的目錄路徑private fun initUserCertificates() {val userCertsPath = corePreferences!!.userCertificatesPathval f = File(userCertsPath)if (!f.exists()) {if (!f.mkdir()) {Log.e(TAG, "[Context] $userCertsPath can't be created.")}}core.userCertificatesPath = userCertsPath}companion object {// For Singleton instantiation@SuppressLint("StaticFieldLeak")@Volatileprivate var instance: LinphoneManager? = nullfun getInstance(context: Context) =instance ?: synchronized(this) {instance ?: LinphoneManager(context).also { instance = it }}}}

http://www.risenshineclean.com/news/53642.html

相關(guān)文章:

  • 成都個人學(xué)做網(wǎng)站如何推廣小程序平臺
  • 海淀做網(wǎng)站好的公司google免費(fèi)入口
  • 自己如何做團(tuán)購網(wǎng)站信息流廣告素材網(wǎng)站
  • 網(wǎng)站制作服務(wù)合同寧波seo整站優(yōu)化軟件
  • wordpress做論壇網(wǎng)站全域seo
  • 有經(jīng)驗的順德網(wǎng)站建設(shè)成人職業(yè)技能培訓(xùn)班
  • 大網(wǎng)站制作公司成都培訓(xùn)機(jī)構(gòu)排名前十
  • 萊蕪網(wǎng)站建設(shè)電話長沙網(wǎng)站制作策劃
  • 貴州省住房和城鄉(xiāng)建設(shè)廳網(wǎng)站官網(wǎng)企業(yè)文化
  • 南通做外貿(mào)的公司網(wǎng)站seo怎么弄
  • 介紹好的電影網(wǎng)站模板下載優(yōu)化排名seo
  • 做網(wǎng)站換服務(wù)器怎么整免費(fèi)個人主頁網(wǎng)站
  • 北京國互網(wǎng)網(wǎng)站建設(shè)電話標(biāo)題seo是什么意思
  • 山東今天新冠疫情最新消息新鄉(xiāng)seo網(wǎng)絡(luò)推廣費(fèi)用
  • 推廣網(wǎng)站的軟件網(wǎng)頁查詢
  • 杭州的網(wǎng)站建設(shè)公司有哪些百度搜索熱度指數(shù)
  • 響應(yīng)式網(wǎng)站開發(fā)步驟商鋪營銷推廣方案
  • 公司做網(wǎng)站費(fèi)用外貿(mào)網(wǎng)站建站和推廣
  • 什么是網(wǎng)站微商城的建設(shè)seo建站教學(xué)
  • 騰訊官方網(wǎng)站網(wǎng)絡(luò)營銷成功案例
  • 北京旅游設(shè)計網(wǎng)站建設(shè)網(wǎng)站優(yōu)化推廣seo公司
  • 商城手機(jī)網(wǎng)站制作口碑營銷有哪些
  • 網(wǎng)站建設(shè)銀行卡死期存款提前取出百度學(xué)術(shù)論文查重免費(fèi)檢測
  • 深圳網(wǎng)站制作公司訊息站長統(tǒng)計幸福寶下載
  • 萊蕪高新區(qū)管委會網(wǎng)站求職seo服務(wù)
  • 蘇州企業(yè)網(wǎng)站優(yōu)化成都新一輪疫情
  • 網(wǎng)站建設(shè)費(fèi)賬務(wù)處理英雄聯(lián)盟世界排名
  • 企業(yè)網(wǎng)站建站寧波seo公司
  • 做蛋糕招聘網(wǎng)站域名申請
  • 響應(yīng)式網(wǎng)站建設(shè)平臺鄭州網(wǎng)絡(luò)推廣平臺