104 lines
2.8 KiB
Rust
104 lines
2.8 KiB
Rust
use serenity::voice::ffmpeg;
|
|
use std::process::{Command, Output, Stdio};
|
|
use std::str::from_utf8;
|
|
|
|
use player::Song;
|
|
|
|
const FIRST_LOAD_PREFIX: &str = "[download] Destination:";
|
|
const RELOAD_SUFFIX: &str = " has already been downloaded";
|
|
const PREFIX: &str = "[download] ";
|
|
|
|
pub fn convert_file_name(file: String) -> String {
|
|
let mut file = file.to_string();
|
|
let file_name_len = file.len();
|
|
|
|
let mut file_without_suffix = if file.ends_with(".webm") {
|
|
file.split_off(file_name_len - 5);
|
|
file
|
|
} else {
|
|
file
|
|
};
|
|
|
|
let file_without_id = match file_without_suffix.rfind("-") {
|
|
Some(minus_pos) => {
|
|
file_without_suffix.split_off(minus_pos);
|
|
file_without_suffix
|
|
}
|
|
None => file_without_suffix,
|
|
};
|
|
|
|
file_without_id
|
|
}
|
|
|
|
fn convert_output(out: &Output) -> Result<Vec<String>, String> {
|
|
match from_utf8(out.stdout.as_slice()) {
|
|
Ok(string) => {
|
|
let lines = string.split("\n");
|
|
|
|
let mut files = Vec::new();
|
|
|
|
for line in lines {
|
|
if !line.is_empty() {
|
|
let mut line = line.to_string();
|
|
let line_len = line.len();
|
|
|
|
if line.starts_with(FIRST_LOAD_PREFIX) {
|
|
let file_name = line.split_off(FIRST_LOAD_PREFIX.len());
|
|
files.push(file_name.trim().to_string());
|
|
} else if line.ends_with(RELOAD_SUFFIX) {
|
|
line.split_off(line_len - RELOAD_SUFFIX.len());
|
|
let file_name = line.split_off(PREFIX.len());
|
|
files.push(file_name.trim().to_string());
|
|
}
|
|
}
|
|
}
|
|
|
|
let mut mp3s = Vec::new();
|
|
|
|
for file in files {
|
|
mp3s.push(str::replace(file.as_str(), ".webm", ".mp3").to_string());
|
|
}
|
|
|
|
Ok(mp3s)
|
|
}
|
|
|
|
Err(_) => Err("error converting output".to_string()),
|
|
}
|
|
}
|
|
|
|
pub fn youtube_dl(uri: &str) -> Result<Vec<Song>, String> {
|
|
let args = ["-f", "bestaudio/best", "-o", "%(title)s", uri];
|
|
|
|
let out = match Command::new("youtube-dl")
|
|
.args(&args)
|
|
.stdin(Stdio::null())
|
|
.output()
|
|
{
|
|
Ok(out) => out,
|
|
Err(_) => return Err("youtube-dl error".to_string()),
|
|
};
|
|
|
|
if !out.status.success() {
|
|
return Err("shell error".to_string());
|
|
}
|
|
|
|
let files = check_result!(convert_output(&out));
|
|
|
|
for file in &files {
|
|
println!("file: {}", file);
|
|
}
|
|
|
|
let mut ffmpegs = Vec::new();
|
|
|
|
for file in files {
|
|
match ffmpeg(&file) {
|
|
Ok(mpeg) => ffmpegs.push(Song {
|
|
source: mpeg,
|
|
name: file,
|
|
}),
|
|
Err(_) => return Err("ffmpeg error".to_string()),
|
|
}
|
|
}
|
|
|
|
Ok(ffmpegs)
|
|
}
|