添加导出音频

This commit is contained in:
Sch 2023-08-14 13:32:47 +08:00
parent d96cd4370f
commit a66f4c6edb
8 changed files with 118 additions and 62 deletions

View File

@ -135,6 +135,7 @@ FString FFFMPEGUtils::LoadMedia(const FString& Path, FTimelinePropertyData* Prop
PropertyData->AudioCodecContext = AudioCodecContext;
PropertyData->AudioCodec = AudioCodec;
PropertyData->AudioSample = AudioCodecContext->sample_rate;
PropertyData->AudioChannels = AudioCodecContext->channels;
}

View File

@ -150,13 +150,54 @@ TArray<FEncodeVideoInfo> FUtils::TrackEncodeVideo(const FTrackData& TrackData, c
//
// av_write_trailer(outctx);
// avio_close(outctx->pb);
// avio_close(outctx->pb);
// avformat_free_context(outctx);
// av_frame_free(&frame);
}
TArray<FEncodeVideoInfo> FUtils::TrackEncodeAudio(const FTrackData& TrackData, const FString& ExportPath)
{
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)
{
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;
EncodeVideoInfos.Add(EncodeVideoInfo);
}
i++;
}
return EncodeVideoInfos;
}
FString FUtils::GetFfmepg()
{
return FPaths::ConvertRelativePathToFull(FPaths::ProjectDir() / TEXT("Binaries") / TEXT("Win64") / TEXT("ffmpeg.exe"));

View File

@ -23,7 +23,7 @@ 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 FString CurtainFullPath(const FString& GroupName)
{
return FPaths::Combine(FGlobalData::BasePath, FGlobalData::CurrentProjectName, TEXT("Curtain"), GroupName + TEXT(".bin"));

View File

@ -338,8 +338,8 @@ struct CUT5_API FTimelinePropertyData
AVCodec* AudioCodec = nullptr;
int32 VideoStream = -1;
int32 AudioStream = -1;
int32 AudioSample = 0;
int32 AudioChannels = 2;
// Base Data
FString MoviePath = "";

View File

@ -26,15 +26,22 @@ void DragDropOperator::OnDragOver(const FGeometry& MyGeometry, const FDragDropEv
if (DragDropBase->DragDropType == FCutDragDropBase::EType::MovePanel)
{
TSharedPtr<SCutTimeline> CutTimeline = StaticCastSharedPtr<SCutTimeline>(DragDropBase->DraggingWidget);
float ChangedValue = (MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X - DragDropEvent.GetOperationAs<FCutDragDropBase>()->DragOffset); // / TrackBodyHScrollBox->GetScrollOffsetOfEnd();
CutTimeline->TrackBodyHScrollBox->SetScrollOffset(CutTimeline->TrackBodyHScrollBox->GetScrollOffset() - ChangedValue);
CutTimeline->TickScrollBox->SetScrollOffset(CutTimeline->TickScrollBox->GetScrollOffset() - ChangedValue);
DragDropEvent.GetOperationAs<FCutDragDropBase>()->DragOffset = (MyGeometry.AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X);
FGlobalData::CurrentTimeScroll = ChangedValue;
float ChangedValue = (CutTimeline->GetCachedGeometry().AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X - DragDropEvent.GetOperationAs<FCutDragDropBase>()->DragOffset); // / TrackBodyHScrollBox->GetScrollOffsetOfEnd();
if (CutTimeline->TrackBodyHScrollBox->GetScrollOffset() <= CutTimeline->TrackBodyHScrollBox->GetScrollOffsetOfEnd() - 10.0)
{
CutTimeline->TrackBodyHScrollBox->SetScrollOffset(CutTimeline->TrackBodyHScrollBox->GetScrollOffset() - ChangedValue);
CutTimeline->TickScrollBox->SetScrollOffset(CutTimeline->TrackBodyHScrollBox->GetScrollOffset());
DragDropEvent.GetOperationAs<FCutDragDropBase>()->DragOffset = (CutTimeline->GetCachedGeometry().AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X);
GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Red, FString::Printf(TEXT("ChangedValue: %f"), CutTimeline->TrackBodyHScrollBox->GetScrollOffset()));
}
else
{
CutTimeline->TickScrollBox->SetScrollOffset(CutTimeline->TrackBodyHScrollBox->GetScrollOffsetOfEnd() - 11.0);
DragDropEvent.GetOperationAs<FCutDragDropBase>()->DragOffset = (CutTimeline->GetCachedGeometry().AbsoluteToLocal(DragDropEvent.GetScreenSpacePosition()).X);
}
return;
}
if (DragDropBase->DragDropType == FCutDragDropBase::EType::ColorDragH || DragDropBase->DragDropType == FCutDragDropBase::EType::ColorDragV)
{
TSharedPtr<SColorBar> ColorBar = StaticCastSharedPtr<SColorBar>(DragDropBase->DraggingWidget);

View File

@ -383,37 +383,32 @@ void SCutMainWindow::Render()
StatePanel->PlayerList2->ClearChildren();
PlayerLightsSlateInstances.Empty();
bool bSingle = false;
for (FTrackGroup& TrackGroup : CutTimeline->TrackGroups)
{
if (TrackGroup.GroupType == ETrackType::PlayerTrack)
{
int32 i = 0;
FString LastGroupName;
for (FSingleTrackGroupInstance& TrackGroupInstance : CutTimeline->TrackGroupInstances)
{
if (LastGroupName != TrackGroupInstance.GroupName)
i = 0;
if (TrackGroupInstance.GroupName == TrackGroup.GroupName && StaticCastSharedPtr<STrackHead>(TrackGroupInstance.GetHead())->TrackData.TrackType == ETrackType::AtomSphereLightTrack)
{
LastGroupName = TrackGroupInstance.GroupName;
FString NewName = TrackGroupInstance.GroupName + FString::FromInt(i);
TSharedPtr<SPlayerLight> PlayerLight = SNew(SPlayerLight).Name(NewName).TrackHead(TrackGroupInstance.Head);
(bSingle ? StatePanel->PlayerList1 : StatePanel->PlayerList2)->AddSlot()
.SizeParam(FAuto())
[
PlayerLight.ToSharedRef()
];
bSingle = !bSingle;
PlayerLightsSlateInstances.Add(PlayerLight);
}
i++;
}
int32 i = 0;
FString LastGroupName;
for (FSingleTrackGroupInstance& TrackGroupInstance : CutTimeline->TrackGroupInstances)
{
if (LastGroupName != TrackGroupInstance.GroupName)
i = 0;
if (StaticCastSharedPtr<STrackHead>(TrackGroupInstance.GetHead())->TrackData.TrackType == ETrackType::AtomSphereLightTrack)
{
LastGroupName = TrackGroupInstance.GroupName;
FString NewName = TrackGroupInstance.GroupName + FString::FromInt(i);
TSharedPtr<SPlayerLight> PlayerLight = SNew(SPlayerLight).Name(NewName).TrackHead(TrackGroupInstance.Head);
(bSingle ? StatePanel->PlayerList1 : StatePanel->PlayerList2)->AddSlot()
.SizeParam(FAuto())
[
PlayerLight.ToSharedRef()
];
bSingle = !bSingle;
PlayerLightsSlateInstances.Add(PlayerLight);
}
i++;
}
}
int32 SCutMainWindow::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry,
@ -600,7 +595,8 @@ void SCutMainWindow::OpenTimeline(const FString& TimelineName, bool NeedSaveBefo
CutTimeline->TimelineInfo = TimelineInfo;
CutTimeline->CurrentEditDebug->SetText(FText::FromString(TEXT("当前正在编辑") + TimelineInfo.CurrentOpenFullPath));
}
OnAddNewTrack(ETrackType::PlayerTrack);
}
void SCutMainWindow::OpenProject(const FString& Project)
@ -1193,22 +1189,23 @@ tinyxml2::XMLElement* SCutMainWindow::GetVideoElement(tinyxml2::XMLElement* Pare
return Parent;
}
tinyxml2::XMLElement* SCutMainWindow::GetSoundElement(tinyxml2::XMLElement* Parent)
tinyxml2::XMLElement* SCutMainWindow::GetSoundElement(tinyxml2::XMLElement* Parent, FEncodeVideoInfo EncodeVideoInfo)
{
tinyxml2::XMLElement* Sound = Parent->InsertNewChildElement("Sound");
tinyxml2::XMLElement* URL = Sound->InsertNewChildElement("URL");
tinyxml2::XMLElement* Loop = Sound->InsertNewChildElement("Loop");
tinyxml2::XMLElement* Mode = Sound->InsertNewChildElement("Mode");
tinyxml2::XMLElement* Round = Sound->InsertNewChildElement("Round");
tinyxml2::XMLElement* Timecode = Sound->InsertNewChildElement("Timecode");
tinyxml2::XMLElement* VolumeEventList = Sound->InsertNewChildElement("VolumeEventList");
{
tinyxml2::XMLElement* VolumeEvent = VolumeEventList->InsertNewChildElement("VolumeEvent");
Sound->InsertNewChildElement("URL")->InsertNewText(TCHAR_TO_UTF8(*(FPaths::GetBaseFilename(EncodeVideoInfo.EncodedVideoName) + TEXT(".mp3"))));
Sound->InsertNewChildElement("Loop")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(0)));
Sound->InsertNewChildElement("Mode")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(0)));
Sound->InsertNewChildElement("Round")->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(0)));
Sound->InsertNewChildElement("Timecode")->InsertNewText(TCHAR_TO_UTF8(*FUtils::GetMsFromString(EncodeVideoInfo.EncodedVideoTimeCode)));
tinyxml2::XMLElement* VolumeEventList = Sound->InsertNewChildElement("VolumeEventList");
{
tinyxml2::XMLElement* VolumeEventTimeCode = VolumeEvent->InsertNewChildElement("TimeCode");
tinyxml2::XMLElement* VolumeEventValue = VolumeEvent->InsertNewChildElement("Value");
tinyxml2::XMLElement* VolumeEvent = VolumeEventList->InsertNewChildElement("VolumeEvent");
{
tinyxml2::XMLElement* VolumeEventTimeCode = VolumeEvent->InsertNewChildElement("TimeCode");
tinyxml2::XMLElement* VolumeEventValue = VolumeEvent->InsertNewChildElement("Value");
}
}
}
return Parent;
}
@ -1221,7 +1218,7 @@ tinyxml2::XMLElement* SCutMainWindow::GetVideoListElement(tinyxml2::XMLElement*
if (StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData.TrackType == ETrackType::VideoTrack)
{
FString Filename = FGuid::NewGuid().ToString();
FString NewExportFilePath = FGlobalData::ExportPath / "Video" / Filename;
FString NewExportFilePath = FGlobalData::ExportPath / "video" / Filename;
TArray<FEncodeVideoInfo> EncodeVideoInfos = FUtils::TrackEncodeVideo(StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData, NewExportFilePath);
for (FEncodeVideoInfo EncodeVideoInfo : EncodeVideoInfos)
{
@ -1235,9 +1232,23 @@ tinyxml2::XMLElement* SCutMainWindow::GetVideoListElement(tinyxml2::XMLElement*
tinyxml2::XMLElement* SCutMainWindow::GetSoundListElement(tinyxml2::XMLElement* Parent)
{
tinyxml2::XMLElement* AudioList = Parent->InsertNewChildElement("SoundList");
{
for (int32 i = 0; i < CutTimeline->TrackGroupInstances.Num(); i++)
{
if (StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData.TrackType == ETrackType::AudioTrack ||
StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData.TrackType == ETrackType::AudioTrackR)
{
FString Filename = FGuid::NewGuid().ToString();
FString NewExportFilePath = FGlobalData::ExportPath / "audio" / Filename;
TArray<FEncodeVideoInfo> EncodeVideoInfos = FUtils::TrackEncodeAudio(StaticCastSharedPtr<STrackHead>(CutTimeline->TrackGroupInstances[i].Head)->TrackData, NewExportFilePath);
for (FEncodeVideoInfo EncodeVideoInfo : EncodeVideoInfos)
{
GetSoundElement(AudioList, EncodeVideoInfo);
}
}
}
}
return nullptr;
}
@ -1257,13 +1268,9 @@ tinyxml2::XMLElement* SCutMainWindow::GetProcessB(tinyxml2::XMLElement* Parent,
tinyxml2::XMLElement* ProcessID = ProcessB->InsertNewChildElement("ID");
tinyxml2::XMLElement* AutoNext = ProcessB->InsertNewChildElement("AutoNext");
tinyxml2::XMLElement* TimeLength = ProcessB->InsertNewChildElement("TimeLength");
tinyxml2::XMLElement* SoundList = ProcessB->InsertNewChildElement("SoundList");
{
GetSoundElement(SoundList);
}
GetSoundListElement(ProcessB);
ProcessB->InsertEndChild(GetDeviceElement(ProcessB));
GetVideoListElement(ProcessB);
// 非必须项
@ -1323,7 +1330,7 @@ tinyxml2::XMLElement* SCutMainWindow::GetSpecialEffectGroup(tinyxml2::XMLElement
ID->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(Group->ID)));
}
tinyxml2::XMLElement* AutoNext = SpecialEffect->InsertNewChildElement("AutoNext");
GetSoundElement(SpecialEffect);
GetSoundListElement(SpecialEffect);
GetDeviceElement(SpecialEffect);
GetVideoListElement(SpecialEffect);
tinyxml2::XMLElement* IsGlobal = SpecialEffect->InsertNewChildElement("IsGlobal");
@ -1347,7 +1354,7 @@ tinyxml2::XMLElement* SCutMainWindow::GetSpecialEffect(tinyxml2::XMLElement* Par
ID->InsertNewText(TCHAR_TO_UTF8(*FString::FromInt(Effect->ID)));
}
tinyxml2::XMLElement* AutoNext = SpecialEffect->InsertNewChildElement("AutoNext");
GetSoundElement(SpecialEffect);
GetSoundListElement(SpecialEffect);
GetDeviceElement(SpecialEffect);
GetVideoListElement(SpecialEffect);
tinyxml2::XMLElement* IsGlobal = SpecialEffect->InsertNewChildElement("IsGlobal");

View File

@ -83,7 +83,7 @@ public:
tinyxml2::XMLElement* GetDeviceElement(tinyxml2::XMLElement* Parent);
tinyxml2::XMLElement* GetVideoElement(tinyxml2::XMLElement* Parent, FEncodeVideoInfo EncodeVideoInfo);
tinyxml2::XMLElement* GetSoundElement(tinyxml2::XMLElement* Parent);
tinyxml2::XMLElement* GetSoundElement(tinyxml2::XMLElement* Parent, FEncodeVideoInfo EncodeVideoInfo);
tinyxml2::XMLElement* GetVideoListElement(tinyxml2::XMLElement* Parent);
tinyxml2::XMLElement* GetSoundListElement(tinyxml2::XMLElement* Parent);

View File

@ -29,8 +29,8 @@ FReply SCutTimeline::OnMouseButtonDown(const FGeometry& MyGeometry, const FPoint
FReply SCutTimeline::OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent)
{
DragDropOperator* DragDropOperator = DragDropOperator::GetDragDropOperator();
DragDropOperator->OnDragOver(MyGeometry, DragDropEvent);
// DragDropOperator* DragDropOperator = DragDropOperator::GetDragDropOperator();
// DragDropOperator->OnDragOver(MyGeometry, DragDropEvent);
return SCompoundWidget::OnDragOver(MyGeometry, DragDropEvent);
}