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

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

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

虽然手机出现许多年了,它具备的功能也越来越丰富,但是最基本的通话功能几乎没有变化。从前使用固定电话的时候,通话就是听声音;如今使用最新的智能手机,通话仍旧是听声音。 只闻其声不见其人的状况持续了好多年,既然手机自带的通话功能不支持视频画面,只好通过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; // 我的昵称
    @Override
    protected 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); // 通知服务器“我已上线”
    }
    @Override
    protected 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连接
        }
    }
    @Override
    public 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();
    }
    @Override
    protected void onRestart() {
        super.onRestart();
        Toast.makeText(this, "视频通话已结束", Toast.LENGTH_SHORT).show();
    }
}

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

相关文章
|
XML Java Android开发
微信虚拟视频插件安卓,微信虚拟相机替换拍照,java源码分享
完整的相机应用项目包含三个主要文件:主活动实现、布局文件和清单文件。代码实现了相机预览、
|
12月前
|
缓存 小程序 开发工具
最新原创uniapp+vue3仿微信界面聊天app系统
最新原创研发uniapp+vue3实战跨端仿微信App界面聊天程序。支持运行到H5+小程序+APP端。
477 6
最新原创uniapp+vue3仿微信界面聊天app系统
|
10月前
|
人工智能 小程序 搜索推荐
【一步步开发AI运动APP】十二、自定义扩展新运动项目2
本文介绍如何基于uni-app运动识别插件实现“双手并举”自定义扩展运动,涵盖动作拆解、姿态检测规则构建及运动分析器代码实现,助力开发者打造个性化AI运动APP。
|
存储 Java PHP
轻量化短视频电商直播带货APP源码全解析:核心功能与设计流程​
在电商直播热潮下,开发专属直播带货APP成为抢占市场关键。本文详解原生开发轻量化APP的核心功能与全流程设计,涵盖用户登录、商品浏览、直播互动、购物车、订单及售后功能,并介绍安卓端Java、苹果端Object-C、后台PHP的技术实现,助力打造高效优质的直播电商平台。
|
存储 人工智能 Android开发
为什么微信发送的APP安装不了,.apk转化为.apk.1
微信发送的APP文件常被改为.apk.1格式导致无法安装,推荐使用夸克或QQ浏览器解决。
2155 14
|
11月前
|
存储 小程序 Java
热门小程序源码合集:微信抖音小程序源码支持PHP/Java/uni-app完整项目实践指南
小程序已成为企业获客与开发者创业的重要载体。本文详解PHP、Java、uni-app三大技术栈在电商、工具、服务类小程序中的源码应用,提供从开发到部署的全流程指南,并分享选型避坑与商业化落地策略,助力开发者高效构建稳定可扩展项目。
|
人工智能 小程序 前端开发
小程序、网站 vs. APP:成本差异究竟在哪里?技术栈如何决定项目上限?优雅草卓伊凡
小程序、网站 vs. APP:成本差异究竟在哪里?技术栈如何决定项目上限?优雅草卓伊凡
871 0
小程序、网站 vs. APP:成本差异究竟在哪里?技术栈如何决定项目上限?优雅草卓伊凡
|
消息中间件 缓存 小程序
婚恋交友相亲公众号app小程序系统源码「脱单神器」婚恋平台全套代码 - 支持快速二次开发
这是一套基于SpringBoot + Vue3开发的婚恋交友系统,支持微信公众号、Uniapp小程序和APP端。系统包含实名认证、智能匹配、视频相亲、会员体系等功能,适用于婚恋社交平台和相亲交友应用。后端采用SpringBoot 3.x与MyBatis-Plus,前端使用Vue3与Uniapp,支持快速部署和二次开发。适合技术团队或有经验的个人创业者使用。
986 8
|
小程序 Java 关系型数据库
圈子系统公众号app小程序系统源码圈子系统带即时通讯 多级圈子系统源码 兴趣小组系统开源 私密圈子系统代码 会员制社区系统
本圈子系统解决方案提供即时通讯、多级圈子、兴趣小组、私密社区及会员制管理功能。支持开源与商业方案,推荐ThinkSNS+、EasyClub及OpenFire等系统,并提供前后端技术选型建议,助力快速搭建社交平台。
657 0
不封号的外卖抢单神器,美团抢单辅助器app,autojs版本源码
这个代码提供了基础框架,包含主循环、订单检测和点击功能。实际使用时需要根据美团骑手AP

热门文章

最新文章