Rocket stream stdout from spawned process

#1

Hey, just playing around with rust and rocket, and I’ve gotten myself stuck here…

I’m not sure if there’s a better way to do this, but essentially what I’m trying to do, is to

  • spawn a process
  • take its stdout and get rocket to return the stream as a io::Result<Stream<Something>>
    (where Stream is from rocket::response::Stream)

after a fair bit messing around, I found that I can return a JSON response from a process’s stdout like this:

#[post("/get_info", format="json", data="<video>")]
fn get_info(video: Json<Video>) -> JsonValue {
    let output = Command::new("youtube-dl")
        .arg("--dump-json")
        .arg(&video.url)
        .output()
        .expect("failed to get info");

    let string_json = String::from_utf8_lossy(&output.stdout);
    
    let return_value = serde_json::from_str(&string_json).unwrap();
    JsonValue(return_value)
}

(where video is just this simple struct)

use rocket_contrib::json::{Json, JsonValue};
#[derive(Serialize, Deserialize)]
struct Video {
    url: String
}

now, I want to have a different function, which streams the process’s standard output to a person making a post request. This is the code I have so far, which won’t compile.
The code below took inspiration from https://rocket.rs/v0.4/guide/responses/#streaming

#[post("/download_video", data="<video>")]
//                           I'm not sure what this type should be
//                                                           ↓↓↓↓↓ 
fn download_video(video: Json<Video>) -> io::Result<Stream<ChildStdout>> {
    let mut child = Command::new("youtube-dl")
        .arg(&video.url)
        .arg("-o")
        .arg("-")
        .stdout(Stdio::piped()) // I'm not sure about this line, I added it in after doing a fair bit of searching
        .spawn()
        .expect("REEEEEEEEEEEEEEEEEEEEEEEEEEEEEE");
    
    // https://api.rocket.rs/rocket/response/struct.Stream.html
    // Stream::chunked(io::stdin(), 10)


    // nope still returning the wrong type
    let reader = BufReader::new(child.stdout);
    Stream::chunked(reader, 10)
}

So, I guess my problem here is that I don’t know what type I want my function to return.
Essentially, I want to be able to send a post request to this path
and then get a downloadable video.

In case anyone is wondering why I’m attempting to use rust to call youtube-dl when I probably could’ve just used flask + python…This is what came to mind when I randomly decided that I would attempt playing around with rust lol

This is the entire project’s source at the point of making this post if anyone wants to try compiling it

0 Likes