需要源码请点赞关注收藏后评论区留言私信~~~

虽然手机出现许多年了,它具备的功能也越来越丰富,但是最基本的通话功能几乎没有变化。从前使用固定电话的时候,通话就是听声音;如今使用最新的智能手机,通话仍旧是听声音。 只闻其声不见其人的状况持续了好多年,既然手机自带的通话功能不支持视频画面,只好通过App自身实现了,比如微信就支持视频通话功能。通话双方一边对话,一边在手机屏幕上看着对方,感觉就像面对面交谈那般亲切。

一、需求描述

视频通话的请求方点击视频通话菜单项,接收方会自动打开等待通话界面。

接收方点击接听按钮,表示同意视频通话,之后双方的微信都切到接通了的视频通话界面。

任何一方点击挂断按钮,都将结束视频通话过程。

二、功能分析

视频童话不但要实时传输语音,还要实时传输画面,这对即时性要求很高,从用户界面到后台服务,视频通话主要集成了以下技术

(1)模糊位图:等待接听界面的背景可使用对方的模糊头像。

(2)音频管理器:按下音量加减键可以调节通话音量。

(3)Socket通信:与拨号事件有关的信令管理,需要采取Socket通信与后端服务器交互。

(4)移动数据格式JSON:客户端与服务器之间传输信令,需要把信令内容封装为JSON格式。 (5)实时音视频:开源库WebRTC适用于一对一的视频传输。

下面介绍代码模块之间的关系

(1)ContactListActivity.java:这是联系人的列表界面。

可以分解为下列三类操作

1:分别侦听好友上线和好友下线时间,在好友上线时将他加入联系人列表,在好友下线时将他从联系人列表移除
2:点击某位好友的头像,确认将要与其视频通话后打开视频通话等待界面

3:未在视频通话时需要侦听好友通话事件  一旦收到某位好友的通话请求就立即跳到等待接听界面

(2)ContactVideoActivity.java:这是视频通话的预览界面,发起方与接收方通用。

(3)服务端HttpServer模块中的VideoChatServer.java:处理Socket通信后端的信令消息传输。

视频通话的发起方与接收方的通话处理有所不同 主要区别如下

1:发起方发起通话请求之后需要侦听对方的接听事件,只有对方接受请求同意接听才能调用createOffer方法为其创建音视频供应

2:接收方只要按下接听按钮就表示同意通话请求,那么在收到对方的媒体能力时就应该调用createAnswer方法为其创建音视频答复

三、效果分析

联系人列表如下

四、代码

部分代码如下 全部代码请点赞关注收藏后评论区留言私信~~~

package com.example.live;import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;import com.example.live.adapter.EntityListAdapter;
import com.example.live.bean.EntityInfo;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import io.socket.client.Socket;public class ContactListActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {private final static String TAG = "ContactListActivity";private EntityListAdapter mAdapter; // 联系人的列表适配器private Map<String, EntityInfo> mContactMap = new HashMap<>(); // 联系人的名称映射private List<EntityInfo> mContactList = new ArrayList<>(); // 联系人列表private Socket mSocket; // 声明一个套接字对象private String mSelfName; // 我的昵称@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_contact_list);initView(); // 初始化视图initSocket(); // 初始化套接字}// 初始化视图private void initView() {TextView tv_title = findViewById(R.id.tv_title);tv_title.setText("联系人列表");findViewById(R.id.iv_back).setOnClickListener(v -> finish());ListView lv_contact = findViewById(R.id.lv_contact);mAdapter = new EntityListAdapter(this, mContactList);lv_contact.setAdapter(mAdapter);lv_contact.setOnItemClickListener(this);}// 初始化套接字private void initSocket() {mSelfName = getIntent().getStringExtra("self_name");Log.d(TAG , "initSocket "+mSelfName);mSocket = MainApplication.getInstance().getSocket();mSocket.connect(); // 建立Socket连接// 开始监听好友上线事件mSocket.on("friend_online", (args) -> {String friend_name = (String) args[0];if (friend_name != null) {// 把刚上线的好友加入联系人列表mContactMap.put(friend_name, new EntityInfo(friend_name, "好友"));mContactList.clear();mContactList.addAll(mContactMap.values());runOnUiThread(() -> mAdapter.notifyDataSetChanged());}});// 开始监听好友下线事件mSocket.on("friend_offline", (args) -> {String friend_name = (String) args[0];if (friend_name != null) {mContactMap.remove(friend_name); // 从联系人列表移除已下线的好友mContactList.clear();mContactList.addAll(mContactMap.values());runOnUiThread(() -> mAdapter.notifyDataSetChanged());}});// 开始监听好友通话事件mSocket.on("friend_converse", (args) -> {String friend_name = (String) args[0];// 接收到好友的通话请求,于是跳到视频通话页面Intent intent = new Intent(this, ContactVideoActivity.class);intent.putExtra("self_name", mSelfName); // 我的昵称intent.putExtra("friend_name", friend_name); // 好友昵称intent.putExtra("is_offer", false); // 是否为发起方startActivity(intent);});mSocket.emit("self_online", mSelfName); // 通知服务器“我已上线”}@Overrideprotected void onDestroy() {super.onDestroy();if (mSocket.connected()) { // 已经连上Socket服务器mSocket.emit("self_offline", mSelfName); // 通知服务器“我已下线”mSocket.off("friend_online"); // 取消监听好友上线事件mSocket.off("friend_offline"); // 取消监听好友下线事件mSocket.off("friend_converse"); // 取消监听好友通话事件mSocket.disconnect(); // 断开Socket连接}}@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {EntityInfo friend = mContactList.get(position);AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setMessage(String.format("你是否要跟%s视频通话?", friend.name));builder.setPositiveButton("是", (dialog, which) -> {// 想跟好友通话,就打开视频通话页面Intent intent = new Intent(this, ContactVideoActivity.class);intent.putExtra("self_name", mSelfName); // 我的昵称intent.putExtra("friend_name", friend.name); // 好友昵称intent.putExtra("is_offer", true); // 是否为发起方startActivity(intent);});builder.setNegativeButton("否", null);builder.create().show();}@Overrideprotected void onRestart() {super.onRestart();Toast.makeText(this, "视频通话已结束", Toast.LENGTH_SHORT).show();}
}

创作不易 觉得有帮助请点赞关注收藏~~~

【Android App】实战项目之仿微信的视频通话(附源码和演示 超详细必看)相关推荐

  1. 【Android App】实战项目之仿拼多多的直播带货(附源码和演示 超详细必看)

    需要源码请点赞关注收藏后评论区留言私信~~~ 近年来电商业态发生了不小的改变,传统的电商平台把商品分门别类,配上精美的图文说明供消费者挑选,新潮的电商平台则请来明星网红,开启直播秀向广大粉丝推销商品, ...

  2. 【Android App】给三维的地球仪贴上动物贴纸实战(附源码和演示 超详细必看)

    需要源码和图片集请点赞关注收藏后评论区留言~~~ 一.纹理贴图 给三维物体穿衣服的动作,通常叫做给三维图形贴图,更专业地说叫纹理渲染. 渲染纹理的过程主要由三大项操作组成,分别说明如下: (1)启用纹 ...

  3. 【Android App】检查手机连接WiFi信息以及扫描周围WiFi的讲解及实战(附源码和演示 超详细必看)

    需要全部代码请点赞关注收藏后评论区留言私信~~~ 一.检查是否连接WiFi以及输出WiFi信息 传统的定位方式不适用于室内的垂直定位,原因如下: (1)卫星定位要求没有障碍物遮挡,它在户外比较精准,在 ...

  4. 【Android App】二维码的讲解及生成属于自己的二维码实战(附源码和演示 超详细必看)

    需要全部代码请点赞关注收藏后评论区留言~~~ 一.二维码基本内容介绍 条形码只能表达十几位数字编码,无法表示更复杂的数据. 二维码在二维方格上描出一个个黑点,从而表达更丰富的信息. 二维码早已在手机A ...

  5. 【Keras+计算机视觉+Tensorflow】OCR文字识别实战(附源码和数据集 超详细必看)

    需要源码和数据集请点赞关注收藏后评论区留言私信~~~ 一.OCR文字识别简介 利用计算机自动识别字符的技术,是模式识别应用的一个重要领域.人们在生产和生活中,要处理大量的文字.报表和文本.为了减轻人们 ...

  6. 【Android App】实战项目之仿微信的附近的人(附源码和演示 超详细)

    需要全部源码请点赞关注收藏后评论区留言私信~~~ 艺术家常说"距离产生美",其实距离近才是优势,谁不希望自己的工作事少钱多离家近呢?不光是工作,像租房买房.恋爱交友,大家都希望找个 ...

  7. 【Android App】物联网实战项目之自动驾驶的智能小车(附源码和演示 超详细)

    需要源码请点赞关注收藏后评论区留言私信~~~~ 当今社会正在步入一个万物互联的时代,它的技术基石主要来自5G.物联网和人工智能. 三者融合产生了许多新产品,其中最璀璨的当数自动驾驶的电动车:它汇聚了最 ...

  8. 【Android App】利用自带的人脸检测器和OpenCV检测人脸讲解及实战(附源码和演示 超详细)

    需要源码请点赞关注收藏后评论区留言私信~~~~ 一.利用人脸检测器识别人脸 对于简单的人脸识别操作,Android已经提供了专门的识别工具,名叫人脸检测器FaceDetector,部分常用方法如下 F ...

  9. 【Android App】人脸识别中扫描识别二维码实战解析(附源码和演示 超详细)

    需要源码请点赞关注收藏后评论区留言私信~~~ 一.扫描识别二维码 不仅可以利用zxing库生成二维码,同样利用zxing库可以扫描二维码并解析得到原始文本,此时除了给build.gradle添加如下一 ...

最新文章

  1. 使tomcat和lighttpd使用service启停
  2. Linux进入单用户模式(passwd root修改密码)
  3. eval?python顺序列表模拟栈实现计算器
  4. 合并外部知识库-学习资料
  5. html全局浮窗,Html 实现浮动窗口
  6. 百度阿里网易大疆等大小厂前端校招面筋 | 掘金技术征文
  7. python从键盘获取数学表达式字符串_python – 数学表达式中String类型的字符串操作...
  8. Python(六):dict、set
  9. 路飞学城之 luffy (2 )
  10. 【Qbot】1.ChatGPT简介与Q群机器人部署教程
  11. GB28181国标平台接入摄像头、NVR录像机通道数位0没有通道的处理方式
  12. 从零开始(温故而知新)
  13. PostgreSQL JDBC 驱动程序版本和JDK关系及下载地址
  14. mc服务器怎么修改浮空字,如何制作悬浮字?我的世界教程 | 我的世界 | MC世界侠...
  15. 计算机视觉(相机标定)-1.1-针孔摄像机透镜
  16. Vue install 失败的一些解决办法
  17. 思科vPC (Virtual Por Channel)
  18. google.cn首页换成了中国四大发明
  19. 如何高效实现多窗口卖票
  20. IEEE Transactions on Intelligent Transportation Systems投稿经验分享

热门文章

  1. python表情符号编码大全_python玩转emoji ?
  2. PaddleWeekly | 支持GPU加速!这款硬字幕提取神器超好用
  3. 数字图像处理课程(作业+实验+大作业)相关文章 传送门
  4. 关于分布式存储,这是你应该知道的(图文详解)
  5. 答复:我不会OOO,仍然可以XXX
  6. 各种音视频编解码学习详解之 编解码学习笔记(八):Real系列
  7. 候鸟防关联浏览器原理
  8. 想考hcip华为认证,网络工程师方向的考的内容是哪三门?
  9. 华为G700升级鸿蒙,华为g700刷recovery的方法(联通版)
  10. MF_RC522及S50卡学习