RMusicBot/src/youtube.rs

105 lines
2.8 KiB
Rust
Raw Normal View History

2018-08-14 16:42:53 +00:00
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());
}
}
2018-09-14 12:08:44 +00:00
}
let mut mp3s = Vec::new();
for file in files {
mp3s.push(str::replace(file.as_str(), ".webm", ".mp3").to_string());
2018-08-14 16:42:53 +00:00
}
2018-09-14 12:08:44 +00:00
Ok(mp3s)
2018-08-14 16:42:53 +00:00
}
Err(_) => Err("error converting output".to_string()),
}
}
pub fn youtube_dl(uri: &str) -> Result<Vec<Song>, String> {
2018-09-14 12:08:44 +00:00
let args = ["-x", "--audio-format", "mp3", "--audio-quality", "5", uri];
2018-08-14 16:42:53 +00:00
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)
}