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:
@@ -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.
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user