Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Progress download status #58

Open
aaalloc opened this issue Nov 4, 2023 · 1 comment
Open

Progress download status #58

aaalloc opened this issue Nov 4, 2023 · 1 comment
Assignees
Labels
enhancement New feature or request

Comments

@aaalloc
Copy link

aaalloc commented Nov 4, 2023

I think it would be great to implement some logic to get the progress of the current download through your wrapper because you are directly returning the YoutubeDlOutput here:

pub async fn run_async(&self) -> Result<YoutubeDlOutput, Error> {
and with this choice you can't let the user of your wrapper implement there own logic for having progress download status.

If needed I can participate for the implementation of this feature.

@GyrosOfWar GyrosOfWar self-assigned this Nov 21, 2023
@GyrosOfWar GyrosOfWar added the enhancement New feature or request label Nov 21, 2023
@neckaros
Copy link

Hello, if it can help I ended up doing my own wrapper to get progress. If you wan i can try to add it to this lib and do a merge request?

impl RsProgress {
    pub fn from_ytdl(str: &str) -> Option<Self> {
        let mut split = str.split("progress=");
        if let Some(progress_part) = split.nth(1) {
            let mut parts = progress_part.split("-");
           Some(Self {
                id: nanoid!(),
                current: parts.next().and_then(|p| p.parse::<u64>().ok()),
                total: parts.next().and_then(|p| p.replace("\"", "").parse::<u64>().ok())
            })
        } else {
            None
        }
    }
}

pub enum YtdlItem {
    Progress(RsProgress),
    Data(Result<Bytes, io::Error>)
}
pub struct YtDlCommandBuilder {
    cmd: Command,
}

impl YtDlCommandBuilder {
    pub fn new(path: &str) -> Self {
        let mut cmd = Command::new("yt-dlp");
        cmd.arg(path);
        Self {
            cmd        
        }
    }
    /// Ex: Path to cookies file in netscape format
    pub fn set_cookies(&mut self, path: &str) -> &mut Self {
        self.cmd
            .arg("-cookies")
            .arg(path);
        self
    }

    pub async fn run(&mut self) -> Result<Pin<Box<dyn Stream<Item = YtdlItem>>>, Error>
    {
        self.cmd
        .arg("--progress-template")
        .arg("\"download:progress=%(progress.downloaded_bytes)s-%(progress.total_bytes)s\"")
        .arg("-o").arg("-")
        .stdout(Stdio::piped())
        .stderr(Stdio::piped());
        let mut child = self.cmd
        .spawn()?;
    
        let stdout = ReaderStream::new(child.stdout.take().unwrap()).map(|b| YtdlItem::Data(b));
        let stderr = ReaderStream::new(child.stderr.take().unwrap()).filter_map(|f| { 
                let r = f.ok().and_then(|b| from_utf8(&b).ok().and_then(|b| RsProgress::from_ytdl(b).and_then(|p| Some(YtdlItem::Progress(p)))));
                r
            }
        );
        
        let merged = stdout.merge(stderr);

        Ok(Box::pin(merged))
    } 
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants