Zego即构是一家做直播的服务商,Zego即构自己的房间列表,本文只是测试功能用,相应代码并没完全测试,请选择性参考。

  

  我们在UE4中来实现一下,我感觉这个过程有点意思,UE4中C++与蓝图和UI的互相通信基本全部用到了。

  Zego即构没有专门的UE4插件,所以我们主要逻辑全部在C++中,蓝图只是辅助。

  首先,我们定义一个房间结构,因为要想UE4中C++和蓝图可见可用,我们要用C++实现,并实现特定的写法让蓝图知道。

  1. USTRUCT(BlueprintType)
  2. struct FRoomBlueprint
  3. {
  4. GENERATED_BODY()
  5.  
  6. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "")
  7. FString roomId;
  8. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "")
  9. FString roomName;
  10. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "")
  11. FString anchorName;
  12. UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "")
  13. int streamSize;
  14. public:
  15. FRoomBlueprint()
  16. {
  17. roomId = nullptr;
  18. roomName = nullptr;
  19. anchorName = nullptr;
  20. streamSize = ;
  21. }
  22. };

FRoomBlueprint

  理一下逻辑,UE得到所有房间列表,然后给UE4蓝图,蓝图根据每个房间列表创建对应个房间,完成了。

  我们找一下Zego即构的如何获得房间列表的API,发现他是通过Http Get方式得到的,因为Http Get我们肯定以异步方式来实现,那么如何通知蓝图了,我们需要定义一个蓝图能识别的事件委托才行。

  1. using namespace ZEGO::LIVEROOM;
  2.  
  3. DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnGetRoomList, TArray<FRoomBlueprint>, roomList);
  4.  
  5. UCLASS()
  6. class TESTJIGOU_API AJigouMain : public AActor, public IZegoVideoRenderCallback
  7. {
  8. GENERATED_BODY()
  9.  
  10. public:
  11. // Sets default values for this actor's properties
  12. AJigouMain();
  13.  
  14. protected:
  15. // Called when the game starts or when spawned
  16. virtual void BeginPlay() override;
  17. virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
  18.  
  19. public:
  20. // Called every frame
  21. virtual void Tick(float DeltaTime) override;
  22. ]);
  23.  
  24. UPROPERTY(BlueprintAssignable)
  25. FOnGetRoomList eventGetRoomList;
  26. UFUNCTION(BlueprintCallable, Category = "AMRVideo")
  27. void PullRoomList();
  28.  
  29. };
  30. void AJigouMain::PullRoomList()
  31. {
  32. FString baseUri = FString::Printf(_T("https://liveroom%u-api.zego.im/demo/roomlist?appid=%u"),
  33. ManagerConnect::Get().GetAppID(), ManagerConnect::Get().GetAppID());
  34.  
  35. auto HttpRequest = FHttpModule::Get().CreateRequest();
  36. HttpRequest->SetVerb("GET");
  37. HttpRequest->SetHeader("Content-Type", "application/json");
  38. HttpRequest->SetURL(baseUri);
  39. //HttpRequest->SetContentAsString(JsonStr);
  40. HttpRequest->OnProcessRequestComplete().BindLambda(
  41. [&](FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
  42. {
  43. if (Response.Get() == nullptr)
  44. return;
  45. auto content = Response->GetContentAsString();
  46. TSharedPtr<FJsonObject> JsonObject;
  47. auto Reader = TJsonReaderFactory<>::Create(content);
  48. if (FJsonSerializer::Deserialize(Reader, JsonObject))
  49. {
  50. auto state = JsonObject->GetIntegerField("code");
  51. )
  52. {
  53. TArray<FRoomBlueprint> roomArray;
  54. auto data = JsonObject->GetObjectField("data");
  55. auto roomList = data->GetArrayField("room_list");
  56. int lenght = roomList.Num();
  57. ; i < lenght; i++)
  58. {
  59. FRoomBlueprint rInfo = {};
  60. auto room = roomList[i]->AsObject();
  61. rInfo.roomId = room->GetStringField("room_id");
  62. rInfo.roomName = room->GetStringField("room_name");
  63. rInfo.anchorName = room->GetStringField("anchor_id_name");
  64.  
  65. auto listStream = room->GetArrayField("stream_info");
  66. )
  67. {
  68. rInfo.streamSize = listStream.Num();
  69. roomArray.Add(rInfo);
  70. }
  71. }
  72. if (eventGetRoomList.IsBound())
  73. {
  74. eventGetRoomList.Broadcast(roomArray);
  75. }
  76. }
  77. }
  78. });
  79.  
  80. HttpRequest->ProcessRequest();
  81.  
  82. }

AJigouMain

  其实如果我们不直接用C++实例,再实现一个蓝图继承AJigouMain,然后实现UFUNCTION(BlueprintNativeEvent)也一样可以得到这个效果,再这,我们就直接把如上AJigouMain实例结果放入场景中。

  嗯,逻辑部分差不多了,我们开始实现UI,首先我们定义一个房间控件。

  

  嗯,记的我们前面声明的结构FRoomBlueprint吗,一个房间对应一个FRoomBlueprint,前面文本分别绑定对应FRoomBlueprint的流数,房间名。

  我们要考虑的是点击加入后如何把当前房间的信息发散出去,简单来说,调用一个事件,事件要包含当前的点击的房间信息,至于事件绑定的执行函数,我们现在还不知道,也不用考虑。

  

  简单来说,Room这个房间控件知道的就是,我点击了我的加入button,并在点击后,调用OnJoin,调用当前事件把对应的FRoomBlueprint结构传入事件中,这个控件就不需要管别的事了。

  如上,得到所有房间后,需要根据得到的房间列表生成对应的房间列表UI,有如上的房间控件后,我们来看看UE4如何生成列表。

  

  如上主要逻辑都在UIPanel里,Room List box就是一个UE4里的Vertical Box控件,用来垂直放入我们上面的Room控件,并把每个FRoomBlueprint实例传入对应的Room控件,在这个集中门面类中,我们知道对应的Room控件的加入功能具体能做什么了,绑定有相同的函数签名的事件上就行了。并且结合上面的eventGetRoomList事件,我们调用这个方法就行了。

  

  对应的加入房间,我们提供一个简单的UBlueprintFunctionLibrary类,帮我们处理一些基本的C++事件,如:

  1. UCLASS()
  2. class TESTJIGOU_API UBlueprintHelper : public UBlueprintFunctionLibrary
  3. {
  4. GENERATED_BODY()
  5.  
  6. public:
  7. UFUNCTION(BlueprintPure, Category = "AJigouMain")
  8. static bool OnJoinRoom(FRoomBlueprint room, FString userID);
  9.  
  10. UFUNCTION(BlueprintPure, Category = "AJigouMain")
  11. static TArray<FDeviceInfo> GetDeviceList();
  12.  
  13. UFUNCTION(BlueprintPure, Category = "AJigouMain")
  14. static bool OnCreateRoom(FString userID);
  15.  
  16. UFUNCTION(BlueprintPure, Category = "AJigouMain")
  17. static bool SetDeviceRoom(FString deviceID);
  18.  
  19. UFUNCTION(BlueprintPure, Category = "AJigouMain")
  20. static bool SetDeviceRoom2(FString deviceID);
  21.  
  22. UFUNCTION(BlueprintPure, Category = "AJigouMain")
  23. static bool SetRole(int roleID);
  24.  
  25. UFUNCTION(BlueprintPure, Category = "AJigouMain")
  26. static FString GetRoleName();
  27.  
  28. UFUNCTION(BlueprintPure, Category = "AJigouMain")
  29. static bool PullStream(FString stream);
  30. };
  31. bool UBlueprintHelper::OnJoinRoom(FRoomBlueprint room, FString userID)
  32. {
  33. auto currentRole = ManagerConnect::Get().getCurrentRole();
  34. FTCHARToUTF8 user(*(currentRole.userID));
  35. FString roomID = room.roomId;
  36. FString roomName = room.roomName;
  37. auto bJoin = LIVEROOM::SetUser(user.Get(), user.Get());
  38. if (bJoin)
  39. {
  40. FTCHARToUTF8 id(*roomID);
  41. FTCHARToUTF8 roomName(*roomName);
  42. auto bJoin = LIVEROOM::LoginRoom(id.Get(), currentRole.role, roomName.Get());
  43. ManagerConnect::Get().bAuthor = false;
  44. }
  45. return bJoin;
  46. }

  倒数第二张图上,点击加入按键,绑定的方法就是这个方法。

  最后效果图:

  和直播出来画面不一样是因为我们在UE4里做了反畸变,用的是in.yml生成的一张UV贴图,需要注意的是,此处这图贴图最好用PF_FloatRGBA,不要用R8G8B8A8,精度不够,生成的图片很多裂变,PF_FloatRGBA对应的是FFloat16Color,而不是FLineColor。  

用UE4来做Zego即构的房间列表的更多相关文章

  1. 一步一步来做WebQQ机器人-(四)(获取好友列表和群列表)

    × 本篇主要是: 获取好友列表,群列表 我会尽量详细一点,尽我所知的分享一些可能大家已经掌握的或者还不清楚的经验 利于大家阅读,文章样式不再复杂化,根据内容取固定色 目前总进度大概65% 全系列预计会 ...

  2. 用jquery做一个带导航的名单列表

    代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...

  3. Node.js 打造实时多人游戏框架

    在 Node.js 如火如荼发展的今天,我们已经可以用它来做各种各样的事情.前段时间UP主参加了极客松活动,在这次活动中我们意在做出一款让“低头族”能够更多交流的游戏,核心功能便是 Lan Party ...

  4. ZEGO音视频服务的高可用架构设计与运营

    前言: ZEGO 即构科技作为一家实时音视频的提供商,系统稳定性直接影响用户的主观体验,如何保障服务高可用且用户体验最优是行业面临的挑战,本文结合实际业务场景进行思考,介绍 ZEGO 即构在高可用架构 ...

  5. es6之变量的解构赋值

    es5中通常我们声明变量都是以下的方式: var a = 10; var b = 20; var c = 30; //或者 var a = 10,b = 20,c = 30; //或者 var arr ...

  6. ES6解构赋值详解

    文章转载自:http://www.zhufengpeixun.cn/article/167 解构赋值(destructuring assignment)语法是一个 Javascript 表达式,这种语 ...

  7. 【UE4 设计模式】抽象工厂模式 Abstract Factory Pattern

    概述 描述 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类:具体的工厂负责实现具体的产品实例 抽象工厂中每个工厂可以创建多种产品(如苹果公司生产iPhone.iPad): 工厂方法 ...

  8. 【UE4 设计模式】建造者模式 Builder Pattern

    概述 描述 建造者模式,又称生成器模式.是将一个复杂的对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示. 建造者模式将客户端与包含多个组成部分的复杂对象的创建过程分离,客户端无需知道复杂 ...

  9. 【UE4 设计模式】享元模式 Flyweight Pattern

    概述 描述 运用共享技术有效地支持大量细粒度对象的复用.系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用. 由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻 ...

随机推荐

  1. PHP源码阅读strtr

    strtr 转换字符串中特定的字符,但是这个函数使用的方式多种. echo strtr('hello world', 'hw', 'ab'); // 第一种 aello borld echo strt ...

  2. Selenium的简单安装和使用

    Selenium的安装 pip install selenium Selenium模块需要调用浏览器,需要配置selenium的浏览器驱动 Firefox(火狐) 下载对应版本的geckdriver. ...

  3. jquery中append与appendTo方法区别

    1. append(content)方法 方法作用:向每个匹配的元素内部追加内容. 参数介绍:content (<Content>): 要追加到目标中的内容. 用法示例: HTML代码为& ...

  4. c++调用python系列(1): 结构体作为入参及返回结构体

    最近在打算用python作测试用例以便对游戏服务器进行功能测试以及压力测试; 因为服务器是用c++写的,采用的TCP协议,当前的架构是打算用python构造结构体,传送给c++层进行socket发送给 ...

  5. ArrayList和LinkedList源码

    1 ArrayList 1.1 父类 java.lang.Object 继承者 java.util.AbstractCollection<E> 继承者 java.util.Abstract ...

  6. man rsync翻译(rsync命令中文手册)

    本文为命令rsync的man文档翻译,几乎所有的选项都翻译了,另外关于筛选规则部分只翻译了一部分.由于原文很多地方都比较啰嗦,所以译文中有些内容可能容易让国人疑惑,所以我个人在某些地方加上了注释.若有 ...

  7. ES6解构赋值

    前面的话 我们经常定义许多对象和数组,然后有组织地从中提取相关的信息片段.在ES6中添加了可以简化这种任务的新特性:解构.解构是一种打破数据结构,将其拆分为更小部分的过程.本文将详细介绍ES6解构赋值 ...

  8. HDOJ2003-求绝对值

    Problem Description 求实数的绝对值.   Input 输入数据有多组,每组占一行,每行包含一个实数.   Output 对于每组输入数据,输出它的绝对值,要求每组数据输出一行,结果 ...

  9. 从Ubunt的安装到hadoop集群的搭建

    一.相关基础配置 1.网络设置 a.调整VMnet8这块网卡网关 b.在VMware[编辑]->[虚拟网络编辑器]对VMnet8进线[NAT 设置] c.调整[DHCP 设置]中的起始IP地址 ...

  10. Eclipse常用快捷键大全

    1.ctrl+shift+r:打开资源 这可能是所有快捷键组合中最省时间的了.这组快捷键可以让你打开你的工作区中任何一个文件,而你只需要按下文件名或mask名中的前几个字母