diff --git a/Source/Cut5/Interface/ExportThread.cpp b/Source/Cut5/Interface/ExportThread.cpp index 8edb7d9..05f9e65 100644 --- a/Source/Cut5/Interface/ExportThread.cpp +++ b/Source/Cut5/Interface/ExportThread.cpp @@ -45,8 +45,9 @@ uint32 FExportThread::Run() { LastPercent = CurrentPercent; LastMaxPercent = MaxPercent; - ::SetWindowTextW(ProcessText, *FString::Printf(TEXT("进度:%d/%d"), int32(CurrentPercent), int32(MaxPercent))); - ::SetWindowTextW(SubProcessText, *FString::Printf(TEXT("子进度:%d/%d"), int32(SubCurrentPercent), int32(SubMaxPercent))); + if (MaxPercent == 0) + MaxPercent = 1; + ::SetWindowTextW(ProcessText, *FString::Printf(TEXT("进度:%d%%"), float(CurrentPercent) / float(MaxPercent) > 1 ? 100 : int32(float(CurrentPercent) / float(MaxPercent) * 100))); } const LPMSG MSG = {nullptr}; diff --git a/Source/Cut5/Interface/VideoInterface.cpp b/Source/Cut5/Interface/VideoInterface.cpp index 58c8d22..f436b08 100644 --- a/Source/Cut5/Interface/VideoInterface.cpp +++ b/Source/Cut5/Interface/VideoInterface.cpp @@ -232,6 +232,10 @@ uint32 FVideoThread::Run() LastSeekFrame = CurrentSeekingFrame.load(); CurrentSeekingFrame = -1; } + else + { + FPlatformProcess::Sleep(0.1f); + } } return 0; } diff --git a/Source/Cut5/Widgets/SCutMainWindow.cpp b/Source/Cut5/Widgets/SCutMainWindow.cpp index 1645c79..fec9b95 100644 --- a/Source/Cut5/Widgets/SCutMainWindow.cpp +++ b/Source/Cut5/Widgets/SCutMainWindow.cpp @@ -448,10 +448,7 @@ void SCutMainWindow::Construct(const FArguments& InArgs) if (CutTimeline->ZoomSlider->GetValue() <= 1.0) { const float NewValue = CutTimeline->ZoomSlider->GetValue() + 0.1; - CutTimeline->ZoomSlider->SetValue(NewValue); - FGlobalData::DefaultTimeTickSpace = FMath::GetMappedRangeValueClamped(FVector2D(0, 1.0), FVector2D(GetCachedGeometry().GetLocalSize().X / FGlobalData::TrackLength, 14), NewValue); - CutTimeline->RenderGroup(); - CutTimeline->UpdateCursorPosition(CutTimeline->GetCursorPosition()); + CutTimeline->UpdateZoom(NewValue); } })); CommandList->MapAction(FShortCutCommands::Get().ZoomOutTimeline, FExecuteAction::CreateLambda([this]() @@ -459,10 +456,7 @@ void SCutMainWindow::Construct(const FArguments& InArgs) if (CutTimeline->ZoomSlider->GetValue() >= 0.1) { const float NewValue = CutTimeline->ZoomSlider->GetValue() - 0.1; - CutTimeline->ZoomSlider->SetValue(NewValue); - FGlobalData::DefaultTimeTickSpace = FMath::GetMappedRangeValueClamped(FVector2D(0, 1.0), FVector2D(GetCachedGeometry().GetLocalSize().X / FGlobalData::TrackLength, 14), NewValue); - CutTimeline->RenderGroup(); - CutTimeline->UpdateCursorPosition(CutTimeline->GetCursorPosition()); + CutTimeline->UpdateZoom(NewValue); } })); diff --git a/Source/Cut5/Widgets/SCutTimeline.cpp b/Source/Cut5/Widgets/SCutTimeline.cpp index 460678b..d830fe9 100644 --- a/Source/Cut5/Widgets/SCutTimeline.cpp +++ b/Source/Cut5/Widgets/SCutTimeline.cpp @@ -56,7 +56,7 @@ FReply SCutTimeline::OnDragOver(const FGeometry& MyGeometry, const FDragDropEven return SCompoundWidget::OnDragOver(MyGeometry, DragDropEvent); } -void SCutTimeline::UpdateTimelineLength() +float SCutTimeline::UpdateTimelineLength() { TimelineTickBox->SetWidthOverride(FGlobalData::TrackLength * FGlobalData::DefaultTimeTickSpace); for (const FSingleTrackGroupInstance& Interface : TrackGroupInstances) @@ -64,6 +64,30 @@ void SCutTimeline::UpdateTimelineLength() Interface.Body->UpdateTimelineLength(); } TimelineTick->TickLengthBox->SetWidthOverride(FGlobalData::TrackLength * FGlobalData::DefaultTimeTickSpace); + return FGlobalData::TrackLength * FGlobalData::DefaultTimeTickSpace; +} + +void SCutTimeline::UpdateZoom(float ZoomValue) +{ + const float OriginTickBoxOffset = LastSliderOffset; + FGlobalData::DefaultTimeTickSpace = FMath::GetMappedRangeValueClamped(FVector2D(0, 1.0), FVector2D(GetCachedGeometry().GetLocalSize().X / FGlobalData::TrackLength, 15.0), ZoomValue); + UpdateTimelineLength(); + const float TickBoxOffset = TickScrollBox->GetScrollOffsetOfEnd(); + LastSliderOffset = TickBoxOffset; + const float NewTickBoxOffset = TickBoxOffset - OriginTickBoxOffset; + + if (NewTickBoxOffset != 0.0f) + { + // GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, FString::Printf(TEXT("NewTickBoxOffset: %f"), NewTickBoxOffset)); + } + + const float Scalar = NewTickBoxOffset / TrackBodyHScrollBox->GetScrollOffsetOfEnd(); + + TrackBodyHScrollBox->SetScrollOffset(TrackBodyHScrollBox->GetScrollOffset() + (TrackBodyHScrollBox->GetScrollOffset() * Scalar)); + TickScrollBox->SetScrollOffset(TrackBodyHScrollBox->GetScrollOffset() + (TrackBodyHScrollBox->GetScrollOffset() * Scalar)); + UpdateCursorPosition(GetCursorPosition(), false); + + RenderGroup(); } void SCutTimeline::UpdateCursorPosition(int32 Frame, bool NeedSeek) @@ -215,36 +239,7 @@ void SCutTimeline::Construct(const FArguments& InArgs) }) .OnValueChanged_Lambda([this](float ChangedValue) { - FGlobalData::DefaultTimeTickSpace = FMath::GetMappedRangeValueClamped(FVector2D(0, 1.0), FVector2D(GetCachedGeometry().GetLocalSize().X / FGlobalData::TrackLength, 15.0), ChangedValue); - UpdateCursorPosition(GetCursorPosition(), false); - - - - int32 Frame = GetCursorPosition(); - - float Offset = TrackBodyHScrollBox->GetScrollOffset(); - float MaxOffset = TrackBodyHScrollBox->GetScrollOffsetOfEnd(); - float TickOffset = TickScrollBox->GetScrollOffset(); - float TickMaxOffset = TickScrollBox->GetScrollOffsetOfEnd(); - - - - - - - - TrackBodyHScrollBox->SetScrollOffset(Frame * FGlobalData::DefaultTimeTickSpace); - if (TickScrollBox->GetScrollOffset() > TickScrollBox->GetScrollOffsetOfEnd()) - { - TickScrollBox->SetScrollOffset(TickScrollBox->GetScrollOffsetOfEnd()); - } - else - { - TickScrollBox->SetScrollOffset(TrackBodyHScrollBox->GetScrollOffset()); - } - - - RenderGroup(); + UpdateZoom(ChangedValue); }) ] @@ -466,7 +461,7 @@ void SCutTimeline::Construct(const FArguments& InArgs) void SCutTimeline::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) { - + SCompoundWidget::Tick(AllottedGeometry, InCurrentTime, InDeltaTime); if (AutoPlaying) { TimeSpace += InDeltaTime; @@ -476,7 +471,17 @@ void SCutTimeline::Tick(const FGeometry& AllottedGeometry, const double InCurren TimeSpace = 0.0; } } - SCompoundWidget::Tick(AllottedGeometry, InCurrentTime, InDeltaTime); + + float ScrollBoxOffset = TrackBodyHScrollBox->GetScrollOffset(); + float TickBoxOffset = TickScrollBox->GetScrollOffset(); + + float ScrollBoxMaxOffset = TrackBodyHScrollBox->GetScrollOffsetOfEnd(); + float TickBoxMaxOffset = TickScrollBox->GetScrollOffsetOfEnd(); + + // GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Yellow, FString::Printf(TEXT("ScrollBoxOffset: %f ScrollBoxMaxOffset: %f"), ScrollBoxOffset, ScrollBoxMaxOffset)); + // GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::White, FString::Printf(TEXT("TickBoxOffset: %f TickBoxMaxOffset: %f"), TickBoxOffset, TickBoxMaxOffset)); + + } bool FSingleTrackGroupInstance::IsThis(TSharedPtr WidgetInterface) const diff --git a/Source/Cut5/Widgets/SCutTimeline.h b/Source/Cut5/Widgets/SCutTimeline.h index bcd6c9e..62df955 100644 --- a/Source/Cut5/Widgets/SCutTimeline.h +++ b/Source/Cut5/Widgets/SCutTimeline.h @@ -65,7 +65,9 @@ public: SLATE_END_ARGS() virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; virtual FReply OnDragOver(const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent) override; - void UpdateTimelineLength(); + float UpdateTimelineLength(); + void UpdateZoom(float ZoomValue); + float LastSliderOffset = 0.0f; void UpdateCursorPosition(int32 Frame, bool NeedSeek = true); int32 GetCursorPosition() const; /** Constructs this widget with InArgs */ diff --git a/Source/Cut5/Widgets/STimelineClip.cpp b/Source/Cut5/Widgets/STimelineClip.cpp index 23637fc..ac54b15 100644 --- a/Source/Cut5/Widgets/STimelineClip.cpp +++ b/Source/Cut5/Widgets/STimelineClip.cpp @@ -267,15 +267,15 @@ void STimelineClip::Construct(const FArguments& InArgs) FRunnableThread::Create(Thread, TEXT("VideoThread")); MainWidgetInterface->GetSelf()->AddThread(FUtils::GetVideoThreadGuid(ClipData->ClipGuid), Thread); } - 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); - } + // 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); + // } } @@ -325,6 +325,39 @@ void STimelineClip::Construct(const FArguments& InArgs) } +STimelineClip::~STimelineClip() +{ + +} + +void STimelineClip::OnRemoved() +{ + if (MainWidgetInterface->GetSelf()->Threads.Contains(FUtils::GetVideoThreadGuid(ClipData->ClipGuid))) + { + if (FRunnable* Thread = MainWidgetInterface->GetSelf()->Threads[FUtils::GetVideoThreadGuid(ClipData->ClipGuid)]) + { + Thread->Stop(); + Thread = nullptr; + } + } + if (MainWidgetInterface->GetSelf()->Threads.Contains(FUtils::GetVideoThumbnailThreadGuid(ClipData->ClipGuid))) + { + if (FRunnable* Thread = MainWidgetInterface->GetSelf()->Threads[FUtils::GetVideoThumbnailThreadGuid(ClipData->ClipGuid)]) + { + Thread->Stop(); + Thread = nullptr; + } + } + if (MainWidgetInterface->GetSelf()->Threads.Contains(FUtils::GetSoundThreadGuid(ClipData->ClipGuid))) + { + if (FRunnable* Thread = MainWidgetInterface->GetSelf()->Threads[FUtils::GetSoundThreadGuid(ClipData->ClipGuid)]) + { + Thread->Stop(); + Thread = nullptr; + } + } +} + void STimelineClip::Seek(int32 Frame) { switch (ClipData->ClipType) @@ -666,34 +699,29 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe MainWidgetInterface->GetCutTimeline()->TimelineMainContentVerticalBox->GetCachedGeometry().AbsolutePosition).X; // MainWidgetInterface->GetCutTimeline()->TimelineMainContentVerticalBox->GetCachedGeometry().LocalToAbsolute(FVector2D(0, 0)).X; - const float RangeEnd = MainWidgetInterface->GetSelf()->GetCachedGeometry().GetLocalSize().X; + const float RangeEnd = MainWidgetInterface->GetSelf()->GetCachedGeometry().AbsoluteToLocal( + MainWidgetInterface->GetCutTimeline()->TimelineMainContentVerticalBox->GetCachedGeometry().AbsolutePosition + MainWidgetInterface->GetCutTimeline()->TimelineMainContentVerticalBox->GetCachedGeometry().GetAbsoluteSize()).X; - // MainWidgetInterface->GetCutTimeline()->TimelineMainContentVerticalBox->GetCachedGeometry().GetLocalSize().X; - const float CurrentStartRange = MainWidgetInterface->GetSelf()->GetCachedGeometry().AbsoluteToLocal( - AllottedGeometry.GetAbsolutePosition()).X; - const float CurrentEndRange = AllottedGeometry.LocalToAbsolute(FVector2D(AllottedGeometry.GetLocalSize().X, 0)).X; + const float CurrentStartRange = MainWidgetInterface->GetSelf()->GetCachedGeometry().AbsoluteToLocal(GetCachedGeometry().GetAbsolutePosition()).X; + const float CurrentEndRange = MainWidgetInterface->GetSelf()->GetCachedGeometry().AbsoluteToLocal(GetCachedGeometry().GetAbsolutePosition() + GetCachedGeometry().GetAbsoluteSize()).X; - GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Red, FString::FromInt(CurrentStartRange)); - GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Yellow, FString::FromInt(CurrentEndRange)); - GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Green, FString::FromInt(RangeStart)); - GEngine->AddOnScreenDebugMessage(-1, 0.0f, FColor::Blue, FString::FromInt(RangeEnd)); - - int32 CropStartFrameOffset = ((CurrentStartRange * -1) + RangeStart > 0 ? (CurrentStartRange * -1) + RangeStart : 0) / FGlobalData::DefaultTimeTickSpace; if (CurrentEndRange < RangeStart) { CropStartFrameOffset = -1; } + int32 CropEndFrameOffset = -1; + if (RangeEnd - CurrentEndRange > 0) + { + CropEndFrameOffset = (CropStartFrameOffset * FGlobalData::DefaultTimeTickSpace) + (RangeEnd - RangeStart) - (RangeEnd - CurrentEndRange); + } + else + { + CropEndFrameOffset = CropStartFrameOffset * FGlobalData::DefaultTimeTickSpace + (RangeEnd - RangeStart); + } - const int32 CropEndFrameOffset = (RangeEnd - CurrentEndRange > 0 ? - (CropStartFrameOffset * FGlobalData::DefaultTimeTickSpace) + (RangeEnd - RangeStart) - (RangeEnd - CurrentEndRange) : CropStartFrameOffset * FGlobalData::DefaultTimeTickSpace + (RangeEnd - RangeStart)) - / FGlobalData::DefaultTimeTickSpace; - - int32 NeedDrawCount = (CropEndFrameOffset - CropStartFrameOffset) * FGlobalData::DefaultTimeTickSpace; - - - + int32 NeedDrawCount = (CropEndFrameOffset - CropStartFrameOffset) * FGlobalData::DefaultTimeTickSpace * 2; const int32 StartOffset = (ClipData->ResourcePropertyDataPtr->AudioSample / FGlobalData::GlobalFPS) * ClipData->VideoStartFrame @@ -772,8 +800,17 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe // FSlateDrawElement::MakeLines(OutDrawElements, LayerId + 6, AllottedGeometry.ToPaintGeometry(), NewLoc, ESlateDrawEffect::None, // FColor(45, 214, 153, 255), true, DownSample * 1.2); // } - FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 5, AllottedGeometry.ToPaintGeometry(), - &Brush, ESlateDrawEffect::None, FColor(22, 105, 78, 255)); + if (ClipData->ClipType == ETrackType::AudioTrack || ClipData->ClipType == ETrackType::AudioTrackR) + { + FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 5, AllottedGeometry.ToPaintGeometry(), + &Brush, ESlateDrawEffect::None, FColor(22, 105, 78, 255)); + } + if (IsVideo(ClipData->ClipType)) + { + FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 5, AllottedGeometry.ToPaintGeometry(), + &Brush, ESlateDrawEffect::None, FColor(123, 152, 199, 255)); + } + } @@ -798,21 +835,21 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe ClipData->ClipType == ETrackType::LightBarTrack)) { - int32 Step = ClipData->MovieBrushNum; - const int32 PerImageLength = TotalLength / ClipData->MovieBrushNum; - const int32 ShouldPerImageLength = TotalLength / 128; + float Step = ClipData->MovieBrushNum; + const int32 PerImageLength = 128; + const int32 ShouldPerImageLength = TotalLength / PerImageLength; if (ShouldPerImageLength != 0) { - Step = ClipData->MovieBrushNum / ShouldPerImageLength; + Step = float(ClipData->MovieBrushNum) / float(ShouldPerImageLength); } TArray NewBrushes; - int32 Current = 0; + float Current = 0.0f; for (int32 j = 0; j < ShouldPerImageLength; j++) { if (ClipData->MovieBrushes.Num() > 0 && Current < ClipData->MovieBrushes.Num()) - NewBrushes.Add(ClipData->MovieBrushes[Current]); + NewBrushes.Add(ClipData->MovieBrushes[int32(Current)]); Current += Step; } int32 i = 0; @@ -822,7 +859,7 @@ int32 STimelineClip::OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGe } for (FSlateBrush& SlateBrush : NewBrushes) { - FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 5, AllottedGeometry.ToPaintGeometry(FVector2f(XLength / NewBrushes.Num(), AllottedGeometry.GetLocalSize().Y), FSlateLayoutTransform(FVector2f(i * (XLength / NewBrushes.Num()), 0))), &SlateBrush); + FSlateDrawElement::MakeBox(OutDrawElements, LayerId + 5, AllottedGeometry.ToPaintGeometry(FVector2f(PerImageLength, AllottedGeometry.GetLocalSize().Y), FSlateLayoutTransform(FVector2f(i * PerImageLength, 0))), &SlateBrush); i++; } } @@ -1061,7 +1098,10 @@ void STimelineClip::Tick(const FGeometry& AllottedGeometry, const double InCurre } if (avcodec_receive_frame(VideoCodecContext, Frame) >= 0) { - break; + if (Frame->best_effort_timestamp >= Timestamp) + { + break; + } } }; diff --git a/Source/Cut5/Widgets/STimelineClip.h b/Source/Cut5/Widgets/STimelineClip.h index 21a6b60..a7d5711 100644 --- a/Source/Cut5/Widgets/STimelineClip.h +++ b/Source/Cut5/Widgets/STimelineClip.h @@ -40,6 +40,9 @@ public: /** Constructs this widget with InArgs */ void Construct(const FArguments& InArgs); + ~STimelineClip(); + + void OnRemoved(); FClipData* ClipData; ICutMainWidgetInterface* MainWidgetInterface; TSharedPtr ClipDataBox; diff --git a/Source/Cut5/Widgets/STrackBody.cpp b/Source/Cut5/Widgets/STrackBody.cpp index acb2d0b..5f42839 100644 --- a/Source/Cut5/Widgets/STrackBody.cpp +++ b/Source/Cut5/Widgets/STrackBody.cpp @@ -191,6 +191,7 @@ void STrackBody::RemoveClip(const FGuid& Guid) if (TrackHead->TrackData.ClipData[i].ClipGuid == Guid) { TrackHead->TrackData.ClipData.RemoveAt(i); + SlateClips[i]->OnRemoved(); SlateClips.RemoveAt(i); MainWidgetInterface->UpdateProperties(nullptr); break;