IAmMaddieAtYou
WPF Video Editor program | Help with the (Timeline/TimeMarks)
This updates my Timeline and creates the Timemarks code:
public void UpdateTimeline() // Time ruler update
{
if (SliderS != null && mediaPlayer != null)
{
double totalMilliseconds = SliderS.Maximum;
double currentMilliseconds = SliderS.Value;
TrackLines.Children.Clear();
// Set TrackLines width
TrackLines.Width = totalMilliseconds * zoomFactor;
int intervalDivisor = (int)IntervalSlider.Value;
TimeSpan interval;
string timeFormat;
if (zoomFactor >= 3)
{
interval = TimeSpan.FromMilliseconds(totalMilliseconds / intervalDivisor);
timeFormat = @"fff\ ms";
}
else if (zoomFactor >= 2)
{
interval = TimeSpan.FromSeconds(totalMilliseconds / 1000 / intervalDivisor);
timeFormat = @"ss\ s";
}
else if (zoomFactor >= 1)
{
interval = TimeSpan.FromMinutes(totalMilliseconds / 1000 / 60 / intervalDivisor);
timeFormat = @"mm\:ss";
}
else
{
interval = TimeSpan.FromHours(totalMilliseconds / 1000 / 60 / 60 / intervalDivisor);
timeFormat = @"hh\:mm\:ss";
}
double pixelsPerMillisecond = zoomFactor;
// Calculate visible time window
double viewportStartPixels = TLines.HorizontalOffset;
double viewportEndPixels = viewportStartPixels + TLines.ViewportWidth;
double visibleStartTimeMilliseconds = viewportStartPixels / pixelsPerMillisecond;
double visibleEndTimeMilliseconds = viewportEndPixels / pixelsPerMillisecond;
// Ensure visible time window is within media bounds
visibleStartTimeMilliseconds = Math.Max(0, visibleStartTimeMilliseconds);
visibleEndTimeMilliseconds = Math.Min(totalMilliseconds, visibleEndTimeMilliseconds);
TimeSpan currentTime = TimeSpan.FromMilliseconds(visibleStartTimeMilliseconds);
string lasttick = "";
while (currentTime.TotalMilliseconds <= visibleEndTimeMilliseconds)
{
double position = currentTime.TotalMilliseconds * pixelsPerMillisecond;
Line tick = new Line
{
X1 = position,
X2 = position,
Y1 = TrackLines.ActualHeight - ((currentTime.TotalMilliseconds % (interval.TotalMilliseconds * 5) == 0) ? 10 : 5),
Y2 = TrackLines.ActualHeight,
Stroke = System.Windows.Media.Brushes.Black,
StrokeThickness = 1
};
TrackLines.Children.Add(tick);
if (currentTime.TotalMilliseconds % interval.TotalMilliseconds == 0)
{
string timeLabel = currentTime.ToString(timeFormat);
if (lasttick != timeLabel)
{
lasttick = timeLabel;
TextBlock label = new TextBlock
{
Text = timeLabel,
Foreground = System.Windows.Media.Brushes.Black,
FontSize = 10
};
Canvas.SetLeft(label, position - (label.ActualWidth / 2));
Canvas.SetTop(label, TrackLines.ActualHeight - 20);
TrackLines.Children.Add(label);
}
}
currentTime = currentTime.Add(interval);
}
}
}
public void UpdateTimeline() // Time ruler update
{
if (SliderS != null && mediaPlayer != null)
{
double totalMilliseconds = SliderS.Maximum;
double currentMilliseconds = SliderS.Value;
TrackLines.Children.Clear();
// Set TrackLines width
TrackLines.Width = totalMilliseconds * zoomFactor;
int intervalDivisor = (int)IntervalSlider.Value;
TimeSpan interval;
string timeFormat;
if (zoomFactor >= 3)
{
interval = TimeSpan.FromMilliseconds(totalMilliseconds / intervalDivisor);
timeFormat = @"fff\ ms";
}
else if (zoomFactor >= 2)
{
interval = TimeSpan.FromSeconds(totalMilliseconds / 1000 / intervalDivisor);
timeFormat = @"ss\ s";
}
else if (zoomFactor >= 1)
{
interval = TimeSpan.FromMinutes(totalMilliseconds / 1000 / 60 / intervalDivisor);
timeFormat = @"mm\:ss";
}
else
{
interval = TimeSpan.FromHours(totalMilliseconds / 1000 / 60 / 60 / intervalDivisor);
timeFormat = @"hh\:mm\:ss";
}
double pixelsPerMillisecond = zoomFactor;
// Calculate visible time window
double viewportStartPixels = TLines.HorizontalOffset;
double viewportEndPixels = viewportStartPixels + TLines.ViewportWidth;
double visibleStartTimeMilliseconds = viewportStartPixels / pixelsPerMillisecond;
double visibleEndTimeMilliseconds = viewportEndPixels / pixelsPerMillisecond;
// Ensure visible time window is within media bounds
visibleStartTimeMilliseconds = Math.Max(0, visibleStartTimeMilliseconds);
visibleEndTimeMilliseconds = Math.Min(totalMilliseconds, visibleEndTimeMilliseconds);
TimeSpan currentTime = TimeSpan.FromMilliseconds(visibleStartTimeMilliseconds);
string lasttick = "";
while (currentTime.TotalMilliseconds <= visibleEndTimeMilliseconds)
{
double position = currentTime.TotalMilliseconds * pixelsPerMillisecond;
Line tick = new Line
{
X1 = position,
X2 = position,
Y1 = TrackLines.ActualHeight - ((currentTime.TotalMilliseconds % (interval.TotalMilliseconds * 5) == 0) ? 10 : 5),
Y2 = TrackLines.ActualHeight,
Stroke = System.Windows.Media.Brushes.Black,
StrokeThickness = 1
};
TrackLines.Children.Add(tick);
if (currentTime.TotalMilliseconds % interval.TotalMilliseconds == 0)
{
string timeLabel = currentTime.ToString(timeFormat);
if (lasttick != timeLabel)
{
lasttick = timeLabel;
TextBlock label = new TextBlock
{
Text = timeLabel,
Foreground = System.Windows.Media.Brushes.Black,
FontSize = 10
};
Canvas.SetLeft(label, position - (label.ActualWidth / 2));
Canvas.SetTop(label, TrackLines.ActualHeight - 20);
TrackLines.Children.Add(label);
}
}
currentTime = currentTime.Add(interval);
}
}
}
private void PlaybackSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (mediaPlayer.NaturalDuration.HasTimeSpan)
{
mediaPlayer.Position = TimeSpan.FromMilliseconds(SliderS.Value); // Update Media ONLY
UpdateTimelineScroll();
UpdateTimeline();
}
}
private void PlaybackSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (mediaPlayer.NaturalDuration.HasTimeSpan)
{
mediaPlayer.Position = TimeSpan.FromMilliseconds(SliderS.Value); // Update Media ONLY
UpdateTimelineScroll();
UpdateTimeline();
}
}
private void UpdateTimelineWidth()
{
double newTimelineWidth = totalDurationMilliseconds * zoomFactor;
TrackBX.Width = newTimelineWidth;
TrackLines.Width = newTimelineWidth;
}
private void UpdateTimelineWidth()
{
double newTimelineWidth = totalDurationMilliseconds * zoomFactor;
TrackBX.Width = newTimelineWidth;
TrackLines.Width = newTimelineWidth;
}
17 replies
WPF Video Editor program | Help with the (Timeline/TimeMarks)
This updates my Timelines Scroll
private void UpdateTimelineScroll()
{
TLines.UpdateLayout();
TRLines.UpdateLayout();
TrackLines.UpdateLayout();
double currentPosition = SliderS.Value;
double viewportWidth = TLines.ViewportWidth;
double totalWidth = TrackLines.Width;
Console.WriteLine($"currentPosition: {currentPosition}, viewportWidth: {viewportWidth}, totalWidth: {totalWidth}, zoomFactor: {zoomFactor}");
if (viewportWidth > 0 && totalWidth > 0 && !double.IsNaN(currentPosition) && !double.IsNaN(zoomFactor))
{
// Calculate desired offset to keep current position centered
double targetOffset = Math.Round((currentPosition * zoomFactor) - (viewportWidth / 2), 2);
// Keep offset within bounds
targetOffset = Math.Max(0, Math.Min(targetOffset, totalWidth - viewportWidth));
if (!double.IsNaN(targetOffset))
{
Dispatcher.BeginInvoke(() =>
{
TLines.ScrollToHorizontalOffset(targetOffset);
TRLines.ScrollToHorizontalOffset(targetOffset);
});
}
else
{
Console.WriteLine("Target offset is NaN");
}
}
else
{
Console.WriteLine("One or more values are invalid");
}
}
private void UpdateTimelineScroll()
{
TLines.UpdateLayout();
TRLines.UpdateLayout();
TrackLines.UpdateLayout();
double currentPosition = SliderS.Value;
double viewportWidth = TLines.ViewportWidth;
double totalWidth = TrackLines.Width;
Console.WriteLine($"currentPosition: {currentPosition}, viewportWidth: {viewportWidth}, totalWidth: {totalWidth}, zoomFactor: {zoomFactor}");
if (viewportWidth > 0 && totalWidth > 0 && !double.IsNaN(currentPosition) && !double.IsNaN(zoomFactor))
{
// Calculate desired offset to keep current position centered
double targetOffset = Math.Round((currentPosition * zoomFactor) - (viewportWidth / 2), 2);
// Keep offset within bounds
targetOffset = Math.Max(0, Math.Min(targetOffset, totalWidth - viewportWidth));
if (!double.IsNaN(targetOffset))
{
Dispatcher.BeginInvoke(() =>
{
TLines.ScrollToHorizontalOffset(targetOffset);
TRLines.ScrollToHorizontalOffset(targetOffset);
});
}
else
{
Console.WriteLine("Target offset is NaN");
}
}
else
{
Console.WriteLine("One or more values are invalid");
}
}
17 replies
WPF Video Editor program | Help with the (Timeline/TimeMarks)
Code for majority of it:
Scrolling mechanism
I create a dispatcherTimer that updates my timeline
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(1); // Reduced interval
timer.Tick += Timer_Tick;
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(1); // Reduced interval
timer.Tick += Timer_Tick;
private void Timer_Tick(object sender, EventArgs e)
{
if (mediaPlayer.Source != null && mediaPlayer.NaturalDuration.HasTimeSpan)
{
Wahoo();
SliderS.Value = mediaPlayer.Position.TotalMilliseconds; // Update Slider ONLY
UpdateTimelineScroll();
UpdateTimeline();
}
}
private void Timer_Tick(object sender, EventArgs e)
{
if (mediaPlayer.Source != null && mediaPlayer.NaturalDuration.HasTimeSpan)
{
Wahoo();
SliderS.Value = mediaPlayer.Position.TotalMilliseconds; // Update Slider ONLY
UpdateTimelineScroll();
UpdateTimeline();
}
}
17 replies