一、这是一件悲伤的故事

我是一名程序员,我和我的女友是异地恋,so sad!!!

一次视频时,她突然来了一句:“我们已经很久没有一起看电影了吧。。。。。。”

“呃。。。好像是”,毕竟离得那么远,一起看电影有点难啊。

女友“哦”了下,我们便陷入了沉默。

视频结束,心情有点忧伤。是啊,已经很久没有好好陪她了吧。

突然想到市面上有不少可以一起看电影的APP。找了下,确实不少,像微光之类的 APP 人气都很火。下载了一个,发现还是挺有意思的,确实能解决异地一起看电影的需求。

于是“啪”的一下,灵光一现,哄女友开心的方法有了,哦耶!!!我可以自己去实现一个 demo 呀!

作为一名优质的程序员,鉴于职业探索精神以及在 ZEGO 即构科技的从业经验,想到实现一个类似功能的 demo 还是很可以的。

说干就干,熬夜小 case,通宵搞出了demo,效果如下:

前面铺设了这么长,相信你们也不是来看我晒狗粮的(狗头保命)。那么现在就和我一起来看看我是怎么实现这个让女朋友欢心的“一起看电影”的功能吧,文章有点长,但是绝对很干货,大家可以耐心看完。

二、开始准备

在开始实现一起看电影的demo之前,我们需要做一些开发前的准备工作:

01

开发环境准备

首先第一步就是准备开发环境,需要确保开发环境满足以下要求:

  • 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。

02

账户注册

开发环境搭建好之后,我们需要去 ZEGO 官网注册一个账户,进入管理控制台并创建应用、获取开发需要的 AppId 和 AppSign 。

具体的创建应用过程详见此文章:  控制台创建项目流程。

三、实现流程介绍

01

接口规范说明

首先分析 ZEGO 的 API 输入输出规范。根据 API使用文档 来看,调用接口格式如下:

以创建 ZegoExpressEngine 单列对象为列,每个参数都详细的解析其作用。每个接口都描述了作用与用法。

02

一起看电影的项目开发

接下来就万事俱备了,跟着我来着手实操一下,看具体怎么实现一起看电影的项目。

项目分为两部分:播放本地电影的服务端、拉流播放电影的客户端。下面会进行每个部分的详细介绍。

项目设置了最大用户数为3人,服务端占了一位,所以客户端只能同时两人在线观看电影(悄咪咪,确保你们两个人之间不会出现第三者)。

1、服务端 —— 播放电影服务端的实现流程

  • 步骤一: 创建 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);
  • 步骤七:当客户端没有观众在房间或者服务器退出播放房间,结束推流将收到自定义视频采集回调通知停止采集。

2、客户端——拉流播放电影客户端的实现流程

首先,播放电影的客户端分别有以下几项功能:

  • A、B 端观众的电影拉流渲染、电影播放\暂停。

  • A、B 端观众音视频的推拉流、摄像头的翻转开关、麦克风的开关。

  • A、B 端观众的房间实时消息的发送接收。

接下来,我们将根据上述提到的具体功能展开为大家介绍:

(1)针对于电影播放功能的流程介绍

  • A 端观众通过后台设置的 RoomID 成功登录房间,如果输入的 RoomID 不存在,就会通过判断当前 A 端是房间内第一人,退出房间提示房间不存在;或者房间内已经满员就会登录失败并提示 房间已满员。

    *  点击电影播放按钮  setRoomExtraInfo() 进行消息的通知

    *  后台手机端 收到 onRoomExtraInfoUpdate() 的回调 进行电影的播放

    *  观众端会收到电影播放的推流 ,获取电影推流 StreamID 进行拉流播放

  • B 端 通过输入 RoomID 进入播放房间 ,进行电影的拉流显示:

/**
*  开始拉流,设置远端拉流渲染视图,视图模式采用 SDK 默认的模式,等比缩放填充整个 View
*  如下 play_view 为 UI 界面上的 SurfaceView/TextureView/SurfaceTexture 对象
*/
engine.startPlayingStream("stream1", new ZegoCanvas(play_view));
  • AB端观众都可以通过 setRoomExtraInfo(String roomID,String key,String value,null) 来对视频媒体进行 播放/暂停。

  • AB端观众都可以通过 setRoomExtraInfo(String roomID,String key,String value,null) 来对视频媒体进行 播放/暂停。

一起看电影 setRoomExtraInfo 的参数意义如下:

  1. key: roomInfo

  2. value:  0 、1、2、3

  3. 0: 代表load start 电影

  4. 1:电影是播放状态

  5. 2:电影是暂停状态

  6. 3:房间已经被关闭

(2)针对于音视频推拉流的过程

  • 通过 ZEGO 音视频服务进行推拉流

  • A端观众进入房间后,向 ZEGO 音视频云服务推流,需要自己生成唯一的 StreamID ,然后开始预览并推流。等到B端观众进入房间后,会收到SDK 的流更新通知,从中筛选出 B端观众流 StreamID 进行拉流

  • B端观众进入房间后,向 ZEGO 音视频云服务推流,需要自己生成唯一的 StreamID ,然后开始预览并推流。同时筛选出 A端观众流 StreamID 进行拉流

  • AB端观众可以各自控制自己的 翻转摄像头、开/关摄像头、开/关麦克风 的功能:

//切换前后摄像头 front 是否采用前置摄像头;true 表示使用前置摄像头;false 表示使用后置摄像头
expressEngine.useFrontCamera(front);// 开/关摄像头 enable 是否打开摄像头;true 表示打开摄像头;false 表示关闭摄像头
expressEngine.enableCamera(enable);// 是否开启麦克风 enable 是否开启麦克风;true 表示开启麦克风;false 表示静音(关闭)麦克风
expressEngine.muteMicrophone(!enable);

都是跟推拉流有关,则以用户 A 拉取用户 B 的流为例,流程如下图:

想要了解更加具体的实现流程,可参考官方文档 音视频实现流程。

(3)针对于房间实时聊天消息的发送显示

  • AB 端观众都可以在房间内发送消息;

  • 调用 sendBroadcastMessage 接口向同一房间内的B端观众发送广播消息,长度不能超过 1024 字节。通过 onIMSendBroadcastMessageResult 回调获取消息发送结果;

// 发送广播消息,每个登录房间的用户都会通过 onIMRecvBroadcastMessage 回调收到此消息【发送方不会收到该回调】
engine.sendBroadcastMessage(roomID, msg, new IZegoIMSendBroadcastMessageCallback() {    /** 发送广播消息结果回调处理 */     @Override     public void onIMSendBroadcastMessageResult(int errorCode, long messageID) {          //发送消息结果成功或失败的处理     }});
  • 实现 IZegoEventHandler 中的 onIMRecvBroadcastMessage 回调,当发送方成功发送广播消息后,同一房间内的其他用户通过此回调接收相关信息,包括消息内容、消息 ID、发送时间及发送方信息。

/**      * 接收房间弹幕消息通知      *      * @param roomID 房间 ID      * @param messageList 收到的消息列表      */
public void onIMRecvBarrageMessage(String roomID, ArrayList<ZegoBarrageMessageInfo> messageList){         // 收到其他用户发送消息的处理
}
  • 发送接收到的消息显示到UI界面。

四、效果呈现(附 demo 源码下载)

01

播放电影端的效果图

(电影播放端)

02

观众端的效果图

(电影观众端)

(电影播放时示意图)

附上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,总体来说还是很简单就可以实现的。

让异地恋女友开心的方法近在咫尺,赶快行动起来体验音视频开发的乐趣吧!


扫描图中二维码或点击阅读原文

了解大会更多信息

如何解决和异地女朋友一起看电影的需求?(内附源码)相关推荐

  1. 基于Vue+Express+Mysql开发的手机端电影购票系统(附源码)

    基于Vue+Express+Mysql开发的手机端电影购票系统 基于手机的电影购票系统-Vue+Node 一个Vue+Express+Mysql的电影售票项目 项目完整源码下载 https://dow ...

  2. 【表白神器】Python超火隐藏表白图 你能看出来吗?【附源码】

    ​ 导语 浪漫至死不渝,温柔绝对屈服. -马上国庆了-没啥送的-那就送大家一些表白的代码吧- 大兄弟小姐妹们,大家好! 我是准时上线更新代码+讲故事的程序媛小姐姐! 整理了一款超火的『 隐藏表白代码  ...

  3. 「表白神器」Python超火隐藏表白图 你能看出来吗?「附源码」

    导语 浪漫至死不渝,温柔绝对屈服. -马上国庆了-没啥送的-那就送大家一些表白的代码吧- 大兄弟小姐妹们,大家好! 我是准时上线更新代码+讲故事的程序媛小姐姐! 整理了一款超火的『 隐藏表白代码 』希 ...

  4. Spring Security,没有看起来那么复杂(附源码)

    权限管理是每个项目必备的功能,只是各自要求的复杂程度不同,简单的项目可能一个 Filter 或 Interceptor 就解决了,复杂一点的就可能会引入安全框架,如 Shiro, Spring Sec ...

  5. 计算机毕业设计SSM电影售票管理系统【附源码数据库】

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

  6. jsp+ssm计算机毕业设计电影影评网【附源码】

    项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclis ...

  7. 基于Python的Flask框架开发的在线电影网站系统(附源码)

    来源丨网络 今天给大家分享的是基于Python的Flask框架开发的在线电影网站系统. 项目介绍 项目介绍:网站前端采用HTML5编写,使用Bootstrap前端开发框架,后端使用Python3语言编 ...

  8. 女朋友喜欢看电影 然后就有了这个程序 来来来 大家一起看电影

    Note: 女朋友喜欢看电影 然后又异地 然后就有了这个程序 NSoup 做的解析  扒下来了电影天堂 和 80s 的网页 后面有空也许会把其它电影网站的数据拉下来 WPF 做的皮  不会设计UI   ...

  9. 使用 SyncPlay 和异地朋友一起看电影

    近日疫情致令本州下了居家令.不过在居家令之前,本也不敢出门了.线下社交完全停滞,就和朋友们约着在线上一起做些事情.比如线上的 movie night.今晚成功举行了第一次,大家聊得很开心.这里是一份实 ...

最新文章

  1. 未来教育python视频百度云-青橙课程 | 人工智能走进课堂,为未来教育高质量发展赋能!...
  2. c++ 类数组_《深入java虚拟机》读书笔记类加载
  3. 【年终总结】有三AI至今在人脸图像算法领域都分享了哪些内容?
  4. 面向对象编程之:封装、继承、多态
  5. C#访问postgresql数据库类MyPostDB的实现
  6. 【转贴】想应聘的瞧仔细了:HW分析大全
  7. [转载] python关键字和保留字_Python关键字
  8. bootstrap基础样式学习(二)——栅格
  9. Unknown run configuration type AndroidRunConfigurationType的解决办法
  10. This file should be served over HTTPS. This download has been blocked. computed高级处理
  11. 17、小写数字转大写数字
  12. matlab fft 相位,从相位和幅度获取傅立叶变换 – Matlab
  13. 腾讯让企业微信连接微信,这是针对钉钉的精准打击吗?
  14. 2019.7.summary
  15. 上海学车科目二,科目三容易扣分点分享,你了解多少
  16. 系统管理Lesson 14. Performing Database Backups
  17. Gentoo无线网卡安装之broadcom-sta(wl)篇(三)
  18. 数据包封包APP信息收集
  19. 简单的网页登录注册页面
  20. linux英伟达显卡驱动390下载,nvidia英伟达驱动|NVIDIA英伟达显卡驱动程序更新下载(32/64位) v384.90 Linux版 - 飞极下载站...

热门文章

  1. 解决 Tomcat 下 getInitParameter 返回 null
  2. Altium Designer 18/AD 设置禁止布线层和铜皮或者其他线之间的间距
  3. ubuntu18.04 VirtualBox 开启虚拟机出错 Kernel driver not installed (rc=-1908)
  4. HMAC-SHA1加密
  5. Python命令行自动补全和记录历史命令
  6. BZOJ2199: [Usaco2011 Jan]奶牛议会
  7. man-翻译和epoll相关的内容,部分
  8. LAMP LNMP性能测试
  9. 微软发布架构师期刊阅读器
  10. CodeForces - 1287D Numbers on Tree(dfs+stl)