summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock2
-rw-r--r--Cargo.toml2
-rw-r--r--src/main.rs31
-rw-r--r--src/playlist.rs18
-rw-r--r--src/youtube_dl.rs24
5 files changed, 42 insertions, 35 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 13a9f68..c229c66 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1829,6 +1829,8 @@ dependencies = [
"gstreamer-audio",
"log",
"log4rs",
+ "serde",
+ "serde_json",
"structopt",
"tokio 0.1.22",
"tokio 0.2.7",
diff --git a/Cargo.toml b/Cargo.toml
index 408e79e..13b743a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -30,3 +30,5 @@ gstreamer = "0.15.0"
gstreamer-app = "0.15.0"
gstreamer-audio = "0.15.0"
byte-slice-cast = "0.3.5"
+serde_json = "1.0.44"
+serde = "1.0.104"
diff --git a/src/main.rs b/src/main.rs
index 18b9cc7..93f2fd7 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -19,6 +19,7 @@ mod youtube_dl;
use audio_player::*;
use playlist::*;
use teamspeak::*;
+use youtube_dl::AudioMetadata;
#[derive(StructOpt, Debug)]
#[structopt(raw(global_settings = "&[AppSettings::ColoredHelp]"))]
@@ -107,33 +108,37 @@ impl Application {
}
}
- fn start_playing_audio(&self, request: AudioRequest) {
- self.send_message(&format!("Playing '{}'", request.title));
- self.set_description(&format!("Currently playing '{}'", request.title));
+ fn start_playing_audio(&self, metadata: AudioMetadata) {
+ if let Some(title) = metadata.title {
+ self.send_message(&format!("Playing '{}'", title));
+ self.set_description(&format!("Currently playing '{}'", title));
+ } else {
+ self.send_message("Playing unknown title");
+ self.set_description("Currently playing");
+ }
self.player.reset().unwrap();
- self.player.set_source_url(request.address).unwrap();
+ self.player.set_source_url(metadata.url).unwrap();
self.player.play().unwrap();
}
pub async fn add_audio(&self, url: String) {
match youtube_dl::get_audio_download_url(url).await {
- Ok((audio_url, audio_title)) => {
- info!("Found audio url: {}", audio_url);
-
- let request = AudioRequest {
- title: audio_title,
- address: audio_url,
- };
+ Ok(metadata) => {
+ info!("Found audio url: {}", metadata.url);
let mut playlist = self.playlist.lock().expect("Mutex was not poisoned");
- playlist.push(request.clone());
+ playlist.push(metadata.clone());
if !self.player.is_started() {
if let Some(request) = playlist.pop() {
self.start_playing_audio(request);
}
} else {
- self.send_message(&format!("Added '{}' to playlist", request.title));
+ if let Some(title) = metadata.title {
+ self.send_message(&format!("Added '{}' to playlist", title));
+ } else {
+ self.send_message("Added to playlist");
+ }
}
}
Err(e) => {
diff --git a/src/playlist.rs b/src/playlist.rs
index 86b9100..87c1c98 100644
--- a/src/playlist.rs
+++ b/src/playlist.rs
@@ -2,8 +2,10 @@ use std::collections::VecDeque;
use log::info;
+use crate::youtube_dl::AudioMetadata;
+
pub struct Playlist {
- data: VecDeque<AudioRequest>,
+ data: VecDeque<AudioMetadata>,
}
impl Playlist {
@@ -13,13 +15,13 @@ impl Playlist {
}
}
- pub fn push(&mut self, req: AudioRequest) {
- info!("Adding {} to playlist", &req.title);
+ pub fn push(&mut self, data: AudioMetadata) {
+ info!("Adding {:?} to playlist", &data.title);
- self.data.push_front(req)
+ self.data.push_front(data)
}
- pub fn pop(&mut self) -> Option<AudioRequest> {
+ pub fn pop(&mut self) -> Option<AudioMetadata> {
let res = self.data.pop_back();
info!("Popping {:?} from playlist", res.as_ref().map(|r| &r.title));
@@ -36,9 +38,3 @@ impl Playlist {
info!("Cleared playlist")
}
}
-
-#[derive(Clone, Debug)]
-pub struct AudioRequest {
- pub title: String,
- pub address: String,
-}
diff --git a/src/youtube_dl.rs b/src/youtube_dl.rs
index d588760..a917c54 100644
--- a/src/youtube_dl.rs
+++ b/src/youtube_dl.rs
@@ -2,17 +2,22 @@ use std::process::{Command, Stdio};
use tokio_process::CommandExt;
use futures::compat::Future01CompatExt;
+use serde::{Serialize, Deserialize};
+
use log::debug;
-pub async fn get_audio_download_url(uri: String) -> Result<(String, String), String> {
+#[derive(Serialize, Deserialize, Clone, Debug)]
+pub struct AudioMetadata {
+ pub url: String,
+ pub title: Option<String>,
+}
+
+pub async fn get_audio_download_url(uri: String) -> Result<AudioMetadata, String> {
let ytdl_args = [
"--no-playlist",
"-f",
"bestaudio/best",
- "-g",
- "--get-filename",
- "-o",
- "%(title)s",
+ "-j",
&uri,
];
@@ -24,15 +29,12 @@ pub async fn get_audio_download_url(uri: String) -> Result<(String, String), Str
let ytdl_output = cmd.output_async().compat().await.unwrap();
- let output = String::from_utf8(ytdl_output.stdout.clone()).unwrap();
-
if ytdl_output.status.success() == false {
return Err(String::from_utf8(ytdl_output.stderr.clone()).unwrap());
}
- let lines = output.lines().collect::<Vec<_>>();
- let url = lines[0].to_owned();
- let title = lines[1].to_owned();
+ let output_str = String::from_utf8(ytdl_output.stdout.clone()).unwrap();
+ let output = serde_json::from_str(&output_str).map_err(|e| e.to_string())?;
- Ok((url, title))
+ Ok(output)
}