7 . 如何进行视频电话

项目地址:https://git.oschina.net/qin_xiao_yu/Linphone.git


1 . 绪论

  • 本月还有3篇微博需要更新,否则就持之以恒的徽章就没啦,前一段时间都在忙各种事情没有时间更新博客,现在阶段性的不太忙了,补上这月个剩下的3篇,关于Linphone的内容,各位有想了解的,想好题目,在留言你提问,如果我能解答我就出个博客专门说一下,解答不了的也没辙了。

  • 本博客的大部分内容是为了记录项目中的一些和业务不太相关,但是和对应技术比较相关的东西,一方面为了以后能回顾一下,另一方面也能帮其它同学解决点实际问题。

- 整体思路

  • 服务器支持。
  • 终端设置。
  • 拨出视频电话。
  • 接听视频电话
  • 显示双向视频。

- 分步实现

3.1 服务器支持

  • 我使用的服务器是Freeswitch,需要在服务器上设置视频对应的编码方式。
  • 已下配置来自于《FreeSWITCH权威指南》: 
    • freeswitch模式支持语音通话,因此默认的通话皆为语音通话,如果需要支持视频通话,只需要在配置文件中增加想关的视频编解码就可以了。
    • freeswitch目前支持的编解码方式有:H261、H263、H264、VP8等。
    • freeswitch只支持视频透传,所以必须电话两侧的终端都为同一种编码方式。
    • 在conf/vars.xml中修改如下
    <X-PRE-PROCESS cmd="set" data="global_codec_prefs=G722,PCMU,PCMA,GSM"/><X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=PCMU,PCMA,GSM"/>改为<X-PRE-PROCESS cmd="set" data="global_codec_prefs=G722,PCMU,PCMA,GSM,H263,H264,VP8"/><X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=PCMU,PCMA,GSM,H263,H264,VP8"/>
  • 重启服务器,使配置生效

    • 使用sofia status profile internal 查看视频编码方式是否成功配置。

3.2 终端设置

  1. 前提为设备成功启动Linphone service,此时LinphoneCore,LinphoneManager,LinphonePreferences 都已经正常启动。
  2. 使用如下代码配置终端参数
/*获得LinphonePreferences的实体类,这个包含了Linphone的所有参数配置*/
LinphonePreferences mPrefs = LinphonePreferences.instance();
/*设置自动接听视频通话的请求,也就是说只要是视频通话来了,直接就接通,不用按键确定,这是我们的业务流,不用理会*/
mPrefs.setAutomaticallyAcceptVideoRequests(true);
/*设置初始话视频电话,设置了这个你拨号的时候就默认为使用视频发起通话了*/
mPrefs.setInitiateVideoCall(true);
/*这是允许视频通话,这个选了false就彻底不能接听或者拨打视频电话了*/
mPrefs.enableVideo(true);
setCodecMime();/*设置音频的codec,这里我只选择了打开VP8的codec。H264因为硬件平台的原因,无法正常使用decode所以放弃了
*/
private void setCodecMime()
{LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();for (final PayloadType pt : lc.getVideoCodecs()){debug.i("setCodecMime = " + pt.getMime());if (!pt.getMime().equals("VP8")){try{debug.i("disable codec " + pt.getMime());LinphoneManager.getLcIfManagerNotDestroyedOrNull().enablePayloadType(pt, false);}catch (LinphoneCoreException e){Log.e(e);}}}
}

3.3 拨出视频电话

  • 实际上在完成了上述设置后,若对方也打开了视频通话的选项,并且选定了编码方式为VP8后,只要调用拨号的API即可实现拨出视频电话。
  • 使用如下方法即可实现上述功能。
public static void dialNumber(String number)
{if (LinphoneManager.getLc().getCallsNb() == 0){debug.i("dialNumber(" + number + ");");LinphoneManager.getInstance().newOutgoingCall("电话号码", "显示姓名");}
}

3.4 接听视频电话

  • 在通话到来时,也就是在callState变成IncomingReceived时,调用answer方法即可实现视频接听。
public static void answer(Context mContext)
{if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null){List<LinphoneCall> calls = LinphoneUtils.getLinphoneCalls(LinphoneManager.getLc());for (LinphoneCall call : calls){if (State.IncomingReceived == call.getState()){mCall = call;break;}}}if (State.IncomingReceived != mCall.getState()) return;if (mContext.getPackageManager().checkPermission(Manifest.permission.RECORD_AUDIO, mContext.getPackageName()) == PackageManager.PERMISSION_GRANTED || LinphonePreferences.instance().audioPermAsked()){// startActivity(new Intent(LinphoneActivity.instance(),// CallIncomingActivity.class));debug.i("CallIncomingActivity.class");}else{debug.i("checkAndRequestAudioPermission(true);");checkAndRequestAudioPermission(mContext, true);}LinphoneCallParams params = LinphoneManager.getLc().createCallParams(mCall);boolean isLowBandwidthConnection = !LinphoneUtils.isHighBandwidthConnection(LinphoneService.instance().getApplicationContext());if (params != null){params.enableLowBandwidth(isLowBandwidthConnection);}else{Log.e("Could not create call params for call");}if (params == null || !LinphoneManager.getInstance().acceptCallWithParams(mCall, params)){// the above method takes care of Samsung Galaxy S// Toast.makeText(this, R.string.couldnt_accept_call,// Toast.LENGTH_LONG).show();}else{// if (!LinphoneActivity.isInstanciated()) {// return;// }final LinphoneCallParams remoteParams = mCall.getRemoteParams();if (remoteParams != null && remoteParams.getVideoEnabled() && LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests()){// LinphoneActivity.instance().startVideoActivity(mCall);debug.i("LinphoneActivity.instance().startVideoActivity(mCall)");switchVideo(true);}else{debug.i("LinphoneActivity.instance().startIncallActivity(mCall);");// LinphoneActivity.instance().startIncallActivity(mCall);switchVideo(false);}}
}private static void switchVideo(final boolean displayVideo)
{debug.i("switchVideo");final LinphoneCall call = LinphoneManager.getLc().getCurrentCall();if (call == null){return;}// Check if the call is not terminatedif (call.getState() == State.CallEnd || call.getState() == State.CallReleased) return;if (!displayVideo){// showAudioView();}else{if (!call.getRemoteParams().isLowBandwidthEnabled()){LinphoneManager.getInstance().addVideo();debug.i("addVideo");// if (videoCallFragment == null ||// !videoCallFragment.isVisible())// {// showVideoView();// }}else{// displayCustomToast(getString(R.string.error_low_bandwidth),// Toast.LENGTH_LONG);}}
}
  • 上面的代码已经屏蔽了所有的页面跳转的代码。其间比较关键的是在switchVideo方法中的如下部分
if (!call.getRemoteParams().isLowBandwidthEnabled())
{LinphoneManager.getInstance().addVideo();debug.i("addVideo");// if (videoCallFragment == null ||// !videoCallFragment.isVisible())// {// showVideoView();// }
}
  • 这里在查看了当前带宽时候能够支持视频通话后,执行LinphoneManager.getInstance().addVideo();添加了视频。

3.4 显示双向视频

  • 在主程序界面放置一个fragment控件。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@+drawable/background"android:gravity="center_horizontal"tools:context="com.sxkeda.launcher.MainActivity"tools:ignore="MergeRootFrame" ><LinearLayoutandroid:id="@+id/fragmentContainer2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_alignParentRight="true"android:layout_below="@+id/titleBar"android:layout_toRightOf="@+id/left_icon_panel"android:orientation="vertical" ></LinearLayout>
</RelativeLayout>   

  • 在电话状态LinphoneCall.State 等于 Connected(接通)和OutgoingProgress(拨出电话)时。在主程序中替换fragment组件。
if (state == LinphoneCall.State.Connected)
{LinphoneCall mCall = LinphoneManager.getLc().getCurrentCall();/*在接通状态下,必须查看来电的远程参数,确定其带有视频通话的参数才打开视频通话,否则只进行语音通话*/final LinphoneCallParams remoteParams = mCall.getRemoteParams();debug.i("remoteParams.getVideoEnabled() = "+remoteParams.getVideoEnabled());if (remoteParams != null && remoteParams.getVideoEnabled()){changeFragmentToVideoCall();} else{changeFragmentToAudioCall();}
}
if (state == LinphoneCall.State.OutgoingProgress)
{debug.i("to CallVideoFragment");if (Business.getInstance().isCurrentCallVideo()){changeFragmentToVideoCall();}else{changeFragmentToAudioCall();}
}               
private void changeFragmentToVideoCall()
{CallVideoFragment videoCallFragment = new CallVideoFragment();FragmentTransaction transaction = getFragmentManager().beginTransaction();transaction.replace(R.id.fragmentContainer2, videoCallFragment);transaction.commit();
}
  • 在切换视频的时候,我们使用了一个fragment为CallVideoFragment,这个组件是Linphone本身就有的组件,我们直接哪来就用了。这个组件自动的将本地摄像头的头像投射到了小窗口,对方视频的图像经过界面投射到了大窗口上。
  • 就是这个文件:

4. 谢谢阅读

智能会议系统(18)---如何进行视频电话相关推荐

  1. AIBlockChain:“知名博主独家讲授”人工智能创新应用竞赛【精选实战作品】之《基于计算机视觉、自然语言处理、区块链和爬虫技术的智能会议系统》软件系统案例的界面简介、功能介绍分享之二、会中智能

    AI&BlockChain:"知名博主独家讲授"人工智能创新应用竞赛[精选实战作品]之<基于计算机视觉.自然语言处理.区块链和爬虫技术的智能会议系统>软件系统案 ...

  2. AIBlockChain:“知名博主独家讲授”人工智能创新应用竞赛【精选实战作品】之《基于计算机视觉、自然语言处理、区块链和爬虫技术的智能会议系统》软件系统案例的界面简介、功能介绍分享之一、会前智能

    AI&BlockChain:"知名博主独家讲授"人工智能创新应用竞赛[精选实战作品]之<基于计算机视觉.自然语言处理.区块链和爬虫技术的智能会议系统>软件系统案 ...

  3. AIBlockChain:“知名博主独家讲授”人工智能创新应用竞赛【精选实战作品】之《基于计算机视觉、自然语言处理、区块链和爬虫技术的智能会议系统》软件系统案例的界面简介、功能介绍分享之总篇

    AI&BlockChain:"知名博主独家讲授"人工智能创新应用竞赛[精选实战作品]之<基于计算机视觉.自然语言处理.区块链和爬虫技术的智能会议系统>软件系统案 ...

  4. AIBlockChain:“知名博主独家讲授”人工智能创新应用竞赛【精选实战作品】之《基于计算机视觉、自然语言处理、区块链和爬虫技术的智能会议系统》软件系统案例的界面简介、功能介绍分享之四、数据挖掘

    AI&BlockChain:"知名博主独家讲授"人工智能创新应用竞赛[精选实战作品]之<基于计算机视觉.自然语言处理.区块链和爬虫技术的智能会议系统>软件系统案 ...

  5. 鲸会务一站式智能会议系统帮助主办方实现数字化会议管理

    在数字时代对算力需求大幅增长的信创产业环境下,为更好地共筑信创产业生态圈,6月17日,以"智算新生态,五舟创未来"为主题的2022广电五舟信创生态赋能大会在广州盛大召开,鲸会务一站 ...

  6. 智能会议系统(6)---高效视频会议系统

    高效视频会议系统 大多数白领都有开视频会议的经历,而且很多人也曾经被开视频会议之前复杂的准备工作难倒.有没有像手机App那样简单的视频会议系统,轻松点几下就可以召开视频会议呢? 英特尔给出的答案是:有 ...

  7. AI 智能会议系统(36)——-外呼失败场景如何处理?

    外呼失败场景如何处理? 产品经理就业班,12周特训,测.练.实战,22位导师全程带班,200+名企内推,保障就业!了解详情 AI技术革新了外呼行业的工作模式,机器人外呼替代了人工坐席,极大的提高了外呼 ...

  8. 智能会议系统(10)---WebRtc在H5视频聊天

    基于WebRtc在H5视频聊天.视频教学.视频会议.视频直播.白板互动低延时方案 随移动互联应用加快,4G,5G网络上马,低延时网络视频应改越来越走近生活,在教学,会议,在线医疗,招聘交友及时视频要求 ...

  9. 智能会议系统(8)---流媒体中用到的几个协议简介

    流媒体中用到的几个协议简介 1. 由来 电视会议是近年兴起的一种通信方式.随着技术的进步,电视会议的发展可以划分为4个浪潮: 第1个浪潮是拨号群组电视会议系统: 第2个浪潮是基于ISDN的电视会议系统 ...

最新文章

  1. 青龙面板修改端口教程避开5700更安全
  2. 二叉查找树 Java实现
  3. 基于词典的逆向最大匹配中文分词算法,更好实现中英文数字混合分词
  4. centos7下配置golang1.7.1环境(自己做测试了)
  5. php loop 语法,Loop - SegmentFault 思否
  6. Windows Server 2008 R2安装Zune 4.0解决方法
  7. 【内核模块auth_rpcgss】netns引用计数泄露导致容器弹性网卡残留
  8. 中心极限定理_High Dimensional Probability(1) 中心极限定理
  9. mysql导入.sql文件及常用命令_MySQL导入.sql文件及常用命令
  10. java 调用groovy_Java调用Groovy脚本
  11. Android中Json数据解析
  12. oracle如何判断奇数偶数_堆垒素数论之旅(1):奇数哥德巴赫猜想
  13. Java相关资源下载路径
  14. 现阶段选择ArcMap还是ArcGIS Pro
  15. 《软件过程管理》 第七章 软件过程的质量管理
  16. oracle修改表的owner,Oracle中改变表的Owner和tablespace
  17. 通过ipsw控制固定端口的网速
  18. 学习:名词定义 大数据 Saas Paas Iaas
  19. 计算机在随机抽样上的应用,数理统计学中随机抽样的应用研究
  20. 如何对待每逢佳节被逼婚

热门文章

  1. 基于modelsim的十个Verilog入门试验程序(2)(JK触发器+环形计数器)—程序+测试代码+波形+结果分析
  2. 【FPGA】——Verilog语法
  3. STM32学习——USART收发数据
  4. linux中同步例子(完成量completion)
  5. linux ntp server配置文件,Linux下配置ntp server
  6. mysql有dataguard吗_Oracle查看是否搭建DataGuard
  7. mysql 设置utf8mb4_mysql配置utf8_mb4
  8. C51单片机————汇编与C语言
  9. Java面试之ArrayList为什么线程不安全?
  10. IO、NIO、AIO