mirror of
https://github.com/RGBCube/serenity
synced 2025-06-01 07:18:13 +00:00
VideoPlayer/LibVideo: Implement the UI functionality for seeking
With these changes, the seek bar can be used, but only to seek to the start of the file. Seeking to anywhere else in the file will cause an error in the demuxer. The timestamp label that was previously invisible now has its text set according to either the playback or seek slider's position.
This commit is contained in:
parent
e216d1a65f
commit
f31621b3f2
7 changed files with 84 additions and 13 deletions
|
@ -38,6 +38,17 @@ VideoPlayerWidget::VideoPlayerWidget(GUI::Window& window)
|
|||
m_seek_slider = player_controls_widget.add<GUI::HorizontalSlider>();
|
||||
m_seek_slider->set_fixed_height(20);
|
||||
m_seek_slider->set_enabled(false);
|
||||
m_seek_slider->on_change = [&](int value) {
|
||||
if (!m_playback_manager)
|
||||
return;
|
||||
update_seek_slider_max();
|
||||
auto progress = value / static_cast<double>(m_seek_slider->max());
|
||||
auto duration = m_playback_manager->duration().to_milliseconds();
|
||||
Time timestamp = Time::from_milliseconds(static_cast<i64>(round(progress * static_cast<double>(duration))));
|
||||
set_current_timestamp(timestamp);
|
||||
m_playback_manager->seek_to_timestamp(timestamp);
|
||||
};
|
||||
m_seek_slider->set_jump_to_cursor(true);
|
||||
|
||||
auto& toolbar_container = player_controls_widget.add<GUI::ToolbarContainer>();
|
||||
m_toolbar = toolbar_container.add<GUI::Toolbar>();
|
||||
|
@ -56,7 +67,7 @@ VideoPlayerWidget::VideoPlayerWidget(GUI::Window& window)
|
|||
m_toolbar->add_action(*m_play_pause_action);
|
||||
m_toolbar->add<GUI::VerticalSeparator>();
|
||||
m_timestamp_label = m_toolbar->add<GUI::Label>();
|
||||
m_timestamp_label->set_fixed_width(50);
|
||||
m_timestamp_label->set_autosize(true);
|
||||
|
||||
m_toolbar->add<GUI::Widget>(); // Filler widget
|
||||
|
||||
|
@ -89,6 +100,7 @@ void VideoPlayerWidget::open_file(StringView filename)
|
|||
|
||||
close_file();
|
||||
m_playback_manager = load_file_result.release_value();
|
||||
update_seek_slider_max();
|
||||
resume_playback();
|
||||
}
|
||||
|
||||
|
@ -162,6 +174,46 @@ void VideoPlayerWidget::on_decoding_error(Video::DecoderError const& error)
|
|||
GUI::MessageBox::show(&m_window, String::formatted(text_format, error.string_literal()), "Video Player encountered an error"sv);
|
||||
}
|
||||
|
||||
void VideoPlayerWidget::update_seek_slider_max()
|
||||
{
|
||||
if (!m_playback_manager) {
|
||||
m_seek_slider->set_enabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
m_seek_slider->set_max(static_cast<int>(min(m_playback_manager->duration().to_milliseconds(), NumericLimits<int>::max())));
|
||||
m_seek_slider->set_enabled(true);
|
||||
}
|
||||
|
||||
void VideoPlayerWidget::set_current_timestamp(Time timestamp)
|
||||
{
|
||||
set_time_label(timestamp);
|
||||
if (!m_playback_manager)
|
||||
return;
|
||||
auto progress = static_cast<double>(timestamp.to_milliseconds()) / static_cast<double>(m_playback_manager->duration().to_milliseconds());
|
||||
m_seek_slider->set_value(static_cast<int>(round(progress * m_seek_slider->max())), GUI::AllowCallback::No);
|
||||
}
|
||||
|
||||
void VideoPlayerWidget::set_time_label(Time timestamp)
|
||||
{
|
||||
StringBuilder string_builder;
|
||||
auto append_time = [&](Time time) {
|
||||
auto seconds = time.to_seconds();
|
||||
string_builder.appendff("{:02}:{:02}:{:02}", seconds / 3600, seconds / 60, seconds % 60);
|
||||
};
|
||||
|
||||
append_time(timestamp);
|
||||
|
||||
if (m_playback_manager) {
|
||||
string_builder.append(" / "sv);
|
||||
append_time(m_playback_manager->duration());
|
||||
} else {
|
||||
string_builder.append(" / --:--:--.---"sv);
|
||||
}
|
||||
|
||||
m_timestamp_label->set_text(string_builder.string_view());
|
||||
}
|
||||
|
||||
void VideoPlayerWidget::event(Core::Event& event)
|
||||
{
|
||||
if (event.type() == Video::EventType::DecoderErrorOccurred) {
|
||||
|
@ -174,9 +226,8 @@ void VideoPlayerWidget::event(Core::Event& event)
|
|||
m_video_display->set_bitmap(frame_event.frame());
|
||||
m_video_display->repaint();
|
||||
|
||||
m_seek_slider->set_max(m_playback_manager->duration().to_milliseconds());
|
||||
m_seek_slider->set_value(m_playback_manager->current_playback_time().to_milliseconds());
|
||||
m_seek_slider->set_enabled(true);
|
||||
update_seek_slider_max();
|
||||
set_current_timestamp(m_playback_manager->current_playback_time());
|
||||
|
||||
frame_event.accept();
|
||||
} else if (event.type() == Video::EventType::PlaybackStatusChange) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue