增加 UpdateBuffer() 方法
通过调用来更新 Buffer 值。我们希望从 Agora SDK 线程接收到新的值。由于 UE4 的限制,我们将值保存到变量 Buffer 中,并在 NativeTick 方法中更新纹理,所以这里不调用UpdateTextureRegions。
//VideoViewWidget.h
...
UCLASS()
class AGORAVIDEOCALL_API UVideoViewWidget : public UUserWidget
{
GENERATED_BODY()
public:
...
void UpdateBuffer( uint8* RGBBuffer, uint32_t Width, uint32_t Height, uint32_t Size );
void ResetBuffer();
...
};
//VideoViewWidget.cpp
void UVideoViewWidget::UpdateBuffer(
uint8* RGBBuffer,
uint32_t NewWidth,
uint32_t NewHeight,
uint32_t NewSize)
{
FScopeLock lock(&Mutex);
if (!RGBBuffer)
{
return;
}
if (BufferSize == NewSize)
{
std::copy(RGBBuffer, RGBBuffer + NewSize, Buffer);
}
else
{
delete[] Buffer;
BufferSize = NewSize;
Width = NewWidth;
Height = NewHeight;
Buffer = new uint8[BufferSize];
std::copy(RGBBuffer, RGBBuffer + NewSize, Buffer);
}
}
void UVideoViewWidget::ResetBuffer()
{
for (uint32 i = 0; i < Width * Height; ++i)
{
Buffer[i * 4 + 0] = 0x32;
Buffer[i * 4 + 1] = 0x32;
Buffer[i * 4 + 2] = 0x32;
Buffer[i * 4 + 3] = 0xFF;
}
}
创建 VideoCallViewWidget C++类
VideoCallViewWidget 类的作用是显示本地和远程用户的视频。我们需要两个 VideoViewWidget 小部件,一个用来显示来自本地摄像头的视频,另一个用来显示从远程用户收到的视频(假设我们只支持一个远程用户)。
创建类和添加所需的 include
像之前那样创建Widget C++类,添加所需的include。
//VideoCallViewWidget.h #include "CoreMinimal.h" #include "Blueprint/UserWidget.h" #include "Components/SizeBox.h" #include "VideoViewWidget.h" #include "VideoCallViewWidget.generated.h" //VideoCallViewWidget.cpp #include "Components/CanvasPanelSlot.h"
添加成员变量
//VideoCallViewWidget.h
...
UCLASS()
class AGORAVIDEOCALL_API UVideoCallViewWidget : public UUserWidget
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
UVideoViewWidget* MainVideoViewWidget = nullptr;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
USizeBox* MainVideoSizeBox = nullptr;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
UVideoViewWidget* AdditionalVideoViewWidget = nullptr;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
USizeBox* AdditionalVideoSizeBox = nullptr;
public:
int32 MainVideoWidth = 0;
int32 MainVideoHeight = 0;
...
};
覆盖 NativeTick() 方法
``
//VideoCallViewWidget.h
...
UCLASS()
class AGORAVIDEOCALL_API UVideoCallViewWidget : public UUserWidget
{
GENERATED_BODY()
public:
...
void NativeTick(const FGeometry& MyGeometry, float DeltaTime) override;
...
};
//VideoCallViewWidget.cpp
void UVideoCallViewWidget::NativeTick(const FGeometry& MyGeometry, float DeltaTime)
{
Super::NativeTick(MyGeometry, DeltaTime);
auto ScreenSize = MyGeometry.GetLocalSize();
if (MainVideoHeight != 0)
{
float AspectRatio = 0;
AspectRatio = MainVideoWidth / (float)MainVideoHeight;
auto MainVideoGeometry = MainVideoViewWidget->GetCachedGeometry();
auto MainVideoScreenSize = MainVideoGeometry.GetLocalSize();
if (MainVideoScreenSize.X == 0)
{
return;
}
auto NewMainVideoHeight = MainVideoScreenSize.Y;
auto NewMainVideoWidth = AspectRatio * NewMainVideoHeight;
MainVideoSizeBox->SetMinDesiredWidth(NewMainVideoWidth);
MainVideoSizeBox->SetMinDesiredHeight(NewMainVideoHeight);
UCanvasPanelSlot* CanvasSlot = Cast<UCanvasPanelSlot>(MainVideoSizeBox->Slot);
CanvasSlot->SetAutoSize(true);
FVector2D NewPosition;
NewPosition.X = -NewMainVideoWidth / 2;
NewPosition.Y = -NewMainVideoHeight / 2;
CanvasSlot->SetPosition(NewPosition);
}
}










