diff options
-rw-r--r-- | yt/src/watch/events/mod.rs | 50 | ||||
-rw-r--r-- | yt/src/watch/mod.rs | 36 |
2 files changed, 70 insertions, 16 deletions
diff --git a/yt/src/watch/events/mod.rs b/yt/src/watch/events/mod.rs index 413fb4b..d2a94a0 100644 --- a/yt/src/watch/events/mod.rs +++ b/yt/src/watch/events/mod.rs @@ -8,18 +8,14 @@ // You should have received a copy of the License along with this program. // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -use std::{ - collections::{HashMap, HashSet}, - time::Duration, -}; +use std::collections::{HashMap, HashSet}; use anyhow::{Context, Result}; use libmpv2::{ events::{Event, PlaylistEntryId}, EndFileReason, Mpv, }; -use log::{debug, info, warn}; -use tokio::time; +use log::{debug, info}; use crate::{ app::App, @@ -37,6 +33,20 @@ use playlist_handler::PlaylistHandler; mod handlers; mod playlist_handler; +#[derive(Debug, Clone, Copy)] +pub enum IdleCheckOutput { + /// There are no videos already downloaded and no more marked to be watched. + /// Waiting is pointless. + NoMoreAvailable, + + /// There are no videos cached, but some (>0) are marked to be watched. + /// So we should wait for them to become available. + NoCached { marked_watched: usize }, + + /// There are videos cached and ready to be inserted into the playback queue. + Available { newly_available: Option<usize> }, +} + #[derive(Debug)] pub struct MpvEventHandler { watch_later_block_list: HashSet<ExtractorHash>, @@ -210,19 +220,35 @@ impl MpvEventHandler { } /// Check if the playback queue is empty - pub async fn check_idle(&mut self, app: &App, mpv: &Mpv) -> Result<bool> { + pub async fn check_idle(&mut self, app: &App, mpv: &Mpv) -> Result<IdleCheckOutput> { if mpv.get_property::<bool>("idle-active")? { - warn!("There is nothing to watch yet. Will idle, until something is available"); + // The playback is currently not running, but we might still have more videos lined up + // to be inserted into the queue. + let number_of_new_videos = self.possibly_add_new_videos(app, mpv, false).await?; if number_of_new_videos == 0 { - time::sleep(Duration::from_secs(10)).await; - Ok(true) + let watch_videos = get_videos(app, &[VideoStatus::Watch], None).await?.len(); + + if watch_videos == 0 { + // There are no more videos left. We should exit now. + Ok(IdleCheckOutput::NoMoreAvailable) + } else { + // There are still videos that *could* get downloaded. Wait for them. + Ok(IdleCheckOutput::NoCached { + marked_watched: watch_videos, + }) + } } else { - Ok(false) + Ok(IdleCheckOutput::Available { + newly_available: Some(number_of_new_videos), + }) } } else { - Ok(false) + // The playback is running. Obviously, something is available. + Ok(IdleCheckOutput::Available { + newly_available: None, + }) } } diff --git a/yt/src/watch/mod.rs b/yt/src/watch/mod.rs index 5c76c12..6e7c372 100644 --- a/yt/src/watch/mod.rs +++ b/yt/src/watch/mod.rs @@ -8,12 +8,13 @@ // You should have received a copy of the License along with this program. // If not, see <https://www.gnu.org/licenses/gpl-3.0.txt>. -use std::collections::HashMap; +use std::{collections::HashMap, time::Duration}; use anyhow::{Context, Result}; -use events::MpvEventHandler; +use events::{IdleCheckOutput, MpvEventHandler}; use libmpv2::{events::EventContext, Mpv}; use log::{debug, info, warn}; +use tokio::time; use crate::{ app::App, @@ -24,6 +25,7 @@ use crate::{ pub mod events; +#[allow(clippy::too_many_lines)] pub async fn watch(app: &App) -> Result<()> { maintain(app, false).await?; @@ -107,8 +109,34 @@ pub async fn watch(app: &App) -> Result<()> { } let mut mpv_event_handler = MpvEventHandler::from_playlist(playlist_cache); - loop { - while mpv_event_handler.check_idle(app, &mpv).await? {} + let mut have_warned = (false, 0); + 'watchloop: loop { + 'waitloop: while let Ok(value) = mpv_event_handler.check_idle(app, &mpv).await { + match value { + IdleCheckOutput::NoMoreAvailable => { + break 'watchloop; + } + IdleCheckOutput::NoCached { marked_watched } => { + // try again next time. + if have_warned.0 { + if have_warned.1 != marked_watched { + warn!("Now {} videos are marked as watched.", marked_watched); + have_warned.1 = marked_watched; + } + } else { + warn!("There is nothing to watch yet, but still {} videos marked as to be watched. \ + Will idle, until they become available", marked_watched); + have_warned = (true, marked_watched); + } + time::sleep(Duration::from_secs(10)).await; + } + IdleCheckOutput::Available { newly_available: _ } => { + have_warned.0 = false; + // Something just became available! + break 'waitloop; + } + } + } if let Some(ev) = ev_ctx.wait_event(600.) { match ev { |