这个项目是如何开始的
我和我女朋友分居,所以我们不能经常见面。有一天,我们在视频聊天时,她说:“嘿,距离上次我们一起去电影院已经有一段时间了,我们什么时候才能再一起看电影……”
她是对的。这已经有一段时间...
虽然我们还不能马上见面,但也许我们可以一起在网上看场电影。我知道有很多应用程序可供人们一起在线观看电影。特别是疫情开始以来,越来越多的此类应用和服务被推出,以满足人们保持联系的需求。但是,我的脑海里突然冒出一个念头:如果我能自己造一个,那不是很酷吗?
由于我是ZEGOCLOUD的开发人员,这是一个基于云的实时交互 API 平台,可帮助开发人员快速将实时音频/视频和应用内聊天功能构建到任何应用程序中,我拥有构建此类所需的所有东西一起看的应用程序。
然后,我无法抗拒这个想法,开始建造。
...
几个小时后,我得到了这样的东西:

作为一名开发人员,我喜欢构建事物,并且我喜欢分享事物是如何构建的。因此,在接下来的部分中,我将概述实现的一些重要步骤,并且在文章的最后,我还提供了整个项目的源代码的链接。
实施
设置开发环境
- Android Studio(2.1 或更高版本)
- Android SDK 25、Android SDK Build-Tools 25.0.2、Android SDK Platform-Tools 25.xx 或更高版本
- 带有麦克风和摄像头的 Android 设备(Android 4.1 或更高版本)
- Android 已连接到互联网。
先决条件
在开始使用 ZEGOCLOUD 构建之前,需要先完成以下几件事。
- 使用ZEGOCLOUD创建一个帐户。显然,我已经有一个帐户,所以我可以跳过这一步。
- 在ZEGOCLOUD 管理控制台中创建一个项目并获取您的 AppID 和 AppSign,这是 SDK 身份验证所需的。详见ZEGOCLOUD 管理控制台-项目管理。
现在,我们可以开始编码了!
功能概述
这将是一个具有以下功能的简单应用程序:
-
将有两个参与者加入一个房间一起看电影。我们称他们为查看器 A 和查看器 B。
-
为确保两位参与者能够获得真正同步的观看体验,我决定从单独的设备播放电影并将其流式传输到房间。我们称它为电影流媒体。
此决定中的考虑是,如果电影从参与者之一的设备播放并流式传输到房间,则流式传输延迟可能会导致两个参与者之间出现可感知的不同步问题。但是,如果电影是从单独的设备播放和流式传输的,那么两个参与者都将从云订阅和播放电影流,并且出现可感知的不同步问题的可能性会低得多。
-
房间内的参与者可以在一起看电影的同时进行视频聊天和文字聊天。
-
为了简单起见,在这个项目中,我将房间中的最大参与者人数设置为 3。
电影流媒体端 - 播放电影并将其流式传输到房间
第一步:创建ZegoExpressEngine
实例。
/// Define the ZegoExpressEngine object
ZegoExpressEngine engine;
/// Specify the AppID and AppSign for SDK authentication
/// AppID Format:123456789L
long appID = ;
/// AppSign Format:"0123456789012345678901234567890123456789012345678901234567890123"
String appSign = "";
/// Create a ZegoExpressEngine instance
engine = ZegoExpressEngine.createEngine(appID, appSign, true, ZegoScenario.GENERAL, getApplication(), null);
第 2 步:为引擎启用自定义视频捕获。
ZegoCustomVideoCaptureConfig videoCaptureConfig = new ZegoCustomVideoCaptureConfig();
// Use RAW_DATA as video buffer data type
videoCaptureConfig.bufferType = ZegoVideoBufferType.RAW_DATA; engine.enableCustomVideoCapture(true, videoCaptureConfig, ZegoPublishChannel.MAIN);
步骤 3:为自定义视频捕获设置回调处理程序并实现回调方法。
// Set the engine itself as the callback handler object
engine.setCustomVideoCaptureHandler(new IZegoCustomVideoCaptureHandler() {
@Override
public void onStart(ZegoPublishChannel channel) {
// On receiving the onStart callback, start to capture video and send the captured video frame data to the ZegoExpressEngine.
...
}
@Override
public void onStop(ZegoPublishChannel channel) {
// On receiving the onStop callback, stop the video capture process.
...
}
});
第 4 步: 加入房间。
/// Create a user
ZegoUser user = new ZegoUser("userA");
/// Join a room
engine.loginRoom("room", user);
第 5 步:为ZegoMediaPlayer
. 通过设置该处理程序,您可以通过回调接收正在播放的电影的视频帧数据onVideoFrame
。
mZegoMediaPlayer.setVideoHandler(
new IZegoMediaPlayerVideoHandler() {
@Override
public void onVideoFrame(ZegoMediaPlayer zegoMediaPlayer, ByteBuffer[] byteBuffers, int[] ints, ZegoVideoFrameParam zegoVideoFrameParam) {
if (RoomManager.getInstance().isCanSenRawData()) {
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);
}
}
}, ZegoVideoFrameFormat.RGBA32);
第 6 步:开始流发布。从指定的文件路径(本地文件路径或指向 Internet 媒体资源的 URL)加载电影,然后开始播放电影。
/// Start publishing the stream
engine.startPublishingStream("streamMovie");
mZegoMediaPlayer.loadResource(path, new IZegoMediaPlayerLoadResourceCallback() {
@Override
public void onLoadResourceCallback(int code) {
if (code == 0) {
mZegoMediaPlayer.start();
if (callback != null) {
callback.onLoadResourceCallback(code);
}
}
}
});
第七步:当房间内没有其他参与者或正在发布流的参与者离开房间时,停止发布流,并触发停止自定义视频采集的回调。
ZegoSDKManager.getInstance().getDeviceService().setCustomVideoCaptureHandler(new IZegoVideoCaptureCallback() {
@Override
public void onStart(ZegoPublishChannel channel) {
canSenRawData = true;
}
@Override
public void onStop(ZegoPublishChannel channel) {
canSenRawData = false;
}
});
观影端——订阅影流一起看,视频聊天,文字聊天
要实现watch together功能,我们需要实现以下功能:
- 观众订阅正在播放的电影的视频流,以便他们可以一起观看。
- 两个观众都可以控制电影播放。例如,其中任何一个都可以暂停和恢复播放。
- 观看电影时进行视频聊天的流媒体发布/订阅和相机/麦克风操作。
- 在房间内发送和接收实时短信。
电影播放的高级程序逻辑:
- 主播会先创建一个房间,观众需要加入同一个房间(调用
loginRoom
方法时指定相同的房间ID)。
如果观众试图加入一个不存在或没有电影流媒体的房间,他们将被提升一条消息Room doesn't exist
。
如果指定房间已满,则房间登录失败,并通知用户。
-
当观众单击“开始电影”按钮时,调用
setRoomExtraInfo()
以向电影流媒体发送通知。通过回调接收到此类通知后onRoomExtraInfoUpdate()
,电影流媒体将执行开始播放电影并开始将电影流式传输到房间的逻辑。 -
然后,电影流将被两个观众接收并在他们的设备上播放。
/// start playing stream
engine.startPlayingStream("stream1", new ZegoCanvas(play_view));
- 两个观众都可以调用该
setRoomExtraInfo(String roomID,String key,String value,null)
方法来控制电影播放(播放或暂停)。
setRoomExtraInfo
下表显示了您可以传递给该方法以发送不同通知的键值参数:

视频聊天的高级程序逻辑:
- 加入房间后,观众 A(或 B)可以开始从具有唯一 Stream ID 的摄像机发布视频,也可以开始本地预览。
- 当其他观众加入房间并开始向房间发布他/她的视频时,ZEGO Express SDK 将相应地发送事件通知。观看者 A(或 B)然后可以使用从回调通知接收到的流 ID 开始播放其他观看者的视频。
- 两个观众都可以随意控制他们的摄像头(例如,在前/后摄像头之间切换、打开/关闭摄像头)和麦克风(例如,静音/取消静音)。
/// Switch between the front/rear camera
expressEngine.useFrontCamera(front);
/// Turn on/off the camera
expressEngine.enableCamera(enable);
/// Mute or unmute the microphone
expressEngine.muteMicrophone(!enable);
文本聊天的高级程序逻辑:
- 两位观众都可以在房间内发送和接收实时短信。
- 调用
sendBroadcastMessage
方法向房间中的其他参与者发送广播消息(不超过 1024 字节)。
/// Send broadcast messages
engine.sendBroadcastMessage(roomID, msg, new IZegoIMSendBroadcastMessageCallback() {
@Override
public void onIMSendBroadcastMessageResult(int errorCode, long messageID) {
/// Returned result of sending broadcast messages
}
});
-
onIMRecvBroadcastMessage
实现中定义的回调方法IZegoEventHandler
来监听和处理其他参与者发送的广播消息。您可以通过该回调获取消息的详细信息,包括消息内容、消息ID、消息发送时间、消息发送者。
/// reveice message
public void onIMRecvBroadcastMessage(String roomID, ArrayList<ZegoBroadcastMessageInfo> messageList){
}
完成后的应用程序是什么样的(源代码下载链接附在下面)
电影流光面

观察者侧


如果您愿意,您可以安装以下演示应用程序并自行尝试:
如何使用演示:
- 首先启动电影流媒体,选择一部电影,然后设置房间 ID。
- 启动查看器应用程序,然后通过指定相同的房间 ID 加入房间。
结论
通过本次分享,希望大家会发现,做一个一起看电影的APP其实并没有大家想象的那么难。准备好自己建造一个了吗?
作者:大卫雷洛
链接:https://dev.to/davidrelo/movies-together-online-in-a-few-hours-source-code-inside-40o0
网友评论