aboutsummaryrefslogtreecommitdiff
path: root/src/audio/ytdl.rs
blob: 645f3f49e2940072c0de72dcbd31e3ebc68df2ed (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/// This module is entirely adapted from the relevant code in Serenity.

use std::{
    process::{
        Command,
        Stdio,
    },
};

use serde_json::Value;
use serenity::{
    voice::{
        VoiceError,
    }
};
use lazy_static::lazy_static;

use crate::{Result, CONFIG};

lazy_static! {
    static ref YTDL_COMMAND: String = {
        let result = CONFIG.ytdl.clone().unwrap_or("youtube-dl".to_owned());
        log::debug!("got ytdl: {}", result);

        result
    };
}

pub fn ytdl_url(uri: &str) -> Result<String> {
    let args = [
        "-f",
        "webm[abr>0]/bestaudio/best",
        "--no-playlist",
        "--print-json",
        "--skip-download",
        uri,
    ];

    let out = Command::new(&*YTDL_COMMAND)
        .args(&args)
        .stdin(Stdio::null())
        .output()?;

    if !out.status.success() {
        log::error!("running ytdl {:?}", out);
        return Err(VoiceError::YouTubeDLRun(out).into());
    }

    let value = serde_json::from_reader(&out.stdout[..])?;
    let mut obj = match value {
        Value::Object(obj) => obj,
        other => return Err(VoiceError::YouTubeDLProcessing(other).into()),
    };

    match obj.remove("url") {
        Some(v) => match v {
            Value::String(uri) => Ok(uri),
            other => Err(VoiceError::YouTubeDLUrl(other).into()),
        },
        None => Err(VoiceError::YouTubeDLUrl(Value::Object(obj)).into()),
    }
}