花了3个小时解决了和异地女朋友一起看电影的需求(内附源码)
一、这是一个悲伤的故事...
我是一名程序员,我和我的女友是异地恋,so sad!!!
一次视频时,她突然来了一句:“我们已经很久没有一起看电影了吧。。。。。。”
“呃。。。好像是”,毕竟离得那么远,一起看电影有点难啊。
女友“哦”了下,我们便陷入了沉默。
视频结束,心情有点忧伤。是啊,已经很久没有好好陪她了吧。
突然想到市面上有不少可以一起看电影的APP。找了下,确实不少,像微光之类的 APP 人气都很火。下载了一个,发现还是挺有意思的,确实能解决异地一起看电影的需求。
于是“啪”的一下,灵光一现,哄女友开心的方法有了,哦耶!!!我可以自己去实现一个 demo 呀!
作为一名优质的程序员,鉴于职业探索精神以及在 ZEGO 即构科技的从业经验,想到实现一个类似功能的 demo 还是很可以的。
说干就干,熬夜小 case,通宵搞出了demo,效果如下:
前面铺设了这么长,相信你们也不是来看我晒狗粮的(狗头保命)。那么现在就和我一起来看看我是怎么实现这个让女朋友欢心的“一起看电影”的功能吧,文章有点长,但是绝对很干货,大家可以耐心看完。
二、开发准备
在开始实现一起看电影的demo之前,我们需要做一些开发前的准备工作:
1、开发环境准备
首先第一步就是准备开发环境,需要确保开发环境满足以下要求:
Android Studio 2.1 或以上版本。
Android SDK 25、Android SDK Build-Tools 25.0.2、Android SDK Platform-Tools 25.x.x 或以上版本。
Android 4.1 或以上版本,且支持音视频的 Android 设备。
Android 设备已经连接到 Internet。
2、账户注册
开发环境搭建好之后,我们需要去 ZEGO 官网注册一个账户,进入管理控制台并创建应用、获取开发需要的 AppId 和 AppSign 。
三、 实现流程介绍
1、接口规范说明
首先分析 ZEGO
的 API
输入输出规范。根据 API
使用文档 来看,调用接口格式如下:
以创建 ZegoExpressEngine 单列对象为列,每个参数都详细的解析其作用。每个接口都描述了作用与用法。
2、一起看电影的项目开发
接下来就万事俱备了,跟着我来着手实操一下,看具体怎么实现一起看电影的项目。
项目分为两部分:播放本地电影的服务端、拉流播放电影的客户端。下面会进行每个部分的详细介绍。
项目设置了最大用户数为3人,服务端占了一位,所以客户端只能同时两人在线观看电影(悄咪咪,确保你们两个人之间不会出现第三者)。
服务端 —— 播放电影服务端的实现流程
步骤一:创建 ZegoExpressEngine 引擎:
/** 定义 SDK 引擎对象 */
ZegoExpressEngine engine;
/** 填写 appID 和 appSign */
long appID = ; /** 请通过官网注册获取,格式为 123456789L */
String appSign = ; /** 64个字符,请通过官网注册获取,格式为"0123456789012345678901234567890123456789012345678901234567890123" */
/** 创建引擎,使用测试环境,通用场景接入 */
engine = ZegoExpressEngine.createEngine(appID, appSign, true, ZegoScenario.GENERAL, getApplication(), null);
步骤二:开启自定义视频采集功能:
ZegoCustomVideoCaptureConfig videoCaptureConfig = new ZegoCustomVideoCaptureConfig();
// 选择 RAW_DATA 类型视频帧数据
videoCaptureConfig.bufferType = ZegoVideoBufferType.RAW_DATA; engine.enableCustomVideoCapture(true, videoCaptureConfig, ZegoPublishChannel.MAIN);
步骤三:设置自定义视频采集回调对象并实现对应方法:
// 将自身作为自定义视频采集回调对象 sdk.setCustomVideoCaptureHandler(new IZegoCustomVideoCaptureHandler() { @Override public void onStart(ZegoPublishChannel channel) { // 收到回调后,开发者需要执行启动视频采集相关的业务逻辑,例如开启摄像头等 ... } @Override public void onStop(ZegoPublishChannel channel) { // 收到回调后,开发者需要执行停止视频采集相关的业务逻辑,例如关闭摄像头等 ... }});
步骤四:选择要播放的电影,设置房间ID。然后登录房间,将收到自定义视频采集回调通知开始采集:
/** 创建用户 */ ZegoUser user = new ZegoUser("user1"); /** 开始登录房间 */ engine.loginRoom("room1", user); mZegoMediaPlayer.setVideoHandler(new IZegoMediaPlayerVideoHandler() {@Overridepublic void onVideoFrame(ZegoMediaPlayer zegoMediaPlayer, ByteBuffer[] byteBuffers, int[] ints, ZegoVideoFrameParam zegoVideoFrameParam) {}
}, ZegoVideoFrameFormat.RGBA32);
步骤五:当客户端发送通知开始播放电影,就开始推流(电影流),预加载load 电影,开始播放start()
/** 开始推流 */ engine.startPublishingStream("stream1");mZegoMediaPlayer.loadResource(path, new IZegoMediaPlayerLoadResourceCallback() {@Overridepublic void onLoadResourceCallback(int code) {if (code == 0) {mZegoMediaPlayer.start();if (callback != null) {callback.onLoadResourceCallback(code);}}}
});
步骤六:调用发送视频帧方法 sendCustomVideoCaptureRawData 向 SDK 提供视频帧数据。
// 将采集的数据传给ZEGO SDK
int totalDataLength = byteBuffers[0].capacity();
if (tempByteBuffer == null || tempByteBuffer.capacity() != totalDataLength) {tempByteBuffer = ByteBuffer.allocateDirect(byteBuffers[0].capacity()).put(byteBuffers[0]);
} else {tempByteBuffer.clear();tempByteBuffer.put(byteBuffers[0]);
}
ZegoSDKManager.getInstance().getStreamService().sendCustomVideoCaptureRawData(tempByteBuffer, tempByteBuffer.capacity(), zegoVideoFrameParam);
步骤七:当客户端没有观众在房间或者服务器退出播放房间,结束推流将收到自定义视频采集回调通知停止采集。
整个过程的时序图已经整理如下,大家可以参考:
客户端——拉流播放电影客户端的实现流程
首先,播放电影的客户端分别有以下几项功能:
A、B 端观众的电影拉流渲染、电影播放\暂停。
A、B 端观众音视频的推拉流、摄像头的翻转开关、麦克风的开关。
A、B 端观众的房间实时消息的发送接收。
接下来,我们将根据上述提到的具体功能展开为大家介绍:
1)针对于电影播放功能的流程介绍
a.A端观众通过后台设置的RoomID 成功登录房间,如果输入的RoomID 不存在,就会通过判断当前A端是房间内第一人,退出房间提示房间不存在;或者房间内已经满员就会登录失败并提示 房间已满员。
点击电影播放按钮 setRoomExtraInfo() 进行消息的通知
后台手机端 收到 onRoomExtraInfoUpdate() 的回调 进行电影的播放
观众端会收到电影播放的推流 ,获取电影推流 StreamID 进行拉流播放
b.B端 通过输入 RoomID 进入播放房间 ,进行电影的拉流显示:
/**
* 开始拉流,设置远端拉流渲染视图,视图模式采用 SDK 默认的模式,等比缩放填充整个 View
* 如下 play_view 为 UI 界面上的 SurfaceView/TextureView/SurfaceTexture 对象
*/
engine.startPlayingStream("stream1", new ZegoCanvas(play_view));
c.AB端观众都可以通过 setRoomExtraInfo(String roomID,String key,String value,null) 来对视频媒体进行 播放/暂停。
一起看电影 setRoomExtraInfo 的参数意义如下:
key: roomInfo
value: 0 、1、2、3
0: 代表load start 电影
1:电影是播放状态
2:电影是暂停状态
3:房间已经被关闭
2)针对于音视频推拉流的过程
a.通过 ZEGO 音视频服务进行推拉流。
b.A端观众进入房间后,向 ZEGO 音视频云服务推流,需要自己生成唯一的 StreamID ,然后开始预览并推流。等到B端观众进入房间后,会收到SDK 的流更新通知,从中筛选出 B端观众流 StreamID 进行拉流。
c.B端观众进入房间后,向 ZEGO 音视频云服务推流,需要自己生成唯一的 StreamID ,然后开始预览并推流。同时筛选出 A端观众流 StreamID 进行拉流。
d.AB端观众可以各自控制自己的 翻转摄像头、开/关摄像头、开/关麦克风 的功能:
//切换前后摄像头 front 是否采用前置摄像头;true 表示使用前置摄像头;false 表示使用后置摄像头
expressEngine.useFrontCamera(front);// 开/关摄像头 enable 是否打开摄像头;true 表示打开摄像头;false 表示关闭摄像头
expressEngine.enableCamera(enable);// 是否开启麦克风 enable 是否开启麦克风;true 表示开启麦克风;false 表示静音(关闭)麦克风
expressEngine.muteMicrophone(!enable);
都是跟推拉流有关,则以用户 A 拉取用户 B 的流为例,流程如下图:
3)针对于房间实时聊天消息的发送显示
a.AB端观众都可以在房间内发送消息;
b.调用 sendBroadcastMessage接口向同一房间内的B端观众发送广播消息,长度不能超过 1024 字节。通过 onIMSendBroadcastMessageResult 回调获取消息发送结果;
// 发送广播消息,每个登录房间的用户都会通过 onIMRecvBroadcastMessage 回调收到此消息【发送方不会收到该回调】
engine.sendBroadcastMessage(roomID, msg, new IZegoIMSendBroadcastMessageCallback() { /** 发送广播消息结果回调处理 */ @Override public void onIMSendBroadcastMessageResult(int errorCode, long messageID) { //发送消息结果成功或失败的处理 }});
c.实现IZegoEventHandler中的 onIMRecvBroadcastMessage回调,当发送方成功发送广播消息后,同一房间内的其他用户通过此回调接收相关信息,包括消息内容、消息 ID、发送时间及发送方信息。
/** * 接收房间弹幕消息通知 * * @param roomID 房间 ID * @param messageList 收到的消息列表 */
public void onIMRecvBarrageMessage(String roomID, ArrayList<ZegoBarrageMessageInfo> messageList){ // 收到其他用户发送消息的处理
}
d.发送接收到的消息显示到UI界面。
整个过程的时序图如下:
A端观众时序图:
B端观众时序图:
房间实时聊天消息时序图:
四、 效果呈现(附 demo 源码下载)
1、 播放电影端的效果图
2、观众端的效果图
附上demo给大家进行体验,一起看电影一共分为两部分,安装密码为 1:
1)服务端demo :https://www.pgyer.com/hLnW
2)客户端demo : https://www.pgyer.com/d4uU
安装方式如下:
1)先启动 服务端demo ,选择电影设置房间ID;
2)客户端 demo 通过输入设置的房间ID 进入播放电影房。
源码下载:https://pan.baidu.com/s/1lU_B_MQ4wK4bZQT90xBrCQ(密码:qrep)
五、 总结
牛顿曾说:我看得远,是因为我站在巨人的肩膀上!
基于 ZEGO 即构科技的音视频功能,一番操作下来,很简单就开发出来一款《一起看电影》的 demo,总体来说还是很简单就可以实现的。搭建过程中如果碰到任何技术问题,也可以咨询下面这个微信(可能不会特别及时,一般当天回复)。
让异地恋女友开心的方法近在咫尺,赶快行动起来体验音视频开发的乐趣吧!
最后,码字不容易啊,求一波赞、收藏、分享、评论走起~
花了3个小时解决了和异地女朋友一起看电影的需求(内附源码)相关推荐
- 如何解决和异地女朋友一起看电影的需求?(内附源码)
一.这是一件悲伤的故事 我是一名程序员,我和我的女友是异地恋,so sad!!! 一次视频时,她突然来了一句:"我们已经很久没有一起看电影了吧......" "呃...好 ...
- 2021年北京积分落户名单公布了,爬了两个多小时得到了所有数据,有了惊人的发现(附源码)
2021年北京积分落户名单公布了,手痒痒就写了一段Java代码,运行了两个多小时,终于到了所有数据,如下截图: 本着"Talk is cheap, Show me the code.&quo ...
- POI读写超大数据量Excel,解决超过几万行而导致内存溢出的问题(附源码)
来源:cnblogs.com/swordfall/p/8298386.html 1. Excel2003与Excel2007 两个版本的最大行数和列数不同,2003版最大行数是65536行,最大列数是 ...
- 成功解决ValueError: array must not contain infs or NaNs(花了好几个小时解决了这个最离奇的bug)
成功解决ValueError: array must not contain infs or NaNs(花了好几个小时解决了这个最离奇的bug) 目录 解决问题 解决思路 解决方法 问题背景
- 一小时学会使用Springboot整合沙箱环境支付宝支付(附源码)
0.前言 文章需求: 对于学生来说,目前网上确实没有比较统一而且质量好的支付教程.因为支付对个人开发者尤其是学生来说不太友好.因此,自己折腾两天,算是整理了一篇关于支付宝沙箱支付的文章. 那么为什么不 ...
- AOP注解@Before、@AfterReturning拦截单个方法的入参和出参,纯注解方式(附源码下载),解决单个方法不生效问题(一)
AOP注解@Before.@AfterReturning拦截单个方法的入参和出参,纯注解方式(附源码下载),解决单个方法不生效问题(一) 问题背景 AOP注解@Before.@AfterReturni ...
- 学生选课管理系统(SQL Server+Java 解决选课冲突问题+附源码)
数据库设计任务 : (1) 实现学生信息.课程信息.教师信息管理: (2) 实现学生选课.退课功能: (3) 实现教师及任课信息管理: (4) 实现教师开课.录入成绩功能 (5) 实现管理员创建和删除 ...
- SSM+ 基于Java的花艺商城系统设计与开发 毕业设计-附源码171536
摘 要 本论文主要论述了如何使用JAVA语言开发一个花艺商城系统 ,本系统将严格按照软件开发流程进行各个阶段的工作,采用B/S架构,面向对象编程思想进行项目开发.在引言中,作者将论述花艺商城系统的当前 ...
- [附源码]Java计算机毕业设计SSM花田音乐网站
项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...
- 【实战】Spring生成beanName冲突的解决之道:附源码分析
一.问题描述 最近公司项目打算模块化,其实一个原因也是为了能够整合公司多个业务的代码,比如一个资源xxx,两个业务中都有对这个资源的管理,虽然是一个资源,但是是完全不同的定义.完全不同的表.不同的处理 ...
最新文章
- python接收邮件内容启动程序_Python实现发送与接收邮件的方法详解
- php把时间变成整数,php怎么将字符串转为整数
- 在Java中如何设置一个定时任务,在每天的一个时间点自动执行一个特定的程序
- 有一句说一千句,是作家....
- 查看本用户对文件的权限_Linux添加新用户,设置文件权限组
- 中科院分区和JCR分区查询
- iphone13怎么安装双卡(双卡功能)
- 多旅行商问题(MTSP)的相关论文总结
- mac的 tr命令_tr命令 - Holy_Shit - 博客园
- 计算机二级front和rear什么意思,关于计算机二级考试内容
- 什么耳机对而伤害最小,传闻不伤耳的骨传导耳机是真的吗?
- 小米miui查看连接过已保存的密码方法
- RankNet,LambdaRank,LambdaMart
- PHP isset()与empty()
- 为什么图像成像时近大远小?
- 从“我爸是李刚”到高校教师聘用体制的改革
- Skr-Eric的Mysql课堂(一)——Mysql的介绍和基本SQL命令
- android 辐射动画_Android仿微信雷达辐射搜索好友(逻辑清晰实现简单)
- Rulo扫地机器人app_传感器升级+支持APP:Panasonic 松下 推出 新款 RULO 扫地机器人 MC-RS800...
- 亥姆霍兹线圈测量系统的测量原理及主要用途