正常特效数据保存切换
This commit is contained in:
parent
5fabd46016
commit
f859840d7b
BIN
DefaultProject/Dataset/CustomInputPanel.bin
Normal file
BIN
DefaultProject/Dataset/CustomInputPanel.bin
Normal file
Binary file not shown.
64
DefaultProject/DefaultProject.xml
Normal file
64
DefaultProject/DefaultProject.xml
Normal file
@ -0,0 +1,64 @@
|
||||
<Project(DefaultProject)>
|
||||
<Standard>
|
||||
<File>
|
||||
<Author>Sch</Author>
|
||||
</File>
|
||||
</Standard>
|
||||
<DeviceList>
|
||||
<PlayerLightList/>
|
||||
<DMLightList/>
|
||||
<GuangZhenList>
|
||||
<GuangZhen>
|
||||
<ID>2</ID>
|
||||
<RoleName>光阵</RoleName>
|
||||
</GuangZhen>
|
||||
</GuangZhenList>
|
||||
<RotationSpeakerList>
|
||||
<RotationSpeaker>
|
||||
<ID>0</ID>
|
||||
<RoleName>音频R</RoleName>
|
||||
</RotationSpeaker>
|
||||
</RotationSpeakerList>
|
||||
<ProjectorList>
|
||||
<Projector>
|
||||
<ID>1</ID>
|
||||
<RoleName>投影仪</RoleName>
|
||||
</Projector>
|
||||
</ProjectorList>
|
||||
</DeviceList>
|
||||
<CardList>
|
||||
<Card>
|
||||
<ID>0</ID>
|
||||
<Type>0</Type>
|
||||
<Times/>
|
||||
<Step/>
|
||||
<SpecialEffectID/>
|
||||
<SerialNumberList/>
|
||||
</Card>
|
||||
</CardList>
|
||||
<KeyBoard/>
|
||||
<ProcessList>
|
||||
<ProcessA>
|
||||
<ProcessB>
|
||||
<ID/>
|
||||
<AutoNext/>
|
||||
<TimeLength/>
|
||||
<SoundList>
|
||||
<Sound>
|
||||
<URL/>
|
||||
<Loop/>
|
||||
<Mode/>
|
||||
<Round/>
|
||||
<Timecode/>
|
||||
<VolumeEventList>
|
||||
<VolumeEvent>
|
||||
<TimeCode/>
|
||||
<Value/>
|
||||
</VolumeEvent>
|
||||
</VolumeEventList>
|
||||
</Sound>
|
||||
</SoundList>
|
||||
</ProcessB>
|
||||
</ProcessA>
|
||||
</ProcessList>
|
||||
</Project(DefaultProject)>
|
BIN
DefaultProject/DefaultProject_Link.cutlink
Normal file
BIN
DefaultProject/DefaultProject_Link.cutlink
Normal file
Binary file not shown.
BIN
Resources/EffectCardUnSelected.png
Normal file
BIN
Resources/EffectCardUnSelected.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 447 B |
@ -36,6 +36,10 @@ public:
|
||||
virtual void OpenTimeline(const FString& TimelineName, bool NeedSaveBefore = false) {};
|
||||
virtual void OpenProject(const FString& Project) {};
|
||||
virtual void ExportProject(const FString& ExportPath) {};
|
||||
virtual void ImportProject(const FString& ImportPath) {};
|
||||
virtual FString GetGroupName(TSharedPtr<class IWidgetInterface> WidgetInterface) { return FString(); };
|
||||
virtual FTimelinePropertyData* GetResourcePropertyDataPtr(FGuid GUID) { return nullptr; };
|
||||
|
||||
|
||||
virtual void OnSelectCard(const FGuid& SelectedCard) {};
|
||||
};
|
||||
|
@ -1,5 +1,8 @@
|
||||
#include "FFMPEGUtils.h"
|
||||
|
||||
#include "ImageUtils.h"
|
||||
#include "Utils.h"
|
||||
|
||||
|
||||
FString FFFMPEGUtils::LoadMedia(const FString& Path, FTimelinePropertyData* PropertyData)
|
||||
{
|
||||
@ -8,6 +11,11 @@ FString FFFMPEGUtils::LoadMedia(const FString& Path, FTimelinePropertyData* Prop
|
||||
{
|
||||
check(false)
|
||||
}
|
||||
if (avformat_find_stream_info(FormatContext, nullptr) < 0)
|
||||
{
|
||||
check(false)
|
||||
}
|
||||
PropertyData->MovieFrameLength = FormatContext->duration / AV_TIME_BASE * 30;
|
||||
int32 VideoStream = -1;
|
||||
int32 AudioStream = -1;
|
||||
for (unsigned int i = 0; i < FormatContext->nb_streams; i++) {
|
||||
@ -33,6 +41,57 @@ FString FFFMPEGUtils::LoadMedia(const FString& Path, FTimelinePropertyData* Prop
|
||||
}
|
||||
PropertyData->VideoCodec = VideoCodec;
|
||||
PropertyData->VideoCodecContext = VideoCodecContext;
|
||||
|
||||
AVPacket* Packet = av_packet_alloc();
|
||||
AVFrame* Frame = av_frame_alloc();
|
||||
while (av_read_frame(FormatContext, Packet) >= 0)
|
||||
{
|
||||
if (avcodec_send_packet(VideoCodecContext, Packet) < 0)
|
||||
{
|
||||
|
||||
}
|
||||
if (avcodec_receive_frame(VideoCodecContext, Frame) >= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
if (Frame)
|
||||
{
|
||||
struct SwsContext* swsCtx = sws_getContext(
|
||||
Frame->width, Frame->height, VideoCodecContext->pix_fmt,
|
||||
Frame->width, Frame->height, AV_PIX_FMT_RGBA,
|
||||
SWS_BILINEAR, NULL, NULL, NULL
|
||||
);
|
||||
if (!swsCtx)
|
||||
{
|
||||
UE_LOG(LogTemp, Error, TEXT("Error creating swsContext"));
|
||||
}
|
||||
uint8* RawData = new uint8[Frame->width * Frame->height * 4];
|
||||
uint8* dest[4] = {RawData, 0, 0, 0};
|
||||
int32 dest_linesize[4] = {Frame->width * 4, 0, 0, 0};
|
||||
sws_scale(swsCtx, Frame->data, Frame->linesize, 0, Frame->height, dest, dest_linesize);
|
||||
sws_freeContext(swsCtx);
|
||||
|
||||
|
||||
UTexture2D* Texture = UTexture2D::CreateTransient(Frame->width, Frame->height, PF_B8G8R8A8);
|
||||
if (Texture)
|
||||
{
|
||||
void* MipData = Texture->GetPlatformData()->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
|
||||
FMemory::Memcpy(MipData, RawData, Frame->width * Frame->height * 4);
|
||||
Texture->GetPlatformData()->Mips[0].BulkData.Unlock();
|
||||
Texture->UpdateResource();
|
||||
|
||||
FGuid Guid = FGuid::NewGuid();
|
||||
ExportImage(Texture, *FPaths::Combine(FPaths::ProjectSavedDir(), FGlobalData::CurrentProjectName, "Resources", "Thumbnail", Guid.ToString() + ".png"));
|
||||
PropertyData->IconPath = FPaths::Combine(FPaths::ProjectSavedDir(), FGlobalData::CurrentProjectName, "Resources", "Thumbnail", Guid.ToString() + ".png");
|
||||
delete RawData;
|
||||
}
|
||||
}
|
||||
av_seek_frame(FormatContext, VideoStream, 0, AVSEEK_FLAG_BACKWARD);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -47,6 +106,32 @@ FString FFFMPEGUtils::LoadMedia(const FString& Path, FTimelinePropertyData* Prop
|
||||
{
|
||||
check(false)
|
||||
}
|
||||
|
||||
TArray<uint8> DataResult;
|
||||
AVPacket Packet = *av_packet_alloc();
|
||||
AVFrame* Frame = av_frame_alloc();
|
||||
while (1)
|
||||
{
|
||||
if (av_read_frame(FormatContext, &Packet) < 0)
|
||||
{
|
||||
if (av_read_frame(FormatContext, &Packet) < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
avcodec_send_packet(AudioCodecContext, &Packet);
|
||||
if (avcodec_receive_frame(AudioCodecContext, Frame) >= 0)
|
||||
{
|
||||
const uint8* Result = FUtils::ConvertTwoChannelSound2PortAudioSound(Frame->data[0], Frame->data[1], Frame->nb_samples);
|
||||
if (Result != nullptr)
|
||||
{
|
||||
DataResult.Append(Result, Frame->nb_samples * 4 * 2);
|
||||
// Pa_WriteStream(Stream, Result, Frame->nb_samples);
|
||||
}
|
||||
delete[] Result;
|
||||
}
|
||||
}
|
||||
PropertyData->AudioData = DataResult;
|
||||
PropertyData->AudioCodecContext = AudioCodecContext;
|
||||
PropertyData->AudioCodec = AudioCodec;
|
||||
}
|
||||
@ -70,7 +155,7 @@ FString FFFMPEGUtils::LoadMedia(const FString& Path, FTimelinePropertyData* Prop
|
||||
|
||||
PropertyData->Name = FPaths::GetBaseFilename(Path);
|
||||
PropertyData->MoviePath = Path;
|
||||
PropertyData->MovieFrameLength = FormatContext->duration / AV_TIME_BASE * 30;
|
||||
|
||||
|
||||
return {};
|
||||
}
|
||||
@ -93,3 +178,56 @@ FString FFFMPEGUtils::ConvertMediaGoPto1(const FString& Path)
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool FFFMPEGUtils::ExportImage(UTexture2D* Texture2D, const FString& Path)
|
||||
{
|
||||
// setup required parameters
|
||||
TextureCompressionSettings OldCompressionSettings = Texture2D->CompressionSettings;
|
||||
TextureMipGenSettings OldMipGenSettings = Texture2D->MipGenSettings;
|
||||
bool OldSRGB = Texture2D->SRGB;
|
||||
|
||||
Texture2D->CompressionSettings = TextureCompressionSettings::TC_VectorDisplacementmap;
|
||||
Texture2D->MipGenSettings = TextureMipGenSettings::TMGS_NoMipmaps;
|
||||
Texture2D->SRGB = false;
|
||||
Texture2D->UpdateResource();
|
||||
|
||||
FTexture2DMipMap& mipmap = Texture2D->PlatformData->Mips[0];
|
||||
uint8* Data = (uint8*)mipmap.BulkData.Lock(LOCK_READ_WRITE);
|
||||
//FColor* FormatedImageData = static_cast<FColor*>(mipmap.BulkData.Lock(LOCK_READ_WRITE));
|
||||
if (Data == nullptr)
|
||||
{
|
||||
mipmap.BulkData.Unlock(); // 不释放,会卡住
|
||||
Texture2D->UpdateResource();
|
||||
return false;
|
||||
}
|
||||
|
||||
int width = Texture2D->PlatformData->SizeX;
|
||||
int height = Texture2D->PlatformData->SizeY;
|
||||
TArray<FColor> nColors;
|
||||
|
||||
for (int32 y = 0; y < height; y++)
|
||||
{
|
||||
for (int32 x = 0; x < width; x++)
|
||||
{
|
||||
FColor bColor;
|
||||
bColor.B = Data[(y * width + x) * 4 + 0];//B 0 - 255
|
||||
bColor.G = Data[(y * width + x) * 4 + 1];//G
|
||||
bColor.R = Data[(y * width + x) * 4 + 2];//R
|
||||
bColor.A = Data[(y * width + x) * 4 + 3];//A
|
||||
nColors.Add(bColor);
|
||||
}
|
||||
}
|
||||
mipmap.BulkData.Unlock();
|
||||
|
||||
// return old parameters
|
||||
Texture2D->CompressionSettings = OldCompressionSettings;
|
||||
Texture2D->MipGenSettings = OldMipGenSettings;
|
||||
Texture2D->SRGB = OldSRGB;
|
||||
|
||||
Texture2D->UpdateResource();
|
||||
|
||||
//获取 uint8 数据,保存
|
||||
TArray<uint8> ImgData;
|
||||
FImageUtils::CompressImageArray(width, height, nColors, ImgData);
|
||||
return FFileHelper::SaveArrayToFile(ImgData, *Path);
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
#pragma once
|
||||
#include "ImageUtils.h"
|
||||
#include "Cut5/Widgets/DefineGlobal.h"
|
||||
|
||||
|
||||
extern "C"{
|
||||
#include <libavformat/avformat.h>
|
||||
#include <libswscale/swscale.h>
|
||||
}
|
||||
struct FFFMPEGUtils
|
||||
{
|
||||
@ -13,4 +15,6 @@ struct FFFMPEGUtils
|
||||
*/
|
||||
static FString LoadMedia(const FString& Path, FTimelinePropertyData* PropertyData);
|
||||
static FString ConvertMediaGoPto1(const FString& Path);
|
||||
static bool ExportImage(UTexture2D* Texture2D, const FString& Path);
|
||||
|
||||
};
|
||||
|
@ -110,5 +110,10 @@ FSaveModifier::~FSaveModifier()
|
||||
{
|
||||
MemoryWriter << TrackData[i];
|
||||
}
|
||||
if (bNewSavePath)
|
||||
{
|
||||
FFileHelper::SaveArrayToFile(SavedData, *NewSavePath);
|
||||
return;
|
||||
}
|
||||
FFileHelper::SaveArrayToFile(SavedData, *FullSavedPath);
|
||||
}
|
||||
|
@ -47,4 +47,6 @@ public:
|
||||
int32 GroupLength = 0;
|
||||
TArray<FString> GroupName;
|
||||
TArray<FTrackData> TrackData;
|
||||
bool bNewSavePath = false;
|
||||
FString NewSavePath = "";
|
||||
};
|
||||
|
@ -76,8 +76,26 @@ void SCurtainPanel::Construct(const FArguments& InArgs)
|
||||
MainWidgetInterface->ExportProject(String);
|
||||
return FReply::Handled();
|
||||
})
|
||||
.Text(FText::FromString(TEXT("导出")))
|
||||
]
|
||||
|
||||
]
|
||||
+ SVerticalBox::Slot()
|
||||
.SizeParam(FAuto())
|
||||
[
|
||||
SNew(SBox)
|
||||
.WidthOverride(100)
|
||||
.HeightOverride(50)
|
||||
[
|
||||
SNew(SButton)
|
||||
.OnClicked_Lambda([this]()
|
||||
{
|
||||
MainWidgetInterface->ImportProject("");
|
||||
return FReply::Handled();
|
||||
})
|
||||
.Text(FText::FromString(TEXT("导入")))
|
||||
]
|
||||
|
||||
]
|
||||
+ SVerticalBox::Slot()
|
||||
.SizeParam(FAuto())
|
||||
|
@ -190,13 +190,26 @@ struct CUT5_API FTimelinePropertyData
|
||||
int32 VideoStream = -1;
|
||||
int32 AudioStream = -1;
|
||||
|
||||
// Movie Data
|
||||
// Base Data
|
||||
FString MoviePath = "";
|
||||
int32 MovieFrameLength = 0;
|
||||
TObjectPtr<USoundWave> Sound;
|
||||
|
||||
// Audio Data
|
||||
TArray<uint8> AudioData;
|
||||
|
||||
friend FArchive& operator<<(FArchive& Ar, FTimelinePropertyData& PropertyData)
|
||||
{
|
||||
Ar << PropertyData.Guid;
|
||||
Ar << PropertyData.Name;
|
||||
Ar << PropertyData.Type;
|
||||
Ar << PropertyData.IconPath;
|
||||
Ar << PropertyData.MoviePath;
|
||||
Ar << PropertyData.MovieFrameLength;
|
||||
Ar << PropertyData.AudioData;
|
||||
Ar << PropertyData.VideoStream;
|
||||
Ar << PropertyData.AudioStream;
|
||||
Ar << PropertyData.MoviePath;
|
||||
Ar << PropertyData.MovieFrameLength;
|
||||
return Ar;
|
||||
}
|
||||
};
|
||||
|
||||
class CUT5_API FCutDragDropBase : public FDecoratedDragDropOp
|
||||
@ -273,7 +286,7 @@ struct CUT5_API FEffectCardProperty
|
||||
FGuid Guid = FGuid::NewGuid();
|
||||
FString Name = "";
|
||||
FTimelineInfo TimelineInfo;
|
||||
|
||||
bool bIsActive = false;
|
||||
friend FArchive& operator<<(FArchive& Ar, FEffectCardProperty& EffectCardProperty)
|
||||
{
|
||||
Ar << EffectCardProperty.Guid;
|
||||
@ -290,7 +303,9 @@ struct CUT5_API FEffectCardGroup
|
||||
bool bIsDedicated = false;
|
||||
bool bCanEditName = false;
|
||||
bool bIsExpanded = true;
|
||||
|
||||
bool bIsActive = false;
|
||||
FGuid Guid = FGuid::NewGuid();
|
||||
FTimelineInfo TimelineInfo;
|
||||
friend FArchive& operator<<(FArchive& Ar, FEffectCardGroup& EffectCard)
|
||||
{
|
||||
Ar << EffectCard.GroupName;
|
||||
@ -298,6 +313,8 @@ struct CUT5_API FEffectCardGroup
|
||||
Ar << EffectCard.bIsDedicated;
|
||||
Ar << EffectCard.bCanEditName;
|
||||
Ar << EffectCard.bIsExpanded;
|
||||
Ar << EffectCard.Guid;
|
||||
Ar << EffectCard.TimelineInfo;
|
||||
return Ar;
|
||||
};
|
||||
};
|
||||
|
@ -7,23 +7,27 @@
|
||||
|
||||
#include "Cut5/Utils/Utils.h"
|
||||
#include "Cut5/Widgets/MicroWidgets/SClickEditableText.h"
|
||||
#include "Widgets/Text/SInlineEditableTextBlock.h"
|
||||
|
||||
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
|
||||
void SEffectCard::OnNameEdited(FString New, FString Old)
|
||||
{
|
||||
CardProperty->Name = New;
|
||||
SetSavePath({TEXT("FX"), TEXT("SingleCard"), New + TEXT(".bin")});
|
||||
if (!IFileManager::Get().FileExists(*GetSavePath()))
|
||||
if (!IFileManager::Get().FileExists(*FUtils::SingleCardFullPath(CardProperty->Name)))
|
||||
{
|
||||
TArray<uint8> BinaryData;
|
||||
FFileHelper::LoadFileToArray(BinaryData, *CardProperty->TimelineInfo.CurrentOpenFullPath);
|
||||
CardProperty->TimelineInfo.CurrentOpenFullPath = FUtils::SingleCardFullPath(CardProperty->Name);
|
||||
FFileHelper::SaveArrayToFile(BinaryData, *CardProperty->TimelineInfo.CurrentOpenFullPath);
|
||||
{
|
||||
FSaveModifier SaveModifier(CardProperty->TimelineInfo.CurrentOpenFullPath);
|
||||
SaveModifier.TimelineInfo.CurrentOpenFullPath = FUtils::SingleCardFullPath(CardProperty->Name);
|
||||
SaveModifier.bNewSavePath = true;
|
||||
SaveModifier.NewSavePath = FUtils::SingleCardFullPath(CardProperty->Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +36,6 @@ void SEffectCard::Construct(const FArguments& InArgs)
|
||||
CardProperty = InArgs._CardProperty;
|
||||
GroupName = InArgs._GroupName;
|
||||
MainInterface = InArgs._MainInterface;
|
||||
SetSavePath({TEXT("FX"), TEXT("SingleCard"), CardProperty->Name + TEXT(".bin")});
|
||||
ChildSlot
|
||||
[
|
||||
SNew(SBox)
|
||||
@ -40,31 +43,38 @@ void SEffectCard::Construct(const FArguments& InArgs)
|
||||
.HeightOverride(125.0f)
|
||||
[
|
||||
SNew(SOverlay)
|
||||
// + SOverlay::Slot()
|
||||
// [
|
||||
// SNew(SButton)
|
||||
// ]
|
||||
+ SOverlay::Slot()
|
||||
[
|
||||
SNew(SButton)
|
||||
]
|
||||
+ SOverlay::Slot()
|
||||
.VAlign(VAlign_Fill)
|
||||
.HAlign(HAlign_Fill)
|
||||
[
|
||||
SNew(SImage)
|
||||
.Visibility(EVisibility::HitTestInvisible)
|
||||
.Image(FUtils::GetBrushFromImage(FUtils::GetResourcesPath("EffectCard.png"), FVector2D(125.0, 125.0)))
|
||||
.Image(CardProperty->bIsActive ? FUtils::GetBrushFromImage(FUtils::GetResourcesPath("EffectCard.png"), FVector2D(125.0, 125.0)) :
|
||||
FUtils::GetBrushFromImage(FUtils::GetResourcesPath("EffectCardUnSelected.png"), FVector2D(125.0, 125.0)))
|
||||
.OnMouseButtonDown_Lambda([this](const FGeometry&, const FPointerEvent& PointerEvent)
|
||||
{
|
||||
MainInterface->OpenTimeline(FUtils::SingleCardFullPath(CardProperty->TimelineInfo.CurrentOpenFullPath), true);
|
||||
MainInterface->OpenTimeline(FUtils::SingleCardFullPath(CardProperty->Name), true);
|
||||
MainInterface->OnSelectCard(CardProperty->Guid);
|
||||
return FReply::Handled();
|
||||
})
|
||||
]
|
||||
+ SOverlay::Slot()
|
||||
.VAlign(VAlign_Center)
|
||||
.HAlign(HAlign_Center)
|
||||
[
|
||||
SNew(SClickEditableText)
|
||||
.InitTextPtr(&CardProperty->Name)
|
||||
.OnEdited_Raw(this, &SEffectCard::OnNameEdited)
|
||||
.CanEdit(true)
|
||||
.CanEdit(!CardProperty->bIsActive)
|
||||
.OnSingleClick_Lambda([this]()
|
||||
{
|
||||
MainInterface->OpenTimeline(FUtils::SingleCardFullPath(CardProperty->Name), true);
|
||||
|
||||
})
|
||||
|
||||
|
||||
]
|
||||
]
|
||||
|
||||
|
@ -13,6 +13,27 @@
|
||||
|
||||
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
|
||||
|
||||
void SEffectCardGroup::OnNameEdited(FString New, FString Old)
|
||||
{
|
||||
EffectCardGroup->GroupName = New;
|
||||
if (!IFileManager::Get().FileExists(*FUtils::GroupFullPath(EffectCardGroup->GroupName)))
|
||||
{
|
||||
TArray<uint8> BinaryData;
|
||||
FFileHelper::LoadFileToArray(BinaryData, *EffectCardGroup->TimelineInfo.CurrentOpenFullPath);
|
||||
{
|
||||
FSaveModifier SaveModifier(EffectCardGroup->TimelineInfo.CurrentOpenFullPath);
|
||||
SaveModifier.TimelineInfo.CurrentOpenFullPath = FUtils::GroupFullPath(EffectCardGroup->GroupName);
|
||||
SaveModifier.bNewSavePath = true;
|
||||
SaveModifier.NewSavePath = FUtils::GroupFullPath(EffectCardGroup->GroupName);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void SEffectCardGroup::Construct(const FArguments& InArgs)
|
||||
{
|
||||
EffectCardGroup = InArgs._EffectCardGroup;
|
||||
@ -38,12 +59,15 @@ void SEffectCardGroup::Construct(const FArguments& InArgs)
|
||||
.InitTextPtr(&EffectCardGroup->GroupName)
|
||||
.CanEdit(EffectCardGroup->bCanEditName)
|
||||
.IsNeedUpright(false)
|
||||
.OnEdited_Raw(this, &SEffectCardGroup::OnNameEdited)
|
||||
]
|
||||
.BodyContent()
|
||||
[
|
||||
SNew(SBorder)
|
||||
.HAlign(HAlign_Fill)
|
||||
.VAlign(VAlign_Fill)
|
||||
// .ColorAndOpacity(EffectCardGroup->bIsDedicated ? FLinearColor(0.5, 0.5, 0.5, 1) :
|
||||
// EffectCardGroup->bIsActive ? FLinearColor(1, 0, 0, 1) : FLinearColor(0.5, 0.5, 0.5, 1))
|
||||
[
|
||||
SNew(SOverlay)
|
||||
+ SOverlay::Slot()
|
||||
|
@ -23,6 +23,7 @@ public:
|
||||
SLATE_ARGUMENT(ICutMainWidgetInterface*, MainInterface)
|
||||
SLATE_END_ARGS()
|
||||
|
||||
void OnNameEdited(FString New, FString Old);
|
||||
/** Constructs this widget with InArgs */
|
||||
void Construct(const FArguments& InArgs);
|
||||
|
||||
|
@ -45,9 +45,7 @@ void SEffectCardsPanel::Construct(const FArguments& InArgs)
|
||||
DedicatedGroup.GroupName = TEXT("独立特效卡");
|
||||
EffectCardGroups.Add(DedicatedGroup);
|
||||
|
||||
FEffectCardProperty CardProperty;
|
||||
CardProperty.Name = TEXT("鲨鱼卡");
|
||||
AddNewCard(CardProperty, "");
|
||||
CallRender();
|
||||
}
|
||||
|
||||
void SEffectCardsPanel::CallRender()
|
||||
@ -82,6 +80,8 @@ void SEffectCardsPanel::CallRender()
|
||||
FSaveModifier SaveModifier(NewPath);
|
||||
SaveModifier.TimelineInfo.CurrentOpenFullPath = NewPath;
|
||||
}
|
||||
Group->TimelineInfo.CurrentOpenFullPath = NewPath;
|
||||
CallRender();
|
||||
return FReply::Handled();
|
||||
})
|
||||
]
|
||||
@ -193,4 +193,54 @@ FEffectCardGroup* SEffectCardsPanel::GetDedicatedGroupFromName()
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SEffectCardsPanel::SelectCard(const FGuid& Guid)
|
||||
{
|
||||
if (Guid == CurrentSelectedCardGuid)
|
||||
{
|
||||
MainInterface->OpenTimeline(FUtils::MainSaveFullPath());
|
||||
CurrentSelectedCardGuid.Invalidate();
|
||||
CallRender();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (FEffectCardGroup& EffectCardGroup : EffectCardGroups)
|
||||
{
|
||||
if (EffectCardGroup.bIsDedicated)
|
||||
{
|
||||
for (FEffectCardProperty& Property : EffectCardGroup.Cards)
|
||||
{
|
||||
Property.bIsActive = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EffectCardGroup.bIsActive = false;
|
||||
}
|
||||
}
|
||||
CurrentSelectedCardGuid = Guid;
|
||||
}
|
||||
for (FEffectCardGroup& EffectCardGroup : EffectCardGroups)
|
||||
{
|
||||
if (EffectCardGroup.bIsDedicated)
|
||||
{
|
||||
for (FEffectCardProperty& Property : EffectCardGroup.Cards)
|
||||
{
|
||||
if (Guid == Property.Guid)
|
||||
{
|
||||
Property.bIsActive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (EffectCardGroup.Guid == Guid)
|
||||
{
|
||||
EffectCardGroup.bIsActive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
CallRender();
|
||||
|
||||
}
|
||||
|
||||
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
|
@ -83,5 +83,9 @@ public:
|
||||
* @return Dedicated Group Ptr.
|
||||
*/
|
||||
FEffectCardGroup* GetDedicatedGroupFromName();
|
||||
|
||||
void SelectCard(const FGuid& Guid);
|
||||
|
||||
FGuid CurrentSelectedCardGuid;
|
||||
};
|
||||
|
||||
|
@ -154,17 +154,24 @@ void SCustomInputPanel::Construct(const FArguments& InArgs)
|
||||
{
|
||||
FTimelinePropertyData Data;
|
||||
FFFMPEGUtils::LoadMedia(OpenFileName[i], &Data);
|
||||
GridPanel->AddSlot(GridPanel->GetChildren()->Num() % 2, GridPanel->GetChildren()->Num() / 2)
|
||||
[
|
||||
SNew(SCustomInputResource)
|
||||
.PropertyData(Data)
|
||||
];
|
||||
PropertyData.Add(Data);
|
||||
return FReply::Handled();
|
||||
}
|
||||
else
|
||||
{
|
||||
FTimelinePropertyData Data;
|
||||
FFFMPEGUtils::LoadMedia(OpenFileName[i], &Data);
|
||||
GridPanel->AddSlot(GridPanel->GetChildren()->Num() % 3, GridPanel->GetChildren()->Num() / 3)
|
||||
GridPanel->AddSlot(GridPanel->GetChildren()->Num() % 2, GridPanel->GetChildren()->Num() / 2)
|
||||
[
|
||||
SNew(SCustomInputResource)
|
||||
.PropertyData(Data)
|
||||
];
|
||||
PropertyData.Add(Data);
|
||||
}
|
||||
}
|
||||
return FReply::Handled();
|
||||
@ -317,5 +324,50 @@ int SCustomInputPanel::AudioCallback(const void* input, void* output, unsigned l
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SCustomInputPanel::SavePanel(const FString& SavePlace)
|
||||
{
|
||||
TArray<uint8> NewData;
|
||||
FMemoryWriter Writer(NewData);
|
||||
int32 PropertyDataNum = PropertyData.Num();
|
||||
Writer << PropertyDataNum;
|
||||
for (FTimelinePropertyData& Data : PropertyData)
|
||||
{
|
||||
Writer << Data;
|
||||
}
|
||||
FFileHelper::SaveArrayToFile(NewData, *SavePlace);
|
||||
}
|
||||
|
||||
void SCustomInputPanel::LoadPanel(const FString& LoadPlace)
|
||||
{
|
||||
ClearPanel();
|
||||
TArray<uint8> LoadData;
|
||||
FFileHelper::LoadFileToArray(LoadData, *LoadPlace);
|
||||
FMemoryReader Reader(LoadData);
|
||||
int32 PropertyDataNum = 0;
|
||||
Reader << PropertyDataNum;
|
||||
for (int32 i = 0; i < PropertyDataNum; i++)
|
||||
{
|
||||
FTimelinePropertyData Data;
|
||||
Reader << Data;
|
||||
FTimelinePropertyData ReloadPropertyData;
|
||||
FFFMPEGUtils::LoadMedia(Data.MoviePath, &ReloadPropertyData);
|
||||
ReloadPropertyData.Guid = Data.Guid;
|
||||
|
||||
GridPanel->AddSlot(GridPanel->GetChildren()->Num() % 2, GridPanel->GetChildren()->Num() / 2)
|
||||
[
|
||||
SNew(SCustomInputResource)
|
||||
.PropertyData(ReloadPropertyData)
|
||||
];
|
||||
PropertyData.Add(ReloadPropertyData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SCustomInputPanel::ClearPanel()
|
||||
{
|
||||
GridPanel->ClearChildren();
|
||||
PropertyData.Empty();
|
||||
}
|
||||
|
||||
|
||||
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
|
@ -47,7 +47,8 @@ public:
|
||||
void *userData );
|
||||
|
||||
TSharedPtr<SWidgetSwitcher> Switcher;
|
||||
|
||||
|
||||
|
||||
TArray<FTimelinePropertyData> PropertyData;
|
||||
void SavePanel(const FString& SavePlace);
|
||||
void LoadPanel(const FString& LoadPlace);
|
||||
void ClearPanel();
|
||||
};
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "DefineGlobal.h"
|
||||
#include "SlateOptMacros.h"
|
||||
#include "Cut5/Utils/Utils.h"
|
||||
|
||||
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
|
||||
|
||||
@ -15,8 +16,8 @@ void SCustomInputResource::Construct(const FArguments& InArgs)
|
||||
ChildSlot
|
||||
[
|
||||
SNew(SBox)
|
||||
.WidthOverride(100)
|
||||
.HeightOverride(100)
|
||||
.WidthOverride(173.5)
|
||||
.HeightOverride(97.5)
|
||||
[
|
||||
SNew(SOverlay)
|
||||
+ SOverlay::Slot()
|
||||
@ -30,6 +31,7 @@ void SCustomInputResource::Construct(const FArguments& InArgs)
|
||||
.VAlign(VAlign_Fill)
|
||||
[
|
||||
SNew(SImage)
|
||||
.Image(FUtils::GetBrushFromImage(PropertyData.IconPath, {}))
|
||||
]
|
||||
|
||||
]
|
||||
|
@ -290,6 +290,8 @@ void SCutMainWindow::OnUpdateSound(uint8* Data, int32 Size)
|
||||
SoundThread->QueueAudio(Data, Size);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void SCutMainWindow::AddNewCard(FEffectCardProperty& CardProperty, FString GroupName)
|
||||
{
|
||||
EffectCardsPanel->AddNewCard(CardProperty, GroupName);
|
||||
@ -320,6 +322,7 @@ void SCutMainWindow::OpenTimeline(const FString& TimelineName, bool NeedSaveBefo
|
||||
if (CutTimeline->LoadTimeline(TimelineName, TimelineInfo))
|
||||
{
|
||||
CutTimeline->TimelineInfo = TimelineInfo;
|
||||
CutTimeline->CurrentEditDebug->SetText(FText::FromString(TEXT("当前正在编辑") + TimelineInfo.CurrentOpenFullPath));
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,6 +335,17 @@ void SCutMainWindow::OpenProject(const FString& Project)
|
||||
|
||||
void SCutMainWindow::ExportProject(const FString& ExportPath)
|
||||
{
|
||||
// Save Project Link
|
||||
TArray<uint8> Data {0};
|
||||
FMemoryWriter MemoryWriter(Data);
|
||||
FString CustomInputPanelSavePath = ExportPath + "/" + FGlobalData::CurrentProjectName + "/Dataset/" + TEXT("CustomInputPanel.bin");
|
||||
MemoryWriter << CustomInputPanelSavePath;
|
||||
CustomInputPanel->SavePanel(CustomInputPanelSavePath);
|
||||
|
||||
|
||||
FFileHelper::SaveArrayToFile(Data, *(ExportPath + "/" + FGlobalData::CurrentProjectName + "/" + FGlobalData::CurrentProjectName + TEXT("_Link.cutlink")));
|
||||
|
||||
|
||||
if (ExportPath.IsEmpty())
|
||||
return;
|
||||
tinyxml2::XMLDocument Document;
|
||||
@ -449,14 +463,46 @@ void SCutMainWindow::ExportProject(const FString& ExportPath)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
TArray<uint8> Data {0};
|
||||
FFileHelper::SaveArrayToFile(Data, *(ExportPath + "/" + FGlobalData::CurrentProjectName + "/" + FGlobalData::CurrentProjectName + TEXT(".bin")));
|
||||
Document.SaveFile(TCHAR_TO_UTF8(*(ExportPath + "/" + FGlobalData::CurrentProjectName + "/" + FGlobalData::CurrentProjectName + TEXT(".xml"))));
|
||||
}
|
||||
|
||||
void SCutMainWindow::ImportProject(const FString& ImportPath)
|
||||
{
|
||||
FString Path = FPaths::ConvertRelativePathToFull(FPaths::ProjectDir());
|
||||
IDesktopPlatform* DesktopPlatform = FDesktopPlatformModule::Get();
|
||||
if (DesktopPlatform)
|
||||
{
|
||||
const void* ParentWindowWindowHandle = FSlateApplication::Get().FindBestParentWindowHandleForDialogs(nullptr);
|
||||
FString OutFolderNames;
|
||||
bool bFolderSelected = DesktopPlatform->OpenDirectoryDialog(ParentWindowWindowHandle, TEXT("选择项目文件夹"), Path, OutFolderNames);
|
||||
if (bFolderSelected)
|
||||
{
|
||||
// 检查有没有后缀为 cutlink 的文件
|
||||
TArray<FString> Files;
|
||||
IFileManager::Get().FindFiles(Files, *OutFolderNames, TEXT("cutlink"));
|
||||
if (Files.Num() != 0)
|
||||
{
|
||||
TArray<uint8> Data;
|
||||
FFileHelper::LoadFileToArray(Data, *(OutFolderNames + "/" + Files[0]));
|
||||
FMemoryReader Reader(Data);
|
||||
FString CustomPanelInputPath = "";
|
||||
Reader << CustomPanelInputPath;
|
||||
CustomInputPanel->LoadPanel(CustomPanelInputPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
void SCutMainWindow::OnSelectCard(const FGuid& SelectedCard)
|
||||
{
|
||||
if (SelectedCard.IsValid())
|
||||
{
|
||||
EffectCardsPanel->SelectCard(SelectedCard);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
FTimelinePropertyData* SCutMainWindow::GetResourcePropertyDataPtr(FGuid GUID)
|
||||
{
|
||||
|
@ -56,7 +56,10 @@ public:
|
||||
virtual void OpenTimeline(const FString& TimelineName, bool NeedSaveBefore) override;
|
||||
virtual void OpenProject(const FString& Project) override;
|
||||
virtual void ExportProject(const FString& ExportPath) override;
|
||||
virtual void ImportProject(const FString& ImportPath) override;
|
||||
|
||||
virtual void OnSelectCard(const FGuid& SelectedCard) override;
|
||||
|
||||
virtual FTimelinePropertyData* GetResourcePropertyDataPtr(FGuid GUID) override;
|
||||
virtual FString GetGroupName(TSharedPtr<IWidgetInterface> WidgetInterface) override;
|
||||
};
|
||||
|
@ -84,6 +84,13 @@ void SCutTimeline::Construct(const FArguments& InArgs)
|
||||
SNew(SHorizontalBox)
|
||||
]
|
||||
+ SVerticalBox::Slot()
|
||||
.SizeParam(FAuto())
|
||||
[
|
||||
SAssignNew(CurrentEditDebug, STextBlock)
|
||||
.Text(FText::FromString(TEXT("当前正在编辑主面板")))
|
||||
|
||||
]
|
||||
+ SVerticalBox::Slot()
|
||||
[
|
||||
// Timeline
|
||||
SNew(SHorizontalBox)
|
||||
|
@ -96,6 +96,7 @@ public:
|
||||
TSharedPtr<SScrollBox> TrackBodyHScrollBox;
|
||||
TSharedPtr<SBox> TimelineTickBox;
|
||||
TSharedPtr<SScrollBox> TickScrollBox;
|
||||
TSharedPtr<STextBlock> CurrentEditDebug;
|
||||
|
||||
TArray<FSingleTrackGroupInstance> TrackGroupInstances;
|
||||
TArray<FTrackGroup> TrackGroups;
|
||||
|
@ -195,28 +195,10 @@ void STimelineClip::Seek(int32 Frame)
|
||||
FMemory::Memcpy(MipData, RawData, AllocatedFrame->width * AllocatedFrame->height * 4);
|
||||
Texture->GetPlatformData()->Mips[0].BulkData.Unlock();
|
||||
Texture->UpdateResource();
|
||||
|
||||
|
||||
|
||||
MainWidgetInterface->OnUpdateVideo(FGuid::NewGuid(), Texture);
|
||||
delete RawData;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
av_frame_free(&AllocatedFrame);
|
||||
|
||||
// AVFrame* frameRGBA = av_frame_alloc();
|
||||
// int numBytes = avpicture_get_size(AV_PIX_FMT_RGBA, VideoCodecContext->width, VideoCodecContext->height);
|
||||
// uint8_t* buffer = (uint8_t*)av_malloc(numBytes * sizeof(uint8_t));
|
||||
// avpicture_fill((AVPicture*)frameRGBA, buffer, AV_PIX_FMT_RGBA, VideoCodecContext->width, VideoCodecContext->height);
|
||||
// sws_scale(swsCtx, AllocatedFrame->data, AllocatedFrame->linesize, 0, VideoCodecContext->height, frameRGBA->data, frameRGBA->linesize);
|
||||
//
|
||||
// UTexture2D* texture = UTexture2D::CreateTransient(VideoCodecContext->width, VideoCodecContext->height);
|
||||
// FUpdateTextureRegion2D region(0, 0, 0, 0, VideoCodecContext->width, VideoCodecContext->height);
|
||||
// texture->UpdateTextureRegions(0, 1, ®ion, VideoCodecContext->width * 4, 4, frameRGBA->data[0]);
|
||||
// MainWidgetInterface->OnUpdateVideo(FGuid::NewGuid(), texture);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -243,8 +225,6 @@ void STimelineClip::Seek(int32 Frame)
|
||||
break;
|
||||
case ETrackType::AudioTrack:
|
||||
{
|
||||
|
||||
|
||||
if (Stream == nullptr)
|
||||
{
|
||||
Pa_Initialize();
|
||||
|
@ -95,7 +95,7 @@ void SStatePanel::Construct(const FArguments& InArgs)
|
||||
|
||||
]
|
||||
+ SOverlay::Slot()
|
||||
.HAlign(HAlign_Center)
|
||||
.HAlign(HAlign_Left)
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(SBox)
|
||||
@ -107,7 +107,7 @@ void SStatePanel::Construct(const FArguments& InArgs)
|
||||
]
|
||||
]
|
||||
+ SOverlay::Slot()
|
||||
.HAlign(HAlign_Center)
|
||||
.HAlign(HAlign_Right)
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(SBox)
|
||||
@ -127,6 +127,15 @@ void SStatePanel::Construct(const FArguments& InArgs)
|
||||
|
||||
]
|
||||
]
|
||||
+ SVerticalBox::Slot()
|
||||
.SizeParam(FAuto())
|
||||
[
|
||||
SNew(SBox)
|
||||
.HeightOverride(125.0)
|
||||
[
|
||||
SAssignNew(PlayerList2, SHorizontalBox)
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user