用C++写播放视频功能,在slate控件上播放

创建一个MediaPlayer的材质,转换成画刷,,然后给SImage,在Tick更新画面,就是这样,下面是具体代码,

#pragma once

#include "CoreMinimal.h"
#include "UObject/WeakObjectPtr.h"
#include "Widgets/DeclarativeSyntaxSupport.h"
#include "Widgets/SCompoundWidget.h"

class UAudioComponent;
class UMaterial;
class UMaterialExpressionTextureSample;
class UMediaPlayer;
class UMediaSoundWave;
class UMediaTexture;
struct FSlateBrush;
enum class EMediaEvent;
/**
 * 
 */

class USERINTERFACE_API SVideoPlay : public SCompoundWidget
{
public:
	DECLARE_DELEGATE(FCloseVieoPlay)
	SLATE_BEGIN_ARGS(SVideoPlay)
	{}
	SLATE_EVENT(FCloseVieoPlay,OnCloseVideoPlay)
	SLATE_ARGUMENT(FString, VideoURL)
		SLATE_END_ARGS()


	SVideoPlay();
	~SVideoPlay();
	/** Constructs this widget with InArgs */
	void Construct(const FArguments& InArgs);

	/** The material that wraps the video texture for display in an SImage. */
	UMaterial* Material;

	/** The Slate brush that renders the material. */
	TSharedPtr<FSlateBrush> MaterialBrush;

	/** The media player whose video texture is shown in this widget. */
	UMediaPlayer* MediaPlayer;

	UMediaTexture* DefaultTexture;

	TWeakObjectPtr<UMediaTexture> CurrentTexture;

	/** The video texture sampler in the wrapper material. */
	UMaterialExpressionTextureSample* TextureSampler;

	virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override;

	void UpdateMaterial();

	FString VideoURL;

	FReply CloseVideoPlay();

	FCloseVieoPlay OnCloseVideoPlay;
};

// Fill out your copyright notice in the Description page of Project Settings.

#include "UserInterface.h"
#include "SVideoPlay.h"
#include "Styling/SlateBrush.h"
#include "Widgets/Images/SImage.h"
#include "IMediaOutput.h"
#include "IMediaPlayer.h"
#include "Materials/Material.h"
#include "Materials/MaterialExpressionTextureSample.h"
#include "MediaPlayer.h"
#include "MediaTexture.h"
#include "Engine.h"
#include "SlateOptMacros.h"


SVideoPlay::SVideoPlay() :
	CurrentTexture(nullptr)
	, DefaultTexture(nullptr)
	, Material(nullptr)
	, MediaPlayer(nullptr)
{
	//DefaultSoundWave = NewObject<UMediaSoundWave>(GetTransientPackage(), NAME_None, RF_Transient | RF_Public);

	//if (DefaultSoundWave != nullptr)
	//{
	//	DefaultSoundWave->AddToRoot();

	//	AudioComponent = FAudioDevice::CreateComponent(DefaultSoundWave);

	//	if (AudioComponent != nullptr)
	//	{
	//		AudioComponent->SetVolumeMultiplier(1.0f);
	//		AudioComponent->SetPitchMultiplier(1.0f);
	//		AudioComponent->bAllowSpatialization = false;
	//		AudioComponent->bIsUISound = true;
	//		AudioComponent->bAutoDestroy = false;
	//		AudioComponent->AddToRoot();
	//	}
	//}
}
SVideoPlay::~SVideoPlay()
{
	if (MediaPlayer != nullptr)
	{
		MediaPlayer->OnMediaEvent().RemoveAll(this);

		// remove default sinks from native player
		//FMediaPlayerBase& Player = MediaPlayer->GetBasePlayer();

		/*if (MediaPlayer->GetSoundWave() == nullptr)
		{
			Player.SetAudioSink(nullptr);
		}*/

		/*if (MediaPlayer->GetVideoTexture() == nullptr)
		{
			Player.SetVideoSink(nullptr);
		}*/
	}

	// release default sinks
	/*if (AudioComponent != nullptr)
	{
		AudioComponent->Stop();
		AudioComponent->RemoveFromRoot();
	}*/

	if (Material != nullptr)
	{
		Material->RemoveFromRoot();
	}

	/*if (DefaultSoundWave != nullptr)
	{
		DefaultSoundWave->RemoveFromRoot();
	}*/

	if (DefaultTexture != nullptr)
	{
		DefaultTexture->RemoveFromRoot();
	}
}
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SVideoPlay::Construct(const FArguments& InArgs)
{
	OnCloseVideoPlay = InArgs._OnCloseVideoPlay;
	VideoURL = InArgs._VideoURL;
	MediaPlayer = LoadObject<UMediaPlayer>(NULL, TEXT("/Game/Common/Video/MediaPlayer.MediaPlayer"), NULL, LOAD_None, NULL);

	Material = NewObject<UMaterial>(GetTransientPackage(), NAME_None, RF_Transient | RF_Public);

	if (Material != nullptr)
	{
		TextureSampler = NewObject<UMaterialExpressionTextureSample>(Material);
		{
			TextureSampler->SamplerType = SAMPLERTYPE_Color;
		}

		FExpressionOutput& Output = TextureSampler->GetOutputs()[0];
		FExpressionInput& Input = Material->EmissiveColor;
		{
			Input.Expression = TextureSampler;
			Input.Mask = Output.Mask;
			Input.MaskR = Output.MaskR;
			Input.MaskG = Output.MaskG;
			Input.MaskB = Output.MaskB;
			Input.MaskA = Output.MaskA;
		}

		Material->Expressions.Add(TextureSampler);
		Material->MaterialDomain = EMaterialDomain::MD_UI;
		Material->AddToRoot();
	}

	 create Slate brush
	MaterialBrush = MakeShareable(new FSlateBrush());
	{
		MaterialBrush->SetResourceObject(Material);
	}

	UpdateMaterial();
	ChildSlot
		[
			SNew(SBox)
			.WidthOverride(1000)
			.HeightOverride(1000)
			.HAlign(HAlign_Center)
			.VAlign(VAlign_Center)
			[
				SNew(SVerticalBox)
				+SVerticalBox::Slot()
				.AutoHeight()
				[
					SNew(SButton)
					.ButtonStyle(FPanelStyle::Get(), "Button_alpha")
					.OnClicked(this, &SVideoPlay::CloseVideoPlay)
					.HAlign(HAlign_Right)
					.VAlign(VAlign_Center)
					.Content()
					[
						SNew(SImage)
						.Image(FPanelStyle::GetBrush("scheme_close"))
					]
				]
				+SVerticalBox::Slot()
				[
					SNew(SImage)
					.Image(MaterialBrush.Get())
				]
			
			]
		];


	//bool IsPlay = MediaPlayer->OpenUrl(TEXT("http://127.0.0.1:8080/Marionette_RL.mp4"));
	bool IsPlay = MediaPlayer->OpenUrl(VideoURL);
	
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

void SVideoPlay::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
{
	UpdateMaterial();
	//UpdateSoundWave();
}

void SVideoPlay::UpdateMaterial()
{
	UMediaTexture* Texture = MediaPlayer->GetVideoTexture();

	//if (Texture == nullptr)
	//{
	//	// create default texture if needed
	//	if (DefaultTexture == nullptr)
	//	{
	//		DefaultTexture = NewObject<UMediaTexture>(GetTransientPackage(), NAME_None, RF_Transient | RF_Public);

	//		if (DefaultTexture != nullptr)
	//		{
	//			DefaultTexture->UpdateResource();
	//			DefaultTexture->AddToRoot();
	//		}
	//	}

	//	// set default texture as output sink
	//	if (DefaultTexture != nullptr)
	//	{
	//		MediaPlayer->GetBasePlayer().SetVideoSink(DefaultTexture);
	//	}

	//	Texture = DefaultTexture;
	//}

	// assign new texture to material
	if (Texture != CurrentTexture)
	{
		TextureSampler->Texture = Texture;
		Material->PostEditChange();
		CurrentTexture = Texture;
	}

	// resize current texture
	if (CurrentTexture != nullptr)
	{
		
		MaterialBrush->ImageSize.X = CurrentTexture->GetSurfaceWidth();
		MaterialBrush->ImageSize.Y = CurrentTexture->GetSurfaceHeight();
	}
	else
	{
		MaterialBrush->ImageSize = FVector2D::ZeroVector;
	}
}
FReply SVideoPlay::CloseVideoPlay()
{
	if (OnCloseVideoPlay.IsBound())
	{
		OnCloseVideoPlay.Execute();
	}
	//OnCloseVideoPlay.ExecuteIfBound();
	return FReply::Handled();
}

  音频部分注释掉了,如果需要,自己完善吧。

  

转载于:https://www.cnblogs.com/staticmao/p/6724104.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值