Input: Allow Restartable sources to be lazy

This change is made with queue users in mind. Since sources
of this kind *know* how to (re)create themselves, they can
avoid being created at all until needed.

This also adds machinery to preload tracks *before* they are
needed, for gapless playback on queues and so on. Queues
make use of the event system to do this.
This commit is contained in:
Kyle Simpson
2020-12-28 17:02:10 +00:00
parent c0d3cb3113
commit 03ae0e7628
10 changed files with 368 additions and 101 deletions

View File

@@ -11,7 +11,7 @@ use std::{
io::{BufRead, BufReader, Read},
process::{Command, Stdio},
};
use tokio::task;
use tokio::{process::Command as TokioCommand, task};
use tracing::trace;
const YOUTUBE_DL_COMMAND: &str = if cfg!(feature = "youtube-dlc") {
@@ -66,6 +66,7 @@ pub(crate) async fn _ytdl(uri: &str, pre_args: &[&str]) -> Result<Input> {
.stdout(Stdio::piped())
.spawn()?;
// This rigmarole is required due to the inner synchronous reading context.
let stderr = youtube_dl.stderr.take();
let (returned_stderr, value) = task::spawn_blocking(move || {
let mut s = stderr.unwrap();
@@ -113,6 +114,45 @@ pub(crate) async fn _ytdl(uri: &str, pre_args: &[&str]) -> Result<Input> {
))
}
pub(crate) async fn _ytdl_metadata(uri: &str) -> Result<Metadata> {
// Most of these flags are likely unused, but we want identical search
// and/or selection as the above functions.
let ytdl_args = [
"-j",
"-f",
"webm[abr>0]/bestaudio/best",
"-R",
"infinite",
"--no-playlist",
"--ignore-config",
uri,
"-o",
"-",
];
let youtube_dl_output = TokioCommand::new(YOUTUBE_DL_COMMAND)
.args(&ytdl_args)
.stdin(Stdio::null())
.output()
.await?;
let o_vec = youtube_dl_output.stderr;
let end = (&o_vec)
.iter()
.position(|el| *el == 0xA)
.unwrap_or_else(|| o_vec.len());
let value = serde_json::from_slice(&o_vec[..end]).map_err(|err| Error::Json {
error: err,
parsed_text: std::str::from_utf8(&o_vec).unwrap_or_default().to_string(),
})?;
let metadata = Metadata::from_ytdl_output(value);
Ok(metadata)
}
/// Creates a streamed audio source from YouTube search results with `youtube-dl(c)`,`ffmpeg`, and `ytsearch`.
/// Takes the first video listed from the YouTube search.
///