diff options
author | Zaggy1024 <zaggy1024@gmail.com> | 2022-11-11 22:26:19 -0600 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-11-25 23:28:39 +0100 |
commit | f31621b3f20b94f319390ac8fc786ee7f42d64d0 (patch) | |
tree | fcb566e7005432152121bd015f7ba92c4188ac07 /Userland/Applications/VideoPlayer | |
parent | e216d1a65f5a41060a38940525d8272a04db6f01 (diff) | |
download | serenity-f31621b3f20b94f319390ac8fc786ee7f42d64d0.zip |
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.
Diffstat (limited to 'Userland/Applications/VideoPlayer')
-rw-r--r-- | Userland/Applications/VideoPlayer/VideoPlayerWidget.cpp | 59 | ||||
-rw-r--r-- | Userland/Applications/VideoPlayer/VideoPlayerWidget.h | 3 |
2 files changed, 58 insertions, 4 deletions
diff --git a/Userland/Applications/VideoPlayer/VideoPlayerWidget.cpp b/Userland/Applications/VideoPlayer/VideoPlayerWidget.cpp index f4d53ca8c4..bafc0f523a 100644 --- a/Userland/Applications/VideoPlayer/VideoPlayerWidget.cpp +++ b/Userland/Applications/VideoPlayer/VideoPlayerWidget.cpp @@ -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) { diff --git a/Userland/Applications/VideoPlayer/VideoPlayerWidget.h b/Userland/Applications/VideoPlayer/VideoPlayerWidget.h index 9f3abe1ddc..2ef81d5251 100644 --- a/Userland/Applications/VideoPlayer/VideoPlayerWidget.h +++ b/Userland/Applications/VideoPlayer/VideoPlayerWidget.h @@ -36,6 +36,9 @@ private: VideoPlayerWidget(GUI::Window&); void update_play_pause_icon(); + void update_seek_slider_max(); + void set_current_timestamp(Time); + void set_time_label(Time); void on_decoding_error(Video::DecoderError const&); void display_next_frame(); |