Merge branch 'master' of http://ddns.myredstone.top:4088/Sch/Cut5
# Conflicts: # Source/Cut5/Widgets/STimelineClip.cpp
This commit is contained in:
commit
991260947f
60
Cut5.sln
60
Cut5.sln
@ -7,67 +7,49 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Engine", "Engine", "{233774
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Games", "Games", "{DE1F8B53-6C02-3C13-9101-A7C8D96F3FF6}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Games", "Games", "{DE1F8B53-6C02-3C13-9101-A7C8D96F3FF6}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Cut5", "Intermediate\ProjectFiles\Cut5.vcxproj", "{B95E7D0E-DB45-3765-9058-E00EBBC4B157}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UE5", "Intermediate\ProjectFiles\UE5.vcxproj", "{6EE39883-7339-3FB6-AD82-931FB137D37F}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UE5", "Intermediate\ProjectFiles\UE5.vcxproj", "{C48D0E9D-C862-3EA3-96A7-752EE9D06362}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Cut5", "Intermediate\ProjectFiles\Cut5.vcxproj", "{AF5A253A-0F37-38CE-8998-45CA936C112B}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Visualizers", "Visualizers", "{1CCEC849-CC72-4C59-8C36-2F7C38706D4C}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Visualizers", "Visualizers", "{1CCEC849-CC72-4C59-8C36-2F7C38706D4C}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
..\..\Software\UE_5.2\Engine\Extras\VisualStudioDebugging\Unreal.natvis = ..\..\Software\UE_5.2\Engine\Extras\VisualStudioDebugging\Unreal.natvis
|
D:\UE\UE_5.2\Engine\Extras\VisualStudioDebugging\Unreal.natvis = D:\UE\UE_5.2\Engine\Extras\VisualStudioDebugging\Unreal.natvis
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
DebugGame Editor|Android = DebugGame Editor|Android
|
|
||||||
DebugGame Editor|Win64 = DebugGame Editor|Win64
|
DebugGame Editor|Win64 = DebugGame Editor|Win64
|
||||||
DebugGame|Android = DebugGame|Android
|
|
||||||
DebugGame|Win64 = DebugGame|Win64
|
DebugGame|Win64 = DebugGame|Win64
|
||||||
Development Editor|Android = Development Editor|Android
|
|
||||||
Development Editor|Win64 = Development Editor|Win64
|
Development Editor|Win64 = Development Editor|Win64
|
||||||
Development|Android = Development|Android
|
|
||||||
Development|Win64 = Development|Win64
|
Development|Win64 = Development|Win64
|
||||||
Shipping|Android = Shipping|Android
|
|
||||||
Shipping|Win64 = Shipping|Win64
|
Shipping|Win64 = Shipping|Win64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
# UnrealVS Section
|
# UnrealVS Section
|
||||||
GlobalSection(ddbf523f-7eb6-4887-bd51-85a714ff87eb) = preSolution
|
GlobalSection(ddbf523f-7eb6-4887-bd51-85a714ff87eb) = preSolution
|
||||||
AvailablePlatforms=Win64;Android
|
AvailablePlatforms=Win64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.DebugGame Editor|Android.ActiveCfg = Invalid|x64
|
{6EE39883-7339-3FB6-AD82-931FB137D37F}.DebugGame Editor|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.DebugGame Editor|Win64.ActiveCfg = DebugGame_Editor|x64
|
{6EE39883-7339-3FB6-AD82-931FB137D37F}.DebugGame|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.DebugGame Editor|Win64.Build.0 = DebugGame_Editor|x64
|
{6EE39883-7339-3FB6-AD82-931FB137D37F}.Development Editor|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.DebugGame|Android.ActiveCfg = Android_DebugGame|Win64
|
{6EE39883-7339-3FB6-AD82-931FB137D37F}.Development|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.DebugGame|Android.Build.0 = Android_DebugGame|Win64
|
{6EE39883-7339-3FB6-AD82-931FB137D37F}.Shipping|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.DebugGame|Win64.ActiveCfg = DebugGame|x64
|
{AF5A253A-0F37-38CE-8998-45CA936C112B}.DebugGame Editor|Win64.ActiveCfg = DebugGame_Editor|x64
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.DebugGame|Win64.Build.0 = DebugGame|x64
|
{AF5A253A-0F37-38CE-8998-45CA936C112B}.DebugGame Editor|Win64.Build.0 = DebugGame_Editor|x64
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Development Editor|Android.ActiveCfg = Invalid|x64
|
{AF5A253A-0F37-38CE-8998-45CA936C112B}.DebugGame|Win64.ActiveCfg = DebugGame|x64
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Development Editor|Win64.ActiveCfg = Development_Editor|x64
|
{AF5A253A-0F37-38CE-8998-45CA936C112B}.DebugGame|Win64.Build.0 = DebugGame|x64
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Development Editor|Win64.Build.0 = Development_Editor|x64
|
{AF5A253A-0F37-38CE-8998-45CA936C112B}.Development Editor|Win64.ActiveCfg = Development_Editor|x64
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Development|Android.ActiveCfg = Android_Development|Win64
|
{AF5A253A-0F37-38CE-8998-45CA936C112B}.Development Editor|Win64.Build.0 = Development_Editor|x64
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Development|Android.Build.0 = Android_Development|Win64
|
{AF5A253A-0F37-38CE-8998-45CA936C112B}.Development|Win64.ActiveCfg = Development|x64
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Development|Win64.ActiveCfg = Development|x64
|
{AF5A253A-0F37-38CE-8998-45CA936C112B}.Development|Win64.Build.0 = Development|x64
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Development|Win64.Build.0 = Development|x64
|
{AF5A253A-0F37-38CE-8998-45CA936C112B}.Shipping|Win64.ActiveCfg = Shipping|x64
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Shipping|Android.ActiveCfg = Android_Shipping|Win64
|
{AF5A253A-0F37-38CE-8998-45CA936C112B}.Shipping|Win64.Build.0 = Shipping|x64
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Shipping|Android.Build.0 = Android_Shipping|Win64
|
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Shipping|Win64.ActiveCfg = Shipping|x64
|
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157}.Shipping|Win64.Build.0 = Shipping|x64
|
|
||||||
{C48D0E9D-C862-3EA3-96A7-752EE9D06362}.DebugGame Editor|Android.ActiveCfg = BuiltWithUnrealBuildTool|Win64
|
|
||||||
{C48D0E9D-C862-3EA3-96A7-752EE9D06362}.DebugGame Editor|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64
|
|
||||||
{C48D0E9D-C862-3EA3-96A7-752EE9D06362}.DebugGame|Android.ActiveCfg = BuiltWithUnrealBuildTool|Win64
|
|
||||||
{C48D0E9D-C862-3EA3-96A7-752EE9D06362}.DebugGame|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64
|
|
||||||
{C48D0E9D-C862-3EA3-96A7-752EE9D06362}.Development Editor|Android.ActiveCfg = BuiltWithUnrealBuildTool|Win64
|
|
||||||
{C48D0E9D-C862-3EA3-96A7-752EE9D06362}.Development Editor|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64
|
|
||||||
{C48D0E9D-C862-3EA3-96A7-752EE9D06362}.Development|Android.ActiveCfg = BuiltWithUnrealBuildTool|Win64
|
|
||||||
{C48D0E9D-C862-3EA3-96A7-752EE9D06362}.Development|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64
|
|
||||||
{C48D0E9D-C862-3EA3-96A7-752EE9D06362}.Shipping|Android.ActiveCfg = BuiltWithUnrealBuildTool|Win64
|
|
||||||
{C48D0E9D-C862-3EA3-96A7-752EE9D06362}.Shipping|Win64.ActiveCfg = BuiltWithUnrealBuildTool|Win64
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{C48D0E9D-C862-3EA3-96A7-752EE9D06362} = {233774A8-CC9D-3FA9-86D1-90573E92B704}
|
{6EE39883-7339-3FB6-AD82-931FB137D37F} = {233774A8-CC9D-3FA9-86D1-90573E92B704}
|
||||||
{B95E7D0E-DB45-3765-9058-E00EBBC4B157} = {DE1F8B53-6C02-3C13-9101-A7C8D96F3FF6}
|
{AF5A253A-0F37-38CE-8998-45CA936C112B} = {DE1F8B53-6C02-3C13-9101-A7C8D96F3FF6}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
@ -40,7 +40,7 @@ public:
|
|||||||
virtual void PreSettingBeforeSeek() {};
|
virtual void PreSettingBeforeSeek() {};
|
||||||
|
|
||||||
virtual void AddNewCard(FEffectCardProperty& CardProperty, FString GroupName) {};
|
virtual void AddNewCard(FEffectCardProperty& CardProperty, FString GroupName) {};
|
||||||
virtual void OpenTimeline(const FString& TimelineName, bool NeedSaveBefore = false, bool ForceOpen = false) {};
|
virtual void OpenTimelineWithRelativePath(const FString& TimelineRelativePath, bool NeedSaveBefore = false, bool ForceOpen = false) {};
|
||||||
virtual void CloseTimeline() {};
|
virtual void CloseTimeline() {};
|
||||||
virtual bool OpenProject(const FString& Project) { return false; };
|
virtual bool OpenProject(const FString& Project) { return false; };
|
||||||
virtual bool PreNewProject() { return false; };
|
virtual bool PreNewProject() { return false; };
|
||||||
|
@ -1,11 +1,16 @@
|
|||||||
#include "VideoThumbnailThread.h"
|
#include "VideoThumbnailThread.h"
|
||||||
|
|
||||||
#include "Cut5/Utils/FFMPEGUtils.h"
|
#include "Cut5/Utils/FFMPEGUtils.h"
|
||||||
|
#include "Cut5/Utils/Utils.h"
|
||||||
|
|
||||||
FVideoThumbnailThread::FVideoThumbnailThread(const FString& MoviePath, TFunction<void(FString)> OnFinished)
|
FVideoThumbnailThread::FVideoThumbnailThread(const FString& MoviePath, TFunction<void(FString)> OnFinished, int32 BrushCount, const FClipData ClipData)
|
||||||
{
|
{
|
||||||
this->MoviePath = MoviePath;
|
this->MoviePath = MoviePath;
|
||||||
this->OnFinished = OnFinished;
|
this->OnFinished = OnFinished;
|
||||||
|
this->BrushCount = BrushCount;
|
||||||
|
this->ClipData = ClipData;
|
||||||
|
|
||||||
|
bMissionStart = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 FVideoThumbnailThread::Run()
|
uint32 FVideoThumbnailThread::Run()
|
||||||
@ -18,32 +23,96 @@ uint32 FVideoThumbnailThread::Run()
|
|||||||
FTimelinePropertyData Info;
|
FTimelinePropertyData Info;
|
||||||
FFFMPEGUtils::LoadContextPure(MoviePath, &Info);
|
FFFMPEGUtils::LoadContextPure(MoviePath, &Info);
|
||||||
|
|
||||||
|
int32 i = 0;
|
||||||
|
while (bMissionStart)
|
||||||
while (true)
|
|
||||||
{
|
{
|
||||||
AVPacket* Packet = av_packet_alloc();
|
if (i < BrushCount && ClipData.ResourcePropertyDataPtr && ClipData.ResourcePropertyDataPtr->Context && ClipData.ResourcePropertyDataPtr->VideoStream != -1)
|
||||||
if (av_read_frame(Info.Context, Packet) < 0)
|
|
||||||
{
|
{
|
||||||
av_packet_free(&Packet);
|
const int32 CurrentFrame = BrushCount - (BrushCount - i);
|
||||||
|
const int64 Timestamp = av_rescale_q(CurrentFrame / FGlobalData::GlobalFPS * AV_TIME_BASE, AVRational{1, AV_TIME_BASE}, Info.Context->streams[Info.VideoStream]->time_base);
|
||||||
|
av_seek_frame(Info.Context, Info.VideoStream, Timestamp, AVSEEK_FLAG_BACKWARD);
|
||||||
|
AVPacket Packet;
|
||||||
|
av_init_packet(&Packet);
|
||||||
|
AVFormatContext* FormatContext = Info.Context;
|
||||||
|
AVCodecContext* VideoCodecContext = Info.VideoCodecContext;
|
||||||
|
AVCodec* VideoCodec = Info.VideoCodec;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
if (Frame->best_effort_timestamp >= Timestamp)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (Frame)
|
||||||
|
{
|
||||||
|
if (Frame->width == 0 || Frame->height == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SwsContext* swsCtx = sws_getContext(
|
||||||
|
Frame->width, Frame->height, VideoCodecContext->pix_fmt,
|
||||||
|
Frame->width / 10, Frame->height / 10, AV_PIX_FMT_BGRA,
|
||||||
|
SWS_BILINEAR, NULL, NULL, NULL
|
||||||
|
);
|
||||||
|
if (!swsCtx)
|
||||||
|
{
|
||||||
|
UE_LOG(LogTemp, Error, TEXT("Error creating swsContext"));
|
||||||
|
}
|
||||||
|
uint8* RawData = new uint8[(Frame->width / 10) * (Frame->height / 10) * 4];
|
||||||
|
uint8* dest[4] = {RawData, 0, 0, 0};
|
||||||
|
int32 dest_linesize[4] = {(Frame->width / 10) * 4, 0, 0, 0};
|
||||||
|
sws_scale(swsCtx, Frame->data, Frame->linesize, 0, Frame->height, dest, dest_linesize);
|
||||||
|
sws_freeContext(swsCtx);
|
||||||
|
|
||||||
|
|
||||||
|
AsyncTask(ENamedThreads::GameThread, [Frame, RawData, this]()
|
||||||
|
{
|
||||||
|
UTexture2D* Texture = UTexture2D::CreateTransient(Frame->width / 10, Frame->height / 10, PF_B8G8R8A8);
|
||||||
|
if (Texture)
|
||||||
|
{
|
||||||
|
void* MipData = Texture->GetPlatformData()->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
|
||||||
|
FMemory::Memcpy(MipData, RawData, (Frame->width / 10) * (Frame->height / 10) * 4);
|
||||||
|
Texture->GetPlatformData()->Mips[0].BulkData.Unlock();
|
||||||
|
Texture->UpdateResource();
|
||||||
|
|
||||||
|
FGuid Guid = FGuid::NewGuid();
|
||||||
|
FFFMPEGUtils::ExportImage(Texture, ToFullPath(FUtils::GetProjectTempPath() / ClipData.ClipGuid.ToString() / Guid.ToString() + ".png"));
|
||||||
|
OnFinished(FUtils::GetProjectTempPath() / ClipData.ClipGuid.ToString() / Guid.ToString() + ".png");
|
||||||
|
|
||||||
|
|
||||||
|
Texture->MarkAsGarbage();
|
||||||
|
delete RawData;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bMissionStart = false;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
if (avcodec_send_packet(Info.VideoCodecContext, Packet) < 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
}
|
||||||
AVFrame* Frame = av_frame_alloc();
|
|
||||||
if (avcodec_receive_frame(Info.VideoCodecContext, Frame) >= 0)
|
|
||||||
{
|
|
||||||
|
|
||||||
int32 CurrentTime = av_rescale(Frame->best_effort_timestamp, Info.VideoCodecContext->time_base.den, AV_TIME_BASE);
|
|
||||||
UE_LOG(LogTemp, Warning, TEXT("Frame->best_effort_timestamp: %d"), CurrentTime);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Cut5/Widgets/DefineGlobal.h"
|
||||||
|
|
||||||
class FVideoThumbnailThread : public FRunnable
|
class FVideoThumbnailThread : public FRunnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FVideoThumbnailThread(const FString& MoviePath, TFunction<void(FString)> OnFinished);
|
FVideoThumbnailThread(const FString& MoviePath, TFunction<void(FString)> OnFinished, int32 BrushCount, const FClipData ClipData);
|
||||||
|
|
||||||
virtual bool Init() override { return true; }
|
virtual bool Init() override { return true; }
|
||||||
virtual uint32 Run() override;
|
virtual uint32 Run() override;
|
||||||
@ -13,5 +14,7 @@ public:
|
|||||||
|
|
||||||
FString MoviePath;
|
FString MoviePath;
|
||||||
TFunction<void(FString)> OnFinished;
|
TFunction<void(FString)> OnFinished;
|
||||||
|
int32 BrushCount;
|
||||||
|
FClipData ClipData;
|
||||||
|
bool bMissionStart = false;
|
||||||
};
|
};
|
||||||
|
@ -106,7 +106,7 @@ FString FFFMPEGUtils::LoadMedia(const FString& Path, FTimelinePropertyData* Prop
|
|||||||
|
|
||||||
FGuid Guid = FGuid::NewGuid();
|
FGuid Guid = FGuid::NewGuid();
|
||||||
ExportImage(Texture, *FPaths::Combine(FGlobalData::BasePath, FGlobalData::CurrentProjectName, "Resources", "Thumbnail", Guid.ToString() + ".png"));
|
ExportImage(Texture, *FPaths::Combine(FGlobalData::BasePath, FGlobalData::CurrentProjectName, "Resources", "Thumbnail", Guid.ToString() + ".png"));
|
||||||
PropertyData->IconPath = FPaths::Combine(FGlobalData::BasePath, FGlobalData::CurrentProjectName, "Resources", "Thumbnail", Guid.ToString() + ".png");
|
PropertyData->IconPath = FString() / TEXT("Resources") / TEXT("Thumbnail") / Guid.ToString() + ".png";
|
||||||
Texture->MarkAsGarbage();
|
Texture->MarkAsGarbage();
|
||||||
delete RawData;
|
delete RawData;
|
||||||
}
|
}
|
||||||
@ -197,7 +197,7 @@ FString FFFMPEGUtils::LoadMedia(const FString& Path, FTimelinePropertyData* Prop
|
|||||||
}
|
}
|
||||||
|
|
||||||
PropertyData->Name = FPaths::GetBaseFilename(Path);
|
PropertyData->Name = FPaths::GetBaseFilename(Path);
|
||||||
PropertyData->MoviePath = NewPath;
|
PropertyData->MoviePath = Path;
|
||||||
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
@ -205,8 +205,19 @@ FString FFFMPEGUtils::LoadMedia(const FString& Path, FTimelinePropertyData* Prop
|
|||||||
|
|
||||||
FString FFFMPEGUtils::LoadContextPure(const FString& Path, FTimelinePropertyData* PropertyData)
|
FString FFFMPEGUtils::LoadContextPure(const FString& Path, FTimelinePropertyData* PropertyData)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
FString NewPath;
|
||||||
|
if (FPaths::IsRelative(Path))
|
||||||
|
{
|
||||||
|
NewPath = FGlobalData::BasePath / FGlobalData::CurrentProjectName / Path;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NewPath = Path;
|
||||||
|
}
|
||||||
|
|
||||||
AVFormatContext* FormatContext = nullptr;
|
AVFormatContext* FormatContext = nullptr;
|
||||||
if (avformat_open_input(&FormatContext, TCHAR_TO_UTF8(*Path), nullptr, nullptr) != 0)
|
if (avformat_open_input(&FormatContext, TCHAR_TO_UTF8(*NewPath), nullptr, nullptr) != 0)
|
||||||
{
|
{
|
||||||
return TEXT("Failed");
|
return TEXT("Failed");
|
||||||
}
|
}
|
||||||
@ -268,7 +279,7 @@ FString FFFMPEGUtils::LoadContextPure(const FString& Path, FTimelinePropertyData
|
|||||||
PropertyData->Type = ETrackType::AudioTrack;
|
PropertyData->Type = ETrackType::AudioTrack;
|
||||||
}
|
}
|
||||||
PropertyData->Name = FPaths::GetBaseFilename(Path);
|
PropertyData->Name = FPaths::GetBaseFilename(Path);
|
||||||
PropertyData->MoviePath = Path;
|
PropertyData->MoviePath = NewPath;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,7 +369,7 @@ TArray<FSlateBrush> FFFMPEGUtils::GetMovieBrush(FClipData* ClipData, bool Regene
|
|||||||
{
|
{
|
||||||
for (int32 i = 0; i < ClipData->MovieBrushesPath.Num(); i++)
|
for (int32 i = 0; i < ClipData->MovieBrushesPath.Num(); i++)
|
||||||
{
|
{
|
||||||
FSlateDynamicImageBrush Brush = FSlateDynamicImageBrush(*ClipData->MovieBrushesPath[i], FVector2f(0, 0));
|
FSlateDynamicImageBrush Brush = FSlateDynamicImageBrush(*ToFullPath(ClipData->MovieBrushesPath[i]), FVector2f(0, 0));
|
||||||
ClipData->MovieBrushNum++;
|
ClipData->MovieBrushNum++;
|
||||||
Result.Add(Brush);
|
Result.Add(Brush);
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ FString FUtils::GetResourcesPath(FString ResourcesName, bool bFullPath)
|
|||||||
|
|
||||||
FString FUtils::GetProjectTempPath()
|
FString FUtils::GetProjectTempPath()
|
||||||
{
|
{
|
||||||
return FPaths::ConvertRelativePathToFull(FPaths::Combine(FGlobalData::BasePath / FGlobalData::CurrentProjectName / "/Temp/"));
|
return TEXT("Temp/");
|
||||||
}
|
}
|
||||||
|
|
||||||
FSlateDynamicImageBrush* FUtils::GetBrushFromImage(const FString& ImageName, const FVector2D Size)
|
FSlateDynamicImageBrush* FUtils::GetBrushFromImage(const FString& ImageName, const FVector2D Size)
|
||||||
@ -370,7 +370,7 @@ TArray<FEncodeVideoInfo> FUtils::TrackEncodeVideo(const FTrackData& TrackData, c
|
|||||||
|
|
||||||
FString StartTime = FString::Printf(TEXT("%02d:%02d:%02d.%s"), StartTimespan.GetHours(), StartTimespan.GetMinutes(), StartTimespan.GetSeconds(), *NewStartMilli);
|
FString StartTime = FString::Printf(TEXT("%02d:%02d:%02d.%s"), StartTimespan.GetHours(), StartTimespan.GetMinutes(), StartTimespan.GetSeconds(), *NewStartMilli);
|
||||||
FString EndTime = FString::Printf(TEXT("%02d:%02d:%02d.%s"), EndTimespan.GetHours(), EndTimespan.GetMinutes(), EndTimespan.GetSeconds(), *NewEndMilli);
|
FString EndTime = FString::Printf(TEXT("%02d:%02d:%02d.%s"), EndTimespan.GetHours(), EndTimespan.GetMinutes(), EndTimespan.GetSeconds(), *NewEndMilli);
|
||||||
FString InputFile = "\"" + TempClipData.ResourcePropertyDataPtr->MoviePath + "\"";
|
FString InputFile = "\"" + ToFullPath(TempClipData.ResourcePropertyDataPtr->MoviePath) + "\"";
|
||||||
|
|
||||||
|
|
||||||
FString OutputFile = "\"" + FPaths::ConvertRelativePathToFull(ExportPath + FString::FromInt(i) + TEXT(".mp4")) + "\"";
|
FString OutputFile = "\"" + FPaths::ConvertRelativePathToFull(ExportPath + FString::FromInt(i) + TEXT(".mp4")) + "\"";
|
||||||
@ -440,7 +440,7 @@ FEncodeVideoInfo FUtils::TrackEncodeAudio(const FTrackData& TrackData, const FSt
|
|||||||
|
|
||||||
FString StartTime = FString::Printf(TEXT("%02d:%02d:%02d"), StartTimespan.GetHours(), StartTimespan.GetMinutes(), StartTimespan.GetSeconds());
|
FString StartTime = FString::Printf(TEXT("%02d:%02d:%02d"), StartTimespan.GetHours(), StartTimespan.GetMinutes(), StartTimespan.GetSeconds());
|
||||||
FString EndTime = FString::Printf(TEXT("%02d:%02d:%02d"), EndTimespan.GetHours(), EndTimespan.GetMinutes(), EndTimespan.GetSeconds());
|
FString EndTime = FString::Printf(TEXT("%02d:%02d:%02d"), EndTimespan.GetHours(), EndTimespan.GetMinutes(), EndTimespan.GetSeconds());
|
||||||
FString InputFile = TempClipData.ResourcePropertyDataPtr->MoviePath;
|
FString InputFile = ToFullPath(TempClipData.ResourcePropertyDataPtr->MoviePath);
|
||||||
|
|
||||||
FString OutputFile = ExportPath + TEXT(".mp3");
|
FString OutputFile = ExportPath + TEXT(".mp3");
|
||||||
|
|
||||||
@ -632,8 +632,7 @@ TArray<FEncodeVideoInfo> FUtils::ExportPsaf(FTrackData TrackData, const FString&
|
|||||||
FString ExportName = FGuid::NewGuid().ToString();;
|
FString ExportName = FGuid::NewGuid().ToString();;
|
||||||
if (TempClipData.ResourcePropertyDataPtr)
|
if (TempClipData.ResourcePropertyDataPtr)
|
||||||
{
|
{
|
||||||
TempClipData.ResourcePropertyDataPtr->MoviePath;
|
FString TempPath = ToFullPath(TempClipData.ResourcePropertyDataPtr->MoviePath);
|
||||||
FString TempPath = TempClipData.ResourcePropertyDataPtr->MoviePath;
|
|
||||||
frames.Empty();
|
frames.Empty();
|
||||||
|
|
||||||
VideoCapture capture;
|
VideoCapture capture;
|
||||||
|
@ -2,6 +2,11 @@
|
|||||||
#include "CoreMinimal.h"
|
#include "CoreMinimal.h"
|
||||||
#include "Cut5/Widgets/DefineGlobal.h"
|
#include "Cut5/Widgets/DefineGlobal.h"
|
||||||
|
|
||||||
|
inline FString ToFullPath(const FString& String)
|
||||||
|
{
|
||||||
|
return FGlobalData::BasePath / FGlobalData::CurrentProjectName / String;
|
||||||
|
}
|
||||||
|
|
||||||
class FUtils
|
class FUtils
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -36,22 +41,20 @@ public:
|
|||||||
static TArray<FEncodeVideoInfo> TrackEncodeVideo(const FTrackData& TrackData, const FString& ExportPath);
|
static TArray<FEncodeVideoInfo> TrackEncodeVideo(const FTrackData& TrackData, const FString& ExportPath);
|
||||||
static FEncodeVideoInfo TrackEncodeAudio(const FTrackData& TrackDataLeft, const FString& ExportPath);
|
static FEncodeVideoInfo TrackEncodeAudio(const FTrackData& TrackDataLeft, const FString& ExportPath);
|
||||||
static FEncodeVideoInfo CombineAudio(const FEncodeVideoInfo& LeftEncodeData, const FEncodeVideoInfo& RightEncodeData, const FString& ExportPath);
|
static FEncodeVideoInfo CombineAudio(const FEncodeVideoInfo& LeftEncodeData, const FEncodeVideoInfo& RightEncodeData, const FString& ExportPath);
|
||||||
static FString CurtainFullPath(const FString& GroupName)
|
|
||||||
|
static FString CurtainRelativePath(const FString& GroupName)
|
||||||
{
|
{
|
||||||
return FPaths::Combine(FGlobalData::BasePath, FGlobalData::CurrentProjectName, TEXT("Curtain"), GroupName + TEXT(".bin"));
|
return TEXT("Curtain") / GroupName + TEXT(".bin");
|
||||||
};
|
};
|
||||||
static FString GroupFullPath(const FString& GroupName)
|
static FString GroupRelativePath(const FString& GroupName)
|
||||||
{
|
{
|
||||||
return FPaths::Combine(FGlobalData::BasePath, FGlobalData::CurrentProjectName, TEXT("FX"), GroupName + TEXT(".bin"));
|
return TEXT("FX") / GroupName + TEXT(".bin");
|
||||||
};
|
};
|
||||||
static FString SingleCardFullPath(const FString& CardName)
|
static FString SingleCardRelativePath(const FString& CardName)
|
||||||
{
|
{
|
||||||
return FPaths::Combine(FGlobalData::BasePath, FGlobalData::CurrentProjectName, TEXT("FX"), TEXT("SingleCard"), CardName + TEXT(".bin"));
|
return FString() / TEXT("FX") / TEXT("SingleCard") / CardName + TEXT(".bin");
|
||||||
};
|
};
|
||||||
static FString MainSaveFullPath()
|
|
||||||
{
|
|
||||||
return FPaths::Combine(FGlobalData::BasePath, FGlobalData::CurrentProjectName, FGlobalData::CurrentProjectName + TEXT(".bin"));
|
|
||||||
};
|
|
||||||
|
|
||||||
static FUtils* GetInstance()
|
static FUtils* GetInstance()
|
||||||
{
|
{
|
||||||
|
@ -163,17 +163,17 @@ TSharedPtr<FCurtainDragDrop> SCurtain::OpenThis()
|
|||||||
|
|
||||||
|
|
||||||
// 没有Curtain就Create一个
|
// 没有Curtain就Create一个
|
||||||
if (!FPaths::FileExists(FUtils::CurtainFullPath(Curtain->CurtainUUID.ToString())))
|
if (!FPaths::FileExists(ToFullPath(FUtils::CurtainRelativePath(Curtain->CurtainUUID.ToString()))))
|
||||||
{
|
{
|
||||||
FUtils::CreateDefaultTimelineSave(FUtils::CurtainFullPath(Curtain->CurtainUUID.ToString()), FTimelineInfo::ETimelineType::FX);
|
FUtils::CreateDefaultTimelineSave(ToFullPath(FUtils::CurtainRelativePath(Curtain->CurtainUUID.ToString())), FTimelineInfo::ETimelineType::FX);
|
||||||
{
|
{
|
||||||
FSaveModifier SaveModifier(FUtils::CurtainFullPath(Curtain->CurtainUUID.ToString()));
|
FSaveModifier SaveModifier(ToFullPath(FUtils::CurtainRelativePath(Curtain->CurtainUUID.ToString())));
|
||||||
SaveModifier.TimelineInfo.CurrentOpenFullPath = FUtils::CurtainFullPath(Curtain->CurtainUUID.ToString());
|
SaveModifier.TimelineInfo.CurrentOpenRelativePath = FUtils::CurtainRelativePath(Curtain->CurtainUUID.ToString());
|
||||||
SaveModifier.TimelineInfo.CurrentOpenType = FTimelineInfo::ETimelineType::FX;
|
SaveModifier.TimelineInfo.CurrentOpenType = FTimelineInfo::ETimelineType::FX;
|
||||||
Curtain->TimelineInfo = SaveModifier.TimelineInfo;
|
Curtain->TimelineInfo = SaveModifier.TimelineInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CurtainPanel->MainWidgetInterface->OpenTimeline(FUtils::CurtainFullPath(Curtain->CurtainUUID.ToString()), true);
|
CurtainPanel->MainWidgetInterface->OpenTimelineWithRelativePath(FUtils::CurtainRelativePath(Curtain->CurtainUUID.ToString()), true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -272,10 +272,10 @@ void SCurtainPanel::AddNewCurtain(int32 Index)
|
|||||||
if (Index < Groups.Num())
|
if (Index < Groups.Num())
|
||||||
{
|
{
|
||||||
FCurtain Curtain;
|
FCurtain Curtain;
|
||||||
FUtils::CreateDefaultTimelineSave(FUtils::CurtainFullPath(Curtain.CurtainUUID.ToString()), FTimelineInfo::ETimelineType::FX);
|
FUtils::CreateDefaultTimelineSave(ToFullPath(FUtils::CurtainRelativePath(Curtain.CurtainUUID.ToString())), FTimelineInfo::ETimelineType::FX);
|
||||||
{
|
{
|
||||||
FSaveModifier SaveModifier(FUtils::CurtainFullPath(Curtain.CurtainUUID.ToString()));
|
FSaveModifier SaveModifier(ToFullPath(FUtils::CurtainRelativePath(Curtain.CurtainUUID.ToString())));
|
||||||
SaveModifier.TimelineInfo.CurrentOpenFullPath = FUtils::CurtainFullPath(Curtain.CurtainUUID.ToString());
|
SaveModifier.TimelineInfo.CurrentOpenRelativePath = FUtils::CurtainRelativePath(Curtain.CurtainUUID.ToString());
|
||||||
SaveModifier.TimelineInfo.CurrentOpenType = FTimelineInfo::ETimelineType::FX;
|
SaveModifier.TimelineInfo.CurrentOpenType = FTimelineInfo::ETimelineType::FX;
|
||||||
Curtain.TimelineInfo = SaveModifier.TimelineInfo;
|
Curtain.TimelineInfo = SaveModifier.TimelineInfo;
|
||||||
}
|
}
|
||||||
|
@ -766,19 +766,22 @@ struct CUT5_API FTimelineInfo
|
|||||||
Main,
|
Main,
|
||||||
FX,
|
FX,
|
||||||
};
|
};
|
||||||
FString CurrentOpenFullPath = "";
|
FString CurrentOpenRelativePath = "";
|
||||||
|
|
||||||
FTimelineInfo::ETimelineType CurrentOpenType = ETimelineType::Main;
|
FTimelineInfo::ETimelineType CurrentOpenType = ETimelineType::Main;
|
||||||
|
|
||||||
|
|
||||||
friend FArchive& operator<<(FArchive& Ar, FTimelineInfo& TimelineInfo)
|
friend FArchive& operator<<(FArchive& Ar, FTimelineInfo& TimelineInfo)
|
||||||
{
|
{
|
||||||
Ar << TimelineInfo.CurrentOpenFullPath;
|
Ar << TimelineInfo.CurrentOpenRelativePath;
|
||||||
Ar << TimelineInfo.CurrentOpenType;
|
Ar << TimelineInfo.CurrentOpenType;
|
||||||
return Ar;
|
return Ar;
|
||||||
};
|
};
|
||||||
FString GetSavePath()
|
|
||||||
|
// 得到完整目录,考虑到项目迁移所以保存的是 相对路径, 但是在打开的时候需要转换成绝对路径
|
||||||
|
FString GetSaveFullPath()
|
||||||
{
|
{
|
||||||
return CurrentOpenFullPath;
|
return FGlobalData::BasePath / FGlobalData::CurrentProjectName / CurrentOpenRelativePath;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -819,13 +819,13 @@ void DragDropOperator::OnDrop(const FGeometry& MyGeometry, const FDragDropEvent&
|
|||||||
{
|
{
|
||||||
NewClipData.ClipType = ETrackType::PlayerTrack;
|
NewClipData.ClipType = ETrackType::PlayerTrack;
|
||||||
NewClipData.PlayerName = TrackBody->MainWidgetInterface->GetGroupName(TrackHead);
|
NewClipData.PlayerName = TrackBody->MainWidgetInterface->GetGroupName(TrackHead);
|
||||||
NewClipData.PlayerLightData = FOpencvUtils::GetVideoSingleLightColor(ClipDragOperation.TimelinePropertyData->MoviePath);
|
NewClipData.PlayerLightData = FOpencvUtils::GetVideoSingleLightColor(ToFullPath(ClipDragOperation.TimelinePropertyData->MoviePath));
|
||||||
}
|
}
|
||||||
if (TrackHead->TrackData.TrackType == ETrackType::AtomSphereLightTrack)
|
if (TrackHead->TrackData.TrackType == ETrackType::AtomSphereLightTrack)
|
||||||
{
|
{
|
||||||
NewClipData.ClipType = ETrackType::AtomSphereLightTrack;
|
NewClipData.ClipType = ETrackType::AtomSphereLightTrack;
|
||||||
NewClipData.PlayerName = TrackBody->MainWidgetInterface->GetGroupName(TrackHead);
|
NewClipData.PlayerName = TrackBody->MainWidgetInterface->GetGroupName(TrackHead);
|
||||||
NewClipData.PlayerLightData = FOpencvUtils::GetVideoSingleLightColor(ClipDragOperation.TimelinePropertyData->MoviePath);
|
NewClipData.PlayerLightData = FOpencvUtils::GetVideoSingleLightColor(ToFullPath(ClipDragOperation.TimelinePropertyData->MoviePath));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ClipDragOperation.TimelinePropertyData->Type == ETrackType::LightArrayTrack)
|
else if (ClipDragOperation.TimelinePropertyData->Type == ETrackType::LightArrayTrack)
|
||||||
|
@ -76,7 +76,7 @@ void SEffectCard::Construct(const FArguments& InArgs)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MainInterface->OpenTimeline(FUtils::SingleCardFullPath(CardProperty->Guid.ToString()), true);
|
MainInterface->OpenTimelineWithRelativePath(FUtils::SingleCardRelativePath(CardProperty->Guid.ToString()), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertiesInterfaceGUID = CardProperty->Guid;
|
PropertiesInterfaceGUID = CardProperty->Guid;
|
||||||
|
@ -474,8 +474,8 @@ void SEffectCardGroup::OnSelect()
|
|||||||
{
|
{
|
||||||
if (EffectCardGroup->bIsDedicated == false)
|
if (EffectCardGroup->bIsDedicated == false)
|
||||||
{
|
{
|
||||||
const FString Name = FPaths::Combine(FGlobalData::BasePath, FGlobalData::CurrentProjectName, TEXT("FX"), EffectCardGroup->Guid.ToString() + TEXT(".bin"));
|
const FString Name = TEXT("FX") / EffectCardGroup->Guid.ToString() + TEXT(".bin");
|
||||||
MainInterface->OpenTimeline(Name, true);
|
MainInterface->OpenTimelineWithRelativePath(Name, true);
|
||||||
MainInterface->CurrentSelectedPropertiesInterfaceGuid = EffectCardGroup->Guid;
|
MainInterface->CurrentSelectedPropertiesInterfaceGuid = EffectCardGroup->Guid;
|
||||||
MainInterface->UpdateProperties(this);
|
MainInterface->UpdateProperties(this);
|
||||||
MainInterface->GetSelf()->DeselectAll();
|
MainInterface->GetSelf()->DeselectAll();
|
||||||
@ -516,10 +516,10 @@ void SEffectCardGroup::CallRender()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
FUtils::CreateDefaultTimelineSave(FUtils::SingleCardFullPath(NewCard.Guid.ToString()), FTimelineInfo::ETimelineType::FX);
|
FUtils::CreateDefaultTimelineSave(ToFullPath(FUtils::SingleCardRelativePath(NewCard.Guid.ToString())), FTimelineInfo::ETimelineType::FX);
|
||||||
{
|
{
|
||||||
FSaveModifier SaveModifier(FUtils::SingleCardFullPath(NewCard.Guid.ToString()));
|
FSaveModifier SaveModifier(ToFullPath(FUtils::SingleCardRelativePath(NewCard.Guid.ToString())));
|
||||||
SaveModifier.TimelineInfo.CurrentOpenFullPath = FUtils::SingleCardFullPath(NewCard.Guid.ToString());
|
SaveModifier.TimelineInfo.CurrentOpenRelativePath = FUtils::SingleCardRelativePath(NewCard.Guid.ToString());
|
||||||
SaveModifier.TimelineInfo.CurrentOpenType = FTimelineInfo::ETimelineType::FX;
|
SaveModifier.TimelineInfo.CurrentOpenType = FTimelineInfo::ETimelineType::FX;
|
||||||
NewCard.TimelineInfo = SaveModifier.TimelineInfo;
|
NewCard.TimelineInfo = SaveModifier.TimelineInfo;
|
||||||
}
|
}
|
||||||
|
@ -110,13 +110,13 @@ void SEffectCardsPanel::CallRender()
|
|||||||
int32 ID = GetCurrentID(true);
|
int32 ID = GetCurrentID(true);
|
||||||
Group->ID = ID;
|
Group->ID = ID;
|
||||||
|
|
||||||
const FString NewPath = FPaths::Combine(FGlobalData::BasePath, FGlobalData::CurrentProjectName, TEXT("FX"), NewGuid.ToString() + TEXT(".bin"));
|
const FString NewPath = TEXT("FX") / NewGuid.ToString() + TEXT(".bin");
|
||||||
FUtils::CreateDefaultTimelineSave(NewPath, FTimelineInfo::ETimelineType::FX);
|
FUtils::CreateDefaultTimelineSave(ToFullPath(NewPath), FTimelineInfo::ETimelineType::FX);
|
||||||
{
|
{
|
||||||
FSaveModifier SaveModifier(NewPath);
|
FSaveModifier SaveModifier(ToFullPath(NewPath));
|
||||||
SaveModifier.TimelineInfo.CurrentOpenFullPath = NewPath;
|
SaveModifier.TimelineInfo.CurrentOpenRelativePath = NewPath;
|
||||||
}
|
}
|
||||||
Group->TimelineInfo.CurrentOpenFullPath = NewPath;
|
Group->TimelineInfo.CurrentOpenRelativePath = NewPath;
|
||||||
CallRender();
|
CallRender();
|
||||||
return FReply::Handled();
|
return FReply::Handled();
|
||||||
})
|
})
|
||||||
@ -157,7 +157,7 @@ void SEffectCardsPanel::RemoveCard(const FGuid& GUID)
|
|||||||
{
|
{
|
||||||
if (Group.bIsActive == true)
|
if (Group.bIsActive == true)
|
||||||
{
|
{
|
||||||
MainInterface->OpenTimeline(FUtils::MainSaveFullPath(), true);
|
MainInterface->OpenTimelineWithRelativePath("", true);
|
||||||
}
|
}
|
||||||
EffectCardGroups.RemoveAt(j);
|
EffectCardGroups.RemoveAt(j);
|
||||||
break;
|
break;
|
||||||
@ -170,7 +170,7 @@ void SEffectCardsPanel::RemoveCard(const FGuid& GUID)
|
|||||||
{
|
{
|
||||||
if (Group.Cards[i].bIsActive == true)
|
if (Group.Cards[i].bIsActive == true)
|
||||||
{
|
{
|
||||||
MainInterface->OpenTimeline(FUtils::MainSaveFullPath(), true);
|
MainInterface->OpenTimelineWithRelativePath("", true);
|
||||||
}
|
}
|
||||||
Group.Cards.RemoveAt(i);
|
Group.Cards.RemoveAt(i);
|
||||||
}
|
}
|
||||||
@ -193,7 +193,7 @@ void SEffectCardsPanel::RemoveCardInGroup(const FGuid& Guid, const FGuid& GroupG
|
|||||||
{
|
{
|
||||||
if (Property.bIsActive == true)
|
if (Property.bIsActive == true)
|
||||||
{
|
{
|
||||||
MainInterface->OpenTimeline(FUtils::MainSaveFullPath());
|
MainInterface->OpenTimelineWithRelativePath("");
|
||||||
}
|
}
|
||||||
Group.Cards.RemoveAt(i);
|
Group.Cards.RemoveAt(i);
|
||||||
break;
|
break;
|
||||||
@ -365,9 +365,7 @@ void SEffectCardsPanel::SavePanel(const FString& Path)
|
|||||||
{
|
{
|
||||||
for (FEffectCardProperty& Property : Group.Cards)
|
for (FEffectCardProperty& Property : Group.Cards)
|
||||||
{
|
{
|
||||||
FString Target = Property.TimelineInfo.CurrentOpenFullPath;
|
IFileManager::Get().Move(*FPaths::Combine(Path, "FX", "Cards"), *ToFullPath(Property.TimelineInfo.CurrentOpenRelativePath));
|
||||||
FPaths::CollapseRelativeDirectories(Target);
|
|
||||||
IFileManager::Get().Move(*FPaths::Combine(Path, "FX", "Cards"), *Property.TimelineInfo.CurrentOpenFullPath);
|
|
||||||
}
|
}
|
||||||
MemoryWriter << Group;
|
MemoryWriter << Group;
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ void SCustomInputResource::Construct(const FArguments& InArgs)
|
|||||||
[
|
[
|
||||||
SNew(SImage)
|
SNew(SImage)
|
||||||
.Image( (PropertyData.VideoStream == -1 && PropertyData.AudioStream != -1) ? FUtils::GetBrushFromImage(FUtils::GetResourcesPath(TEXT("Music.png")), {}) :
|
.Image( (PropertyData.VideoStream == -1 && PropertyData.AudioStream != -1) ? FUtils::GetBrushFromImage(FUtils::GetResourcesPath(TEXT("Music.png")), {}) :
|
||||||
PropertyData.bIsCustomPresetData == false ? FUtils::GetBrushFromImage(PropertyData.IconPath, {}) : FUtils::GetBrushFromImage(FUtils::GetResourcesPath("CustomPreset.png"), {}))
|
PropertyData.bIsCustomPresetData == false ? FUtils::GetBrushFromImage(ToFullPath(PropertyData.IconPath), {}) : FUtils::GetBrushFromImage(FUtils::GetResourcesPath("CustomPreset.png"), {}))
|
||||||
]
|
]
|
||||||
+ SOverlay::Slot()
|
+ SOverlay::Slot()
|
||||||
.HAlign(HAlign_Center)
|
.HAlign(HAlign_Center)
|
||||||
@ -91,7 +91,7 @@ FReply SCustomInputResource::OnDragDetected(const FGeometry& MyGeometry, const F
|
|||||||
[
|
[
|
||||||
SNew(SImage)
|
SNew(SImage)
|
||||||
.Image( (PropertyData.VideoStream == -1 && PropertyData.AudioStream != -1) ? FUtils::GetBrushFromImage(FUtils::GetResourcesPath(TEXT("Music.png")), {}) :
|
.Image( (PropertyData.VideoStream == -1 && PropertyData.AudioStream != -1) ? FUtils::GetBrushFromImage(FUtils::GetResourcesPath(TEXT("Music.png")), {}) :
|
||||||
PropertyData.bIsCustomPresetData == false ? FUtils::GetBrushFromImage(PropertyData.IconPath, {}) : FUtils::GetBrushFromImage(FUtils::GetResourcesPath("CustomPreset.png"), {}))
|
PropertyData.bIsCustomPresetData == false ? FUtils::GetBrushFromImage(ToFullPath(PropertyData.IconPath), {}) : FUtils::GetBrushFromImage(FUtils::GetResourcesPath("CustomPreset.png"), {}))
|
||||||
];
|
];
|
||||||
|
|
||||||
return FReply::Handled().BeginDragDrop(Operation.ToSharedRef());
|
return FReply::Handled().BeginDragDrop(Operation.ToSharedRef());
|
||||||
|
@ -453,7 +453,7 @@ void SCutMainWindow::Construct(const FArguments& InArgs)
|
|||||||
}));
|
}));
|
||||||
CommandList->MapAction(FShortCutCommands::Get().ZoomOutTimeline, FExecuteAction::CreateLambda([this]()
|
CommandList->MapAction(FShortCutCommands::Get().ZoomOutTimeline, FExecuteAction::CreateLambda([this]()
|
||||||
{
|
{
|
||||||
if (CutTimeline->ZoomSlider->GetValue() >= 0.1)
|
if (CutTimeline->ZoomSlider->GetValue() >= 0.0)
|
||||||
{
|
{
|
||||||
const float NewValue = CutTimeline->ZoomSlider->GetValue() - 0.1;
|
const float NewValue = CutTimeline->ZoomSlider->GetValue() - 0.1;
|
||||||
CutTimeline->UpdateZoom(NewValue);
|
CutTimeline->UpdateZoom(NewValue);
|
||||||
@ -902,37 +902,29 @@ void SCutMainWindow::AddNewCard(FEffectCardProperty& CardProperty, FString Group
|
|||||||
EffectCardsPanel->AddNewCard(CardProperty, GroupName);
|
EffectCardsPanel->AddNewCard(CardProperty, GroupName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCutMainWindow::OpenTimeline(const FString& TimelineName, bool NeedSaveBefore, bool ForceOpen)
|
void SCutMainWindow::OpenTimelineWithRelativePath(const FString& TimelineRelativePath, bool NeedSaveBefore, bool ForceOpen)
|
||||||
{
|
{
|
||||||
CutTimeline->bNeedShowPanel = true;
|
CutTimeline->bNeedShowPanel = true;
|
||||||
if (NeedSaveBefore)
|
if (NeedSaveBefore)
|
||||||
{
|
{
|
||||||
CutTimeline->SaveTimeline(CutTimeline->TimelineInfo.CurrentOpenFullPath, CutTimeline->TimelineInfo);
|
CutTimeline->SaveTimeline(CutTimeline->TimelineInfo.CurrentOpenRelativePath, CutTimeline->TimelineInfo);
|
||||||
CutTimeline->TimelineInfo.CurrentOpenFullPath = TimelineName;
|
CutTimeline->TimelineInfo.CurrentOpenRelativePath = TimelineRelativePath;
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// if (TimelineName == CutTimeline->TimelineInfo.CurrentOpenFullPath && !ForceOpen)
|
|
||||||
// {
|
|
||||||
// CloseTimeline();
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
FTimelineInfo TimelineInfo;
|
FTimelineInfo TimelineInfo;
|
||||||
// 拿到TimelineName路径中的名字,也就是倒数第四位开始,去掉后缀
|
// 拿到TimelineName路径中的名字,也就是倒数第四位开始,去掉后缀
|
||||||
|
if (CutTimeline->LoadTimeline(TimelineRelativePath, TimelineInfo))
|
||||||
if (CutTimeline->LoadTimeline(TimelineName, TimelineInfo))
|
|
||||||
{
|
{
|
||||||
CutTimeline->TimelineInfo = TimelineInfo;
|
CutTimeline->TimelineInfo = TimelineInfo;
|
||||||
// CutTimeline->CurrentEditDebug->SetText(FText::FromString(TEXT("当前正在编辑") + TimelineInfo.CurrentOpenFullPath));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OnAddNewTrack(ETrackType::PlayerTrack);
|
OnAddNewTrack(ETrackType::PlayerTrack);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCutMainWindow::CloseTimeline()
|
void SCutMainWindow::CloseTimeline()
|
||||||
{
|
{
|
||||||
CutTimeline->bNeedShowPanel = false;
|
CutTimeline->bNeedShowPanel = false;
|
||||||
CutTimeline->SaveTimeline(CutTimeline->TimelineInfo.CurrentOpenFullPath, CutTimeline->TimelineInfo);
|
CutTimeline->SaveTimeline(CutTimeline->TimelineInfo.CurrentOpenRelativePath, CutTimeline->TimelineInfo);
|
||||||
CutTimeline->RenderGroup();
|
CutTimeline->RenderGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1261,7 +1253,7 @@ void SCutMainWindow::ExportProject(const FString& ExportPath)
|
|||||||
ExportCard.SerialID.Add(EffectCardsPanel->EffectCardGroups[i].Cards[j].ID);
|
ExportCard.SerialID.Add(EffectCardsPanel->EffectCardGroups[i].Cards[j].ID);
|
||||||
|
|
||||||
|
|
||||||
ExportCard.TimelinePath = FUtils::SingleCardFullPath(EffectCardsPanel->EffectCardGroups[i].Cards[j].Guid.ToString());
|
ExportCard.TimelinePath = ToFullPath(FUtils::SingleCardRelativePath(EffectCardsPanel->EffectCardGroups[i].Cards[j].Guid.ToString()));
|
||||||
ExportCard.CardGuid = EffectCardsPanel->EffectCardGroups[i].Cards[j].Guid;
|
ExportCard.CardGuid = EffectCardsPanel->EffectCardGroups[i].Cards[j].Guid;
|
||||||
ExportCards.Add(ExportCard);
|
ExportCards.Add(ExportCard);
|
||||||
UE_LOG(LogTemp, Log, TEXT("ExportCard.TimelinePath = %s"), *ExportCard.TimelinePath);
|
UE_LOG(LogTemp, Log, TEXT("ExportCard.TimelinePath = %s"), *ExportCard.TimelinePath);
|
||||||
@ -1301,7 +1293,7 @@ void SCutMainWindow::ExportProject(const FString& ExportPath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ExportCard.TimelinePath = FUtils::GroupFullPath(EffectCardsPanel->EffectCardGroups[i].Guid.ToString());
|
ExportCard.TimelinePath = ToFullPath(FUtils::GroupRelativePath(EffectCardsPanel->EffectCardGroups[i].Guid.ToString()));
|
||||||
ExportCard.CardGuid = EffectCardsPanel->EffectCardGroups[i].Guid;
|
ExportCard.CardGuid = EffectCardsPanel->EffectCardGroups[i].Guid;
|
||||||
ExportCards.Add(ExportCard);
|
ExportCards.Add(ExportCard);
|
||||||
}
|
}
|
||||||
@ -1417,10 +1409,8 @@ void SCutMainWindow::ImportProject(const FString& ImportPath)
|
|||||||
|
|
||||||
void SCutMainWindow::NewProject(const FString& NewPath)
|
void SCutMainWindow::NewProject(const FString& NewPath)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
FGlobalData::BasePath = NewPath;
|
FGlobalData::BasePath = NewPath;
|
||||||
CutTimeline->TimelineInfo.CurrentOpenFullPath = FUtils::MainSaveFullPath();
|
CutTimeline->TimelineInfo.CurrentOpenRelativePath = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void SCutMainWindow::SaveProject()
|
void SCutMainWindow::SaveProject()
|
||||||
@ -1433,7 +1423,7 @@ void SCutMainWindow::SaveProject()
|
|||||||
// 根 << 记录所有导入资产链接
|
// 根 << 记录所有导入资产链接
|
||||||
// 根 << 记录所有幕
|
// 根 << 记录所有幕
|
||||||
// 根 << 记录所有组轨道链接
|
// 根 << 记录所有组轨道链接
|
||||||
CutTimeline->SaveTimeline(CutTimeline->TimelineInfo.CurrentOpenFullPath, CutTimeline->TimelineInfo);
|
CutTimeline->SaveTimeline(CutTimeline->TimelineInfo.CurrentOpenRelativePath, CutTimeline->TimelineInfo);
|
||||||
|
|
||||||
// 新建项目关联文件.cutlink
|
// 新建项目关联文件.cutlink
|
||||||
TArray<uint8> ProjectLinkData;
|
TArray<uint8> ProjectLinkData;
|
||||||
@ -2387,7 +2377,7 @@ tinyxml2::XMLElement* SCutMainWindow::GetProcessA(tinyxml2::XMLElement* Parent,
|
|||||||
DeselectAll();
|
DeselectAll();
|
||||||
CurtainPanel->DeSelectedAll();
|
CurtainPanel->DeSelectedAll();
|
||||||
CurtainGroup->Curtains[i].bIsActive = true;
|
CurtainGroup->Curtains[i].bIsActive = true;
|
||||||
OpenTimeline(CurtainGroup->Curtains[i].TimelineInfo.CurrentOpenFullPath, true, true);
|
OpenTimelineWithRelativePath(CurtainGroup->Curtains[i].TimelineInfo.CurrentOpenRelativePath, true, true);
|
||||||
GetProcessB(ProcessA, &CurtainGroup->Curtains[i]);
|
GetProcessB(ProcessA, &CurtainGroup->Curtains[i]);
|
||||||
}
|
}
|
||||||
if (CurtainGroup->Curtains.Num() == 0)
|
if (CurtainGroup->Curtains.Num() == 0)
|
||||||
@ -2487,7 +2477,7 @@ tinyxml2::XMLElement* SCutMainWindow::GetSpecialEffectList(tinyxml2::XMLElement*
|
|||||||
{
|
{
|
||||||
DeselectAll();
|
DeselectAll();
|
||||||
SetActive(ExportCard.CardGuid);
|
SetActive(ExportCard.CardGuid);
|
||||||
OpenTimeline(ExportCard.TimelinePath, true, true);
|
OpenTimelineWithRelativePath(ExportCard.TimelinePath, true, true);
|
||||||
|
|
||||||
tinyxml2::XMLElement* SpecialEffect = SpecialEffectsList->InsertNewChildElement("SpecialEffect");
|
tinyxml2::XMLElement* SpecialEffect = SpecialEffectsList->InsertNewChildElement("SpecialEffect");
|
||||||
tinyxml2::XMLElement* Effect = SpecialEffect->InsertNewChildElement("Effect");
|
tinyxml2::XMLElement* Effect = SpecialEffect->InsertNewChildElement("Effect");
|
||||||
@ -3006,7 +2996,7 @@ int32 SCutMainWindow::CalculateExportCount()
|
|||||||
{
|
{
|
||||||
for (FCurtain& Curtain : CurtainGroup.Curtains)
|
for (FCurtain& Curtain : CurtainGroup.Curtains)
|
||||||
{
|
{
|
||||||
FTimelineLoader TimelineLoader(Curtain.TimelineInfo.CurrentOpenFullPath);
|
FTimelineLoader TimelineLoader(ToFullPath(Curtain.TimelineInfo.CurrentOpenRelativePath));
|
||||||
Count += TimelineLoader.GetClipData().Num();
|
Count += TimelineLoader.GetClipData().Num();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3016,13 +3006,13 @@ int32 SCutMainWindow::CalculateExportCount()
|
|||||||
{
|
{
|
||||||
for (FEffectCardProperty& Property : Group.Cards)
|
for (FEffectCardProperty& Property : Group.Cards)
|
||||||
{
|
{
|
||||||
FTimelineLoader TimelineLoader(Property.TimelineInfo.CurrentOpenFullPath);
|
FTimelineLoader TimelineLoader(ToFullPath(Property.TimelineInfo.CurrentOpenRelativePath));
|
||||||
Count += TimelineLoader.GetClipData().Num();
|
Count += TimelineLoader.GetClipData().Num();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (FEffectCardProperty& Property : Group.Cards)
|
for (FEffectCardProperty& Property : Group.Cards)
|
||||||
{
|
{
|
||||||
FTimelineLoader TimelineLoader(Property.TimelineInfo.CurrentOpenFullPath);
|
FTimelineLoader TimelineLoader(ToFullPath(Property.TimelineInfo.CurrentOpenRelativePath));
|
||||||
Count += TimelineLoader.GetClipData().Num();
|
Count += TimelineLoader.GetClipData().Num();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ public:
|
|||||||
virtual void SelectClip(const FGuid& Guid) override;
|
virtual void SelectClip(const FGuid& Guid) override;
|
||||||
// 不好 到时候改成 Group Widget 内部操作
|
// 不好 到时候改成 Group Widget 内部操作
|
||||||
virtual void AddNewCard(FEffectCardProperty& CardProperty, FString GroupName) override;
|
virtual void AddNewCard(FEffectCardProperty& CardProperty, FString GroupName) override;
|
||||||
virtual void OpenTimeline(const FString& TimelineName, bool NeedSaveBefore, bool ForceOpen = false) override;
|
virtual void OpenTimelineWithRelativePath(const FString& TimelineRelativePath, bool NeedSaveBefore, bool ForceOpen = false) override;
|
||||||
virtual void CloseTimeline() override;
|
virtual void CloseTimeline() override;
|
||||||
virtual bool OpenProject(const FString& Project) override;
|
virtual bool OpenProject(const FString& Project) override;
|
||||||
virtual void ExportProject(const FString& ExportPath) override;
|
virtual void ExportProject(const FString& ExportPath) override;
|
||||||
|
@ -418,7 +418,7 @@ void SCutTimeline::Construct(const FArguments& InArgs)
|
|||||||
|
|
||||||
];
|
];
|
||||||
TrackHeadScrollBox->SetScrollBarVisibility(EVisibility::Hidden);
|
TrackHeadScrollBox->SetScrollBarVisibility(EVisibility::Hidden);
|
||||||
TimelineInfo.CurrentOpenFullPath = FUtils::MainSaveFullPath();
|
TimelineInfo.CurrentOpenRelativePath = "";
|
||||||
|
|
||||||
FDeviceTrack Volume(TEXT("音量数据"), ETrackType::VolumeTrack);
|
FDeviceTrack Volume(TEXT("音量数据"), ETrackType::VolumeTrack);
|
||||||
AddNewDeviceToGroup(TEXT("固定轨道"), Volume);
|
AddNewDeviceToGroup(TEXT("固定轨道"), Volume);
|
||||||
@ -760,13 +760,25 @@ void SCutTimeline::SaveTimeline(const FString& SavedPath, FTimelineInfo Info)
|
|||||||
MemoryWriter << ClipLength;
|
MemoryWriter << ClipLength;
|
||||||
MemoryWriter << AllClips;
|
MemoryWriter << AllClips;
|
||||||
|
|
||||||
FString NewSavedPath = FPaths::ConvertRelativePathToFull(SavedPath);
|
FString NewSavedPath = ToFullPath(SavedPath);
|
||||||
|
|
||||||
FFileHelper::SaveArrayToFile(SavedData, *NewSavedPath);
|
FFileHelper::SaveArrayToFile(SavedData, *NewSavedPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SCutTimeline::LoadTimeline(const FString& LoadPath, FTimelineInfo& Info)
|
bool SCutTimeline::LoadTimeline(const FString& LoadPath, FTimelineInfo& Info)
|
||||||
{
|
{
|
||||||
|
if (LoadPath == "")
|
||||||
|
{
|
||||||
|
bNeedShowPanel = false;
|
||||||
|
TimelineInfo.CurrentOpenRelativePath = "";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FString NewLoadPath = ToFullPath(LoadPath);
|
||||||
|
|
||||||
|
|
||||||
MainWidgetInterface->GetSelf()->CloseAllThreads();
|
MainWidgetInterface->GetSelf()->CloseAllThreads();
|
||||||
|
|
||||||
@ -775,8 +787,8 @@ bool SCutTimeline::LoadTimeline(const FString& LoadPath, FTimelineInfo& Info)
|
|||||||
static_cast<SCutMainWindow*>(MainWidgetInterface)->UpdateProperties(nullptr);
|
static_cast<SCutMainWindow*>(MainWidgetInterface)->UpdateProperties(nullptr);
|
||||||
static_cast<SCutMainWindow*>(MainWidgetInterface)->CloseAllThreads();
|
static_cast<SCutMainWindow*>(MainWidgetInterface)->CloseAllThreads();
|
||||||
TArray<uint8> LoadData;
|
TArray<uint8> LoadData;
|
||||||
FPaths::ConvertRelativePathToFull(LoadPath);
|
FPaths::ConvertRelativePathToFull(NewLoadPath);
|
||||||
FFileHelper::LoadFileToArray(LoadData, *LoadPath);
|
FFileHelper::LoadFileToArray(LoadData, *NewLoadPath);
|
||||||
if (LoadData.Num() == 0)
|
if (LoadData.Num() == 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -798,8 +810,13 @@ bool SCutTimeline::LoadTimeline(const FString& LoadPath, FTimelineInfo& Info)
|
|||||||
MemoryReader << ClipLength;
|
MemoryReader << ClipLength;
|
||||||
TArray<FClipData> AllClips;
|
TArray<FClipData> AllClips;
|
||||||
MemoryReader << AllClips;
|
MemoryReader << AllClips;
|
||||||
|
float MaxLength = 0.0f;
|
||||||
for (int32 i = 0; i < AllClips.Num(); i++)
|
for (int32 i = 0; i < AllClips.Num(); i++)
|
||||||
{
|
{
|
||||||
|
if (MaxLength < AllClips[i].ClipEndFrame)
|
||||||
|
{
|
||||||
|
MaxLength = AllClips[i].ClipEndFrame;
|
||||||
|
}
|
||||||
AllClips[i].ResourcePropertyDataPtr = MainWidgetInterface->GetResourcePropertyDataPtr(AllClips[i].ResourcePropertyGuid);
|
AllClips[i].ResourcePropertyDataPtr = MainWidgetInterface->GetResourcePropertyDataPtr(AllClips[i].ResourcePropertyGuid);
|
||||||
for (int32 j = 0; j < DeviceTrackGroups.Num(); j++)
|
for (int32 j = 0; j < DeviceTrackGroups.Num(); j++)
|
||||||
{
|
{
|
||||||
@ -823,30 +840,17 @@ bool SCutTimeline::LoadTimeline(const FString& LoadPath, FTimelineInfo& Info)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
FGlobalData::TrackLength = MaxLength + (MaxLength * 0.2);
|
||||||
|
if (FGlobalData::TrackLength == 0)
|
||||||
|
{
|
||||||
|
FGlobalData::TrackLength = 100;
|
||||||
|
}
|
||||||
|
UpdateTimelineLength();
|
||||||
|
|
||||||
RenderGroup();
|
RenderGroup();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// int32 Length = 0;
|
|
||||||
// MemoryReader << Length;
|
|
||||||
// TArray<FString> GroupName;
|
|
||||||
// GroupName.Init("", Length);
|
|
||||||
// for (int32 i = 0; i < Length; i++)
|
|
||||||
// {
|
|
||||||
// MemoryReader << GroupName[i];
|
|
||||||
// }
|
|
||||||
// for (int32 i = 0; i < Length; i++)
|
|
||||||
// {
|
|
||||||
// FTrackData TrackData;
|
|
||||||
// MemoryReader << TrackData;
|
|
||||||
// for (FClipData& ClipData : TrackData.ClipData)
|
|
||||||
// {
|
|
||||||
// ClipData.ResourcePropertyDataPtr = MainWidgetInterface->GetResourcePropertyDataPtr(ClipData.ResourcePropertyGuid);
|
|
||||||
// }
|
|
||||||
// AddNewTrackToGroup(GroupName[i], TrackData);
|
|
||||||
// }
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,13 +93,13 @@ public:
|
|||||||
void RenderGroup();
|
void RenderGroup();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Save Current Time line Track to File.
|
* @brief Save Current Time line Track to File. Relative
|
||||||
* @param SavedPath Where to save.
|
* @param SavedPath Where to save.
|
||||||
*/
|
*/
|
||||||
void SaveTimeline(const FString& SavedPath, FTimelineInfo Info);
|
void SaveTimeline(const FString& SavedPath, FTimelineInfo Info);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Load Time line Track from File.
|
* @brief Load Time line Track from File. Relative
|
||||||
* @param LoadPath Where to load.
|
* @param LoadPath Where to load.
|
||||||
*/
|
*/
|
||||||
bool LoadTimeline(const FString& LoadPath, FTimelineInfo& Info);
|
bool LoadTimeline(const FString& LoadPath, FTimelineInfo& Info);
|
||||||
|
@ -267,15 +267,23 @@ void STimelineClip::Construct(const FArguments& InArgs)
|
|||||||
FRunnableThread::Create(Thread, TEXT("VideoThread"));
|
FRunnableThread::Create(Thread, TEXT("VideoThread"));
|
||||||
MainWidgetInterface->GetSelf()->AddThread(FUtils::GetVideoThreadGuid(ClipData->ClipGuid), Thread);
|
MainWidgetInterface->GetSelf()->AddThread(FUtils::GetVideoThreadGuid(ClipData->ClipGuid), Thread);
|
||||||
}
|
}
|
||||||
// if (!MainWidgetInterface->GetSelf()->GetThread(FUtils::GetVideoThumbnailThreadGuid(ClipData->ClipGuid)))
|
|
||||||
// {
|
if (ClipData->ClipGuid != FGuid())
|
||||||
// FVideoThumbnailThread* ThumbnailThread = new FVideoThumbnailThread(ClipData->MoviePath, [this](const FString& PicPath)
|
{
|
||||||
// {
|
if (!MainWidgetInterface->GetSelf()->GetThread(FUtils::GetVideoThumbnailThreadGuid(ClipData->ClipGuid)))
|
||||||
//
|
{
|
||||||
// });
|
FVideoThumbnailThread* ThumbnailThread = new FVideoThumbnailThread(ClipData->MoviePath, [this](const FString& PicPath)
|
||||||
// FRunnableThread::Create(ThumbnailThread, TEXT("VideoThumbnailThread"));
|
{
|
||||||
// MainWidgetInterface->GetSelf()->AddThread(FUtils::GetVideoThumbnailThreadGuid(ClipData->ClipGuid), ThumbnailThread);
|
ClipData->MovieBrushesPath.Add(PicPath);
|
||||||
// }
|
const FSlateDynamicImageBrush Brush = FSlateDynamicImageBrush(*ToFullPath(PicPath), FVector2f(0, 0));
|
||||||
|
ClipData->MovieBrushes.Add(Brush);
|
||||||
|
}, ClipData->MovieBrushNum, *ClipData);
|
||||||
|
|
||||||
|
FRunnableThread::Create(ThumbnailThread, TEXT("VideoThumbnailThread"));
|
||||||
|
MainWidgetInterface->GetSelf()->AddThread(FUtils::GetVideoThumbnailThreadGuid(ClipData->ClipGuid), ThumbnailThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -746,6 +754,8 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe
|
|||||||
|
|
||||||
if (CropStartFrameOffset != -1 || NeedDrawCount != -1)
|
if (CropStartFrameOffset != -1 || NeedDrawCount != -1)
|
||||||
{
|
{
|
||||||
|
const float StartRange = CurrentStartRange - RangeStart;
|
||||||
|
const float EndRange = CurrentEndRange;
|
||||||
for (int32 i = 0; i < NeedDrawCount / DownSample; i++)
|
for (int32 i = 0; i < NeedDrawCount / DownSample; i++)
|
||||||
{
|
{
|
||||||
const int32 CurrentIndex = (CropStartDataOffset * DownSample) + (i * (Interval * DownSample * 4));
|
const int32 CurrentIndex = (CropStartDataOffset * DownSample) + (i * (Interval * DownSample * 4));
|
||||||
@ -755,14 +765,23 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe
|
|||||||
float NewFloat = *reinterpret_cast<float*>(&ClipData->ResourcePropertyDataPtr->AudioData[CurrentIndex]);
|
float NewFloat = *reinterpret_cast<float*>(&ClipData->ResourcePropertyDataPtr->AudioData[CurrentIndex]);
|
||||||
float Y = FMath::GetMappedRangeValueClamped(FVector2D(1.0, 0.0), FVector2D(0.0, AllottedGeometry.GetLocalSize().Y),
|
float Y = FMath::GetMappedRangeValueClamped(FVector2D(1.0, 0.0), FVector2D(0.0, AllottedGeometry.GetLocalSize().Y),
|
||||||
FMath::Abs(NewFloat));
|
FMath::Abs(NewFloat));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TArray<FVector2D> NewLoc;
|
TArray<FVector2D> NewLoc;
|
||||||
NewLoc.Add(FVector2D((CropStartFrameOffset * FGlobalData::DefaultTimeTickSpace + i * DownSample) , AllottedGeometry.GetLocalSize().Y));
|
NewLoc.Add(FVector2D((CropStartFrameOffset * FGlobalData::DefaultTimeTickSpace + i * DownSample) , AllottedGeometry.GetLocalSize().Y));
|
||||||
NewLoc.Add(FVector2D((CropStartFrameOffset * FGlobalData::DefaultTimeTickSpace + i * DownSample) , Y));
|
NewLoc.Add(FVector2D((CropStartFrameOffset * FGlobalData::DefaultTimeTickSpace + i * DownSample) , Y));
|
||||||
|
|
||||||
FSlateDrawElement::MakeLines(OutDrawElements, LayerId + 6, AllottedGeometry.ToPaintGeometry(), NewLoc, ESlateDrawEffect::None,
|
FSlateDrawElement::MakeLines(OutDrawElements, LayerId + 6, AllottedGeometry.ToPaintGeometry(), NewLoc, ESlateDrawEffect::None,
|
||||||
FColor(45, 214, 153, 255), true, DownSample * 1.2);
|
FColor(45, 214, 153, 255), true, DownSample * 1.2);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GEngine->AddOnScreenDebugMessage(-1, 0.1f, FColor::Red, FString::SanitizeFloat(StartRange));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (ClipData->ClipType == ETrackType::AudioTrack || ClipData->ClipType == ETrackType::AudioTrackR)
|
if (ClipData->ClipType == ETrackType::AudioTrack || ClipData->ClipType == ETrackType::AudioTrackR)
|
||||||
{
|
{
|
||||||
FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 5, AllottedGeometry.ToPaintGeometry(),
|
FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 5, AllottedGeometry.ToPaintGeometry(),
|
||||||
@ -1034,90 +1053,7 @@ void STimelineClip::OnMouseLeave(const FPointerEvent& MouseEvent)
|
|||||||
|
|
||||||
void STimelineClip::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
|
void STimelineClip::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
|
||||||
{
|
{
|
||||||
if (ClipData->MovieBrushes.Num() < ClipData->MovieBrushNum && ClipData->ResourcePropertyDataPtr && ClipData->ResourcePropertyDataPtr->Context && ClipData->ResourcePropertyDataPtr->VideoStream != -1)
|
SCompoundWidget::Tick(AllottedGeometry, InCurrentTime, InDeltaTime);
|
||||||
{
|
|
||||||
if (ThumbnailCodecContext.Context == nullptr)
|
|
||||||
{
|
|
||||||
FFFMPEGUtils::LoadContextPure(ClipData->ResourcePropertyDataPtr->MoviePath, &ThumbnailCodecContext);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int32 CurrentFrame = ClipData->MovieBrushNum - (ClipData->MovieBrushNum - ClipData->MovieBrushes.Num());
|
|
||||||
const int64 Timestamp = av_rescale_q(CurrentFrame / FGlobalData::GlobalFPS * AV_TIME_BASE, AVRational{1, AV_TIME_BASE}, ThumbnailCodecContext.Context->streams[ThumbnailCodecContext.VideoStream]->time_base);
|
|
||||||
av_seek_frame(ThumbnailCodecContext.Context, ThumbnailCodecContext.VideoStream, Timestamp, AVSEEK_FLAG_BACKWARD);
|
|
||||||
AVPacket Packet;
|
|
||||||
av_init_packet(&Packet);
|
|
||||||
AVFormatContext* FormatContext = ThumbnailCodecContext.Context;
|
|
||||||
AVCodecContext* VideoCodecContext = ThumbnailCodecContext.VideoCodecContext;
|
|
||||||
AVCodec* VideoCodec = ThumbnailCodecContext.VideoCodec;
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
if (Frame->best_effort_timestamp >= Timestamp)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (Frame)
|
|
||||||
{
|
|
||||||
if (Frame->width == 0 || Frame->height == 0)
|
|
||||||
{
|
|
||||||
TArray<FSlateBrush> Brushes;
|
|
||||||
Brushes.Init(FSlateBrush(), ClipData->MovieBrushNum - ClipData->MovieBrushes.Num());
|
|
||||||
ClipData->MovieBrushes.Append(Brushes);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct SwsContext* swsCtx = sws_getContext(
|
|
||||||
Frame->width, Frame->height, VideoCodecContext->pix_fmt,
|
|
||||||
Frame->width / 10, Frame->height / 10, AV_PIX_FMT_BGRA,
|
|
||||||
SWS_BILINEAR, NULL, NULL, NULL
|
|
||||||
);
|
|
||||||
if (!swsCtx)
|
|
||||||
{
|
|
||||||
UE_LOG(LogTemp, Error, TEXT("Error creating swsContext"));
|
|
||||||
}
|
|
||||||
uint8* RawData = new uint8[(Frame->width / 10) * (Frame->height / 10) * 4];
|
|
||||||
uint8* dest[4] = {RawData, 0, 0, 0};
|
|
||||||
int32 dest_linesize[4] = {(Frame->width / 10) * 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 / 10, Frame->height / 10, PF_B8G8R8A8);
|
|
||||||
if (Texture)
|
|
||||||
{
|
|
||||||
void* MipData = Texture->GetPlatformData()->Mips[0].BulkData.Lock(LOCK_READ_WRITE);
|
|
||||||
FMemory::Memcpy(MipData, RawData, (Frame->width / 10) * (Frame->height / 10) * 4);
|
|
||||||
Texture->GetPlatformData()->Mips[0].BulkData.Unlock();
|
|
||||||
Texture->UpdateResource();
|
|
||||||
|
|
||||||
FGuid Guid = FGuid::NewGuid();
|
|
||||||
FFFMPEGUtils::ExportImage(Texture, *FPaths::Combine(FUtils::GetProjectTempPath() / ClipData->ClipGuid.ToString() / Guid.ToString() + ".png"));
|
|
||||||
ClipData->MovieBrushesPath.Add(FPaths::Combine(FUtils::GetProjectTempPath() / ClipData->ClipGuid.ToString() / Guid.ToString() + ".png"));
|
|
||||||
FSlateDynamicImageBrush Brush = FSlateDynamicImageBrush(*ClipData->MovieBrushesPath[ClipData->MovieBrushesPath.Num() - 1], FVector2f(0, 0));
|
|
||||||
ClipData->MovieBrushes.Add(Brush);
|
|
||||||
|
|
||||||
Texture->MarkAsGarbage();
|
|
||||||
delete RawData;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TSharedPtr<SWidget> STimelineClip::GetPropertiesWidget()
|
TSharedPtr<SWidget> STimelineClip::GetPropertiesWidget()
|
||||||
|
@ -413,8 +413,8 @@ TSharedPtr<SWidget> FClipProxy::GetPropertiesWidget()
|
|||||||
const FGuid& Guid = InItem.Get()->Guid;
|
const FGuid& Guid = InItem.Get()->Guid;
|
||||||
FCurtainGroup* Group = nullptr;
|
FCurtainGroup* Group = nullptr;
|
||||||
const FString CurrentPath = // MainInterface->GetSelf()->CurtainPanel->FindCurtain(Guid,Group)->TimelineInfo.CurrentOpenFullPath;
|
const FString CurrentPath = // MainInterface->GetSelf()->CurtainPanel->FindCurtain(Guid,Group)->TimelineInfo.CurrentOpenFullPath;
|
||||||
MainInterface->GetSelf()->GetSelectTimelineInfoByGuid(Guid).CurrentOpenFullPath;
|
MainInterface->GetSelf()->GetSelectTimelineInfoByGuid(Guid).CurrentOpenRelativePath;
|
||||||
FTimelineLoader TimelineLoader(CurrentPath, true);
|
FTimelineLoader TimelineLoader(ToFullPath(CurrentPath), true);
|
||||||
if (TimelineLoader.GetSpecifyClipData(ClipData->ClipType).Num() > 0 && State == ECheckBoxState::Checked)
|
if (TimelineLoader.GetSpecifyClipData(ClipData->ClipType).Num() > 0 && State == ECheckBoxState::Checked)
|
||||||
{
|
{
|
||||||
FUtils::AddTips(
|
FUtils::AddTips(
|
||||||
@ -424,7 +424,7 @@ TSharedPtr<SWidget> FClipProxy::GetPropertiesWidget()
|
|||||||
.OnEnsure_Lambda([this, State, InItem, CurrentPath](const FString& String)
|
.OnEnsure_Lambda([this, State, InItem, CurrentPath](const FString& String)
|
||||||
{
|
{
|
||||||
// 先清空
|
// 先清空
|
||||||
FTimelineLoader ModifyTimelineLoader(CurrentPath, true);
|
FTimelineLoader ModifyTimelineLoader(ToFullPath(CurrentPath), true);
|
||||||
TArray<FClipData> Clips = ModifyTimelineLoader.GetSpecifyClipData(ClipData->ClipType);
|
TArray<FClipData> Clips = ModifyTimelineLoader.GetSpecifyClipData(ClipData->ClipType);
|
||||||
for (int32 i = Clips.Num() - 1; i >= 0; i--)
|
for (int32 i = Clips.Num() - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user