修改一下音频合并
This commit is contained in:
parent
2b6dd72a30
commit
8005d78372
@ -372,46 +372,107 @@ TArray<FEncodeVideoInfo> FUtils::TrackEncodeAudio(const FTrackData& TrackData, c
|
||||
{
|
||||
TArray<FClipData> ClipData = TrackData.ClipData;
|
||||
ClipData.Sort([](const FClipData& A, const FClipData& B) {return A.ClipStartFrame < B.ClipStartFrame; });
|
||||
|
||||
int32 i = 0;
|
||||
TArray<FEncodeVideoInfo> EncodeVideoInfos;
|
||||
for (FClipData& TempClipData : ClipData)
|
||||
|
||||
// 先拆出所有音频
|
||||
int32 AudioCount = 0;
|
||||
{
|
||||
if (TempClipData.ResourcePropertyDataPtr->Context)
|
||||
int32 i = 0;
|
||||
for (FClipData& TempClipData : ClipData)
|
||||
{
|
||||
FEncodeVideoInfo EncodeVideoInfo;
|
||||
FTimespan EndTimespan = FTimespan::FromSeconds(TempClipData.VideoEndFrame / FGlobalData::GlobalFPS);
|
||||
FTimespan StartTimespan = FTimespan::FromSeconds(TempClipData.VideoStartFrame / FGlobalData::GlobalFPS);
|
||||
if (TempClipData.ResourcePropertyDataPtr->Context)
|
||||
{
|
||||
FEncodeVideoInfo EncodeVideoInfo;
|
||||
FTimespan EndTimespan = FTimespan::FromSeconds(TempClipData.VideoEndFrame / FGlobalData::GlobalFPS);
|
||||
FTimespan StartTimespan = FTimespan::FromSeconds(TempClipData.VideoStartFrame / FGlobalData::GlobalFPS);
|
||||
|
||||
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 InputFile = TempClipData.ResourcePropertyDataPtr->MoviePath;
|
||||
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 InputFile = TempClipData.ResourcePropertyDataPtr->MoviePath;
|
||||
|
||||
FString OutputFile = FPaths::ConvertRelativePathToFull(ExportPath + FString::FromInt(i) + TEXT(".mp3"));
|
||||
FString OutputFile = FPaths::ConvertRelativePathToFull(GetProjectTempPath() / FString::FromInt(i) + TEXT(".mp3"));
|
||||
|
||||
int32 StartFrame = (TempClipData.VideoStartFrame) % static_cast<int>(FGlobalData::GlobalFPS);;
|
||||
int32 EndFrame = (TempClipData.VideoEndFrame) % static_cast<int>(FGlobalData::GlobalFPS);
|
||||
int32 StartFrame = (TempClipData.VideoStartFrame) % static_cast<int>(FGlobalData::GlobalFPS);;
|
||||
int32 EndFrame = (TempClipData.VideoEndFrame) % static_cast<int>(FGlobalData::GlobalFPS);
|
||||
|
||||
FString Command = FString::Printf(TEXT("-y -i \"%s\" -ss %s -to %s -c copy \"%s\""),
|
||||
*InputFile, *StartTime, *EndTime, *OutputFile);
|
||||
FString Command = FString::Printf(TEXT("-y -i \"%s\" -ss %s -to %s -c copy \"%s\""),
|
||||
*InputFile, *StartTime, *EndTime, *OutputFile);
|
||||
|
||||
FPlatformProcess::CreateProc(*GetFfmepg(), *Command, true, false, false, nullptr, 0, nullptr, nullptr);
|
||||
|
||||
EncodeVideoInfo.EncodedVideoTimeCode = FGlobalData::GetTimeData(TempClipData.ClipStartFrame);
|
||||
EncodeVideoInfo.EncodedVideoName = ExportPath + FString::FromInt(i) + TEXT(".mp3");
|
||||
EncodeVideoInfo.ClipStartFrame = TempClipData.ClipStartFrame;
|
||||
EncodeVideoInfo.ClipEndFrame = TempClipData.ClipEndFrame;
|
||||
|
||||
EncodeVideoInfo.TrackData = TrackData;
|
||||
EncodeVideoInfo.ClipData = TempClipData;
|
||||
EncodeVideoInfos.Add(EncodeVideoInfo);
|
||||
FPlatformProcess::CreateProc(*GetFfmepg(), *Command, true, false, false, nullptr, 0, nullptr, nullptr);
|
||||
i++;
|
||||
AudioCount++;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
FString Header = GetFfmepg();
|
||||
for (int32 i = 0; i < ClipData.Num(); i++)
|
||||
{
|
||||
Header += " -i ";
|
||||
Header += "\"" + GetProjectTempPath() / FString::FromInt(i) + ".mp3" + "\"";
|
||||
}
|
||||
|
||||
Header += " -filter_complex";
|
||||
|
||||
// [0:0][1:0]...[n:0]concat=n=n=2:v=0:a=1[out]
|
||||
for (int32 i = 0; i < ClipData.Num(); i++)
|
||||
{
|
||||
Header += "[" + FString::FromInt(i) + ":0]";
|
||||
}
|
||||
|
||||
Header += "concat=n=" + FString::FromInt(ClipData.Num()) + ":v=0:a=1[out]";
|
||||
Header += " -map [out] -y " + ExportPath + ".mp3";
|
||||
FPlatformProcess::CreateProc(*GetFfmepg(), *Header, true, false, false, nullptr, 0, nullptr, nullptr);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// int32 i = 0;
|
||||
TArray<FEncodeVideoInfo> EncodeVideoInfos;
|
||||
// for (FClipData& TempClipData : ClipData)
|
||||
// {
|
||||
// if (TempClipData.ResourcePropertyDataPtr->Context)
|
||||
// {
|
||||
// FEncodeVideoInfo EncodeVideoInfo;
|
||||
// FTimespan EndTimespan = FTimespan::FromSeconds(TempClipData.VideoEndFrame / FGlobalData::GlobalFPS);
|
||||
// FTimespan StartTimespan = FTimespan::FromSeconds(TempClipData.VideoStartFrame / FGlobalData::GlobalFPS);
|
||||
//
|
||||
// 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 InputFile = TempClipData.ResourcePropertyDataPtr->MoviePath;
|
||||
//
|
||||
// FString OutputFile = FPaths::ConvertRelativePathToFull(ExportPath + FString::FromInt(i) + TEXT(".mp3"));
|
||||
//
|
||||
// int32 StartFrame = (TempClipData.VideoStartFrame) % static_cast<int>(FGlobalData::GlobalFPS);;
|
||||
// int32 EndFrame = (TempClipData.VideoEndFrame) % static_cast<int>(FGlobalData::GlobalFPS);
|
||||
//
|
||||
// FString Command = FString::Printf(TEXT("-y -i \"%s\" -ss %s -to %s -c copy \"%s\""),
|
||||
// *InputFile, *StartTime, *EndTime, *OutputFile);
|
||||
//
|
||||
// FPlatformProcess::CreateProc(*GetFfmepg(), *Command, true, false, false, nullptr, 0, nullptr, nullptr);
|
||||
//
|
||||
// EncodeVideoInfo.EncodedVideoTimeCode = FGlobalData::GetTimeData(TempClipData.ClipStartFrame);
|
||||
// EncodeVideoInfo.EncodedVideoName = ExportPath + FString::FromInt(i) + TEXT(".mp3");
|
||||
// EncodeVideoInfo.ClipStartFrame = TempClipData.ClipStartFrame;
|
||||
// EncodeVideoInfo.ClipEndFrame = TempClipData.ClipEndFrame;
|
||||
//
|
||||
// EncodeVideoInfo.TrackData = TrackData;
|
||||
// EncodeVideoInfo.ClipData = TempClipData;
|
||||
// EncodeVideoInfos.Add(EncodeVideoInfo);
|
||||
// }
|
||||
// i++;
|
||||
// }
|
||||
return EncodeVideoInfos;
|
||||
|
||||
}
|
||||
|
||||
TArray<FEncodeVideoInfo> FUtils::CombineAudio(const FEncodeVideoInfo& EncodeVideoInfo,
|
||||
const FEncodeVideoInfo& EncodeAudioInfo, const FString& ExportPath)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
FString FUtils::GetFfmepg()
|
||||
{
|
||||
return FPaths::ConvertRelativePathToFull(FPaths::ProjectDir() / TEXT("Binaries") / TEXT("Win64") / TEXT("ffmpeg.exe"));
|
||||
|
@ -33,7 +33,8 @@ public:
|
||||
static void CreateDefaultTimelineSave(const FString& SavedPath, const FTimelineInfo::ETimelineType Type);
|
||||
|
||||
static TArray<FEncodeVideoInfo> TrackEncodeVideo(const FTrackData& TrackData, const FString& ExportPath);
|
||||
static TArray<FEncodeVideoInfo> TrackEncodeAudio(const FTrackData& TrackData, const FString& ExportPath);
|
||||
static TArray<FEncodeVideoInfo> TrackEncodeAudio(const FTrackData& TrackDataLeft, const FString& ExportPath);
|
||||
static TArray<FEncodeVideoInfo> CombineAudio(const FEncodeVideoInfo& EncodeVideoInfo, const FEncodeVideoInfo& EncodeAudioInfo, const FString& ExportPath);
|
||||
static FString CurtainFullPath(const FString& GroupName)
|
||||
{
|
||||
// GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, FGlobalData::BasePath);
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
inline static FString CurrentProjectName = "DefaultProject";
|
||||
inline static FString BasePath = FPaths::ProjectDir();
|
||||
inline static FString Version = "3.0";
|
||||
inline static FString CutVersion = "1.1";
|
||||
inline static FString ExportPath = "";
|
||||
|
||||
inline static TArray<FColor> Colors =
|
||||
@ -333,6 +334,7 @@ struct CUT5_API FClipData : public TSharedFromThis<FClipData>
|
||||
Ar << ClipData.MovieBrushesPath;
|
||||
Ar << ClipData.VolumeData;
|
||||
Ar << ClipData.bIsCycle;
|
||||
Ar << ClipData.AudioCurtains;
|
||||
return Ar;
|
||||
};
|
||||
|
||||
@ -352,6 +354,7 @@ struct CUT5_API FClipData : public TSharedFromThis<FClipData>
|
||||
bool bIsCycle = false;
|
||||
|
||||
TArray<FLinearColor> ClipColors;
|
||||
TArray<FStringWithGUID> AudioCurtains;
|
||||
|
||||
UE_DEPRECATED(0.0, "Use int32 instead of float, Please just use ClipStartFrame and ClipEndFrame")
|
||||
int32 GetClipStartFrame() const { return ClipStartTime / FGlobalData::DefaultTimeTickSpace; };
|
||||
@ -1025,7 +1028,7 @@ struct FProperties
|
||||
};
|
||||
|
||||
|
||||
struct FEncodeVideoInfo
|
||||
struct FEncodeVideoInfo
|
||||
{
|
||||
FString EncodedVideoName = "";
|
||||
FString EncodedVideoTimeCode = "00:00:00:00";
|
||||
|
@ -2005,13 +2005,14 @@ tinyxml2::XMLElement* SCutMainWindow::GetSoundListElement(tinyxml2::XMLElement*
|
||||
tinyxml2::XMLElement* AudioList = Parent->InsertNewChildElement("SoundList");
|
||||
{
|
||||
int32 Count = 0;
|
||||
bool bGlobalAudio = false;
|
||||
for (int32 i = 0; i < CutTimeline->TrackGroupInstances.Num(); i++)
|
||||
{
|
||||
const FTrackData& TrackData = StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData;
|
||||
if (StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData.TrackType == ETrackType::AudioTrack ||
|
||||
StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData.TrackType == ETrackType::AudioTrackR)
|
||||
{
|
||||
FString Filename = GetCurrentSelectFileName();
|
||||
|
||||
|
||||
if (StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData.TrackType == ETrackType::AudioTrackR)
|
||||
{
|
||||
@ -2022,16 +2023,48 @@ tinyxml2::XMLElement* SCutMainWindow::GetSoundListElement(tinyxml2::XMLElement*
|
||||
Filename += TEXT("_L");
|
||||
}
|
||||
FString NewExportFilePath = FGlobalData::ExportPath / "Sound" / Filename;
|
||||
TArray<FEncodeVideoInfo> EncodeVideoInfos = FUtils::TrackEncodeAudio(StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData, NewExportFilePath);
|
||||
for (const FEncodeVideoInfo EncodeVideoInfo : EncodeVideoInfos)
|
||||
|
||||
|
||||
bGlobalAudio = false;
|
||||
FEncodeVideoInfo GlobalAudioEncodeVideoInfo = {};
|
||||
for (const FEncodeVideoInfo& EncodeVideoInfo : AllGlobalSounds)
|
||||
{
|
||||
GetSoundElement(AudioList, EncodeVideoInfo);
|
||||
Count++;
|
||||
if (EncodeVideoInfo.ClipData.AudioCurtains.Contains(GetCurrentSelectCurtain()))
|
||||
{
|
||||
bGlobalAudio = true;
|
||||
GlobalAudioEncodeVideoInfo = EncodeVideoInfo;
|
||||
Count++;
|
||||
};
|
||||
}
|
||||
|
||||
if (bGlobalAudio == false)
|
||||
{
|
||||
TArray<FEncodeVideoInfo> EncodeVideoInfos = FUtils::TrackEncodeAudio(StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData, NewExportFilePath);
|
||||
|
||||
for (const FEncodeVideoInfo EncodeVideoInfo : EncodeVideoInfos)
|
||||
{
|
||||
if (EncodeVideoInfo.ClipData.AudioCurtains.Num() > 0)
|
||||
{
|
||||
AllGlobalSounds.Add(EncodeVideoInfo);
|
||||
}
|
||||
}
|
||||
for (const FEncodeVideoInfo EncodeVideoInfo : EncodeVideoInfos)
|
||||
{
|
||||
GetSoundElement(AudioList, EncodeVideoInfo);
|
||||
Count++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GetSoundElement(AudioList, GlobalAudioEncodeVideoInfo);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (Count == 0)
|
||||
|
||||
|
||||
|
||||
|
||||
if (Count == 0 && !bGlobalAudio)
|
||||
{
|
||||
GetSoundElement(AudioList, FEncodeVideoInfo());
|
||||
}
|
||||
@ -2343,6 +2376,36 @@ tinyxml2::XMLElement* SCutMainWindow::GetGradientLight(tinyxml2::XMLElement* Par
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FGuid SCutMainWindow::GetCurrentSelectCurtain() const
|
||||
{
|
||||
for (FCurtainGroup& CurtainGroup : CurtainPanel->Groups)
|
||||
{
|
||||
for (const FCurtain& Curtain : CurtainGroup.Curtains)
|
||||
{
|
||||
if (Curtain.bIsActive)
|
||||
{
|
||||
return Curtain.CurtainUUID;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FGuid();
|
||||
}
|
||||
|
||||
bool SCutMainWindow::IsSelectCurtain() const
|
||||
{
|
||||
for (FCurtainGroup& CurtainGroup : CurtainPanel->Groups)
|
||||
{
|
||||
for (const FCurtain& Curtain : CurtainGroup.Curtains)
|
||||
{
|
||||
if (Curtain.bIsActive)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SCutMainWindow::DeselectAll()
|
||||
{
|
||||
for (FCurtainGroup& CurtainGroup : CurtainPanel->Groups)
|
||||
|
@ -111,6 +111,9 @@ public:
|
||||
|
||||
tinyxml2::XMLElement* GetVideoListElement(tinyxml2::XMLElement* Parent);
|
||||
tinyxml2::XMLElement* GetSoundListElement(tinyxml2::XMLElement* Parent);
|
||||
|
||||
TArray<FEncodeVideoInfo> AllGlobalSounds;
|
||||
|
||||
tinyxml2::XMLElement* GetProcessA(tinyxml2::XMLElement* Parent, FCurtainGroup* CurtainGroup);
|
||||
tinyxml2::XMLElement* GetProcessB(tinyxml2::XMLElement* Parent, FCurtain* Curtain);
|
||||
tinyxml2::XMLElement* GetSpecialEffectList(tinyxml2::XMLElement* Parent);
|
||||
@ -121,7 +124,9 @@ public:
|
||||
tinyxml2::XMLElement* GetBreatheLight(tinyxml2::XMLElement* Parent, const FClipData& ClipData);
|
||||
tinyxml2::XMLElement* GetFlashLight(tinyxml2::XMLElement* Parent, const FClipData& ClipData);
|
||||
tinyxml2::XMLElement* GetGradientLight(tinyxml2::XMLElement* Parent, const FClipData& ClipData);
|
||||
FString GetCurrentSelectFileName();
|
||||
FString GetCurrentSelectFileName() const;
|
||||
FGuid GetCurrentSelectCurtain() const;
|
||||
bool IsSelectCurtain() const;
|
||||
void DeselectAll();
|
||||
|
||||
int32 RotatorSpeakerIndex = 0;
|
||||
@ -136,7 +141,7 @@ public:
|
||||
void RemoveThread(const FGuid& Guid);
|
||||
};
|
||||
|
||||
inline FString SCutMainWindow::GetCurrentSelectFileName()
|
||||
inline FString SCutMainWindow::GetCurrentSelectFileName() const
|
||||
{
|
||||
for (FCurtainGroup& CurtainGroup : CurtainPanel->Groups)
|
||||
{
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "ClipProxy.h"
|
||||
|
||||
#include "Cut5/Utils/Utils.h"
|
||||
#include "Cut5/Widgets/SCutMainWindow.h"
|
||||
#include "Cut5/Widgets/SCutTimeline.h"
|
||||
#include "Cut5/Widgets/STimelineClip.h"
|
||||
#include "Cut5/Widgets/MicroWidgets/SNewProjectTips.h"
|
||||
@ -330,6 +331,101 @@ TSharedPtr<SWidget> FClipProxy::GetPropertiesWidget()
|
||||
];
|
||||
}
|
||||
|
||||
if (ClipData->ClipType == ETrackType::AudioTrack || ClipData->ClipType == ETrackType::AudioTrackR)
|
||||
{
|
||||
AudiosCurtainOptions.Empty();
|
||||
TArray<FCurtainGroup>& Groups = MainInterface->GetSelf()->CurtainPanel->Groups;
|
||||
for (FCurtainGroup& Group : Groups)
|
||||
{
|
||||
for (FCurtain& Curtain : Group.Curtains)
|
||||
{
|
||||
AudiosCurtainOptions.Add(MakeShared<FStringWithGUID>(Curtain.CurtainName, Curtain.CurtainUUID));
|
||||
}
|
||||
}
|
||||
|
||||
VerticalBox->AddSlot()
|
||||
.Padding(0, 16, 0 ,0)
|
||||
[
|
||||
SNew(SBox).HeightOverride(32).WidthOverride(214)
|
||||
[
|
||||
SNew(SHorizontalBox)
|
||||
+ SHorizontalBox::Slot()
|
||||
.SizeParam(FAuto())
|
||||
.VAlign(VAlign_Center)
|
||||
[
|
||||
SNew(SBox)
|
||||
.VAlign(VAlign_Center)
|
||||
.WidthOverride(62)
|
||||
.HeightOverride(32)
|
||||
[
|
||||
SNew(STextBlock)
|
||||
.Text(FText::FromString(TEXT("有效幕")))
|
||||
.Font(NormalText.Font)
|
||||
.Justification(ETextJustify::Center)
|
||||
]
|
||||
]
|
||||
+ SHorizontalBox::Slot()
|
||||
.SizeParam(FAuto())
|
||||
[
|
||||
SNew(SBox)
|
||||
.WidthOverride(136)
|
||||
.HeightOverride(32)
|
||||
[
|
||||
SAssignNew(AudiosCurtainComboBox, SComboBox<TSharedPtr<FStringWithGUID>>)
|
||||
.OptionsSource(&AudiosCurtainOptions)
|
||||
.OnGenerateWidget_Lambda([this](TSharedPtr<FStringWithGUID> InItem)
|
||||
{
|
||||
return SNew(SHorizontalBox)
|
||||
+ SHorizontalBox::Slot()
|
||||
[
|
||||
SNew(STextBlock).Text(FText::FromString(*InItem->String))
|
||||
]
|
||||
+ SHorizontalBox::Slot()
|
||||
.HAlign(HAlign_Right)
|
||||
[
|
||||
SNew(SCheckBox)
|
||||
.IsChecked(ClipData->AudioCurtains.Contains(*InItem.Get()) ? ECheckBoxState::Checked : ECheckBoxState::Unchecked)
|
||||
.OnCheckStateChanged_Lambda([this, InItem](const ECheckBoxState& State)
|
||||
{
|
||||
if (State == ECheckBoxState::Checked)
|
||||
{
|
||||
ClipData->AudioCurtains.Add(*InItem.Get());
|
||||
MainInterface->UpdateProperties(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClipData->AudioCurtains.Remove(*InItem.Get());
|
||||
MainInterface->UpdateProperties(this);
|
||||
}
|
||||
|
||||
|
||||
})
|
||||
];
|
||||
|
||||
})
|
||||
[
|
||||
SNew(STextBlock).Text_Lambda([this]()
|
||||
{
|
||||
if (ClipData->AudioCurtains.Num() == 1)
|
||||
{
|
||||
return FText::FromString(ClipData->AudioCurtains[0].String);
|
||||
}
|
||||
else if (ClipData->AudioCurtains.Num() > 1)
|
||||
{
|
||||
return FText::FromString(TEXT("多个"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return FText::FromString(TEXT("无"));
|
||||
}
|
||||
})
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
|
||||
return PropertiesWidget;
|
||||
|
@ -10,9 +10,11 @@ public:
|
||||
void UpdateInterface(TSharedPtr<class STimelineClip> InTimeClip);
|
||||
FSlateColor GetColor() const;
|
||||
virtual TSharedPtr<SWidget> GetPropertiesWidget() override;
|
||||
|
||||
void Reset();
|
||||
TArray<TSharedPtr<FStringWithGUID>> AudiosCurtainOptions;
|
||||
TSharedPtr<SComboBox<TSharedPtr<FString>>> GroupComboBox;
|
||||
TSharedPtr<SComboBox<TSharedPtr<FStringWithGUID>>> AudiosCurtainComboBox;
|
||||
void Reset();
|
||||
|
||||
TArray<TSharedPtr<FString>> Selectable;
|
||||
|
||||
TSharedPtr<STimelineClip> TimelineClip = nullptr;
|
||||
|
Loading…
Reference in New Issue
Block a user