From dce4df7893dae3eb899ee83b922bee273603b4af Mon Sep 17 00:00:00 2001 From: hodasemi Date: Fri, 14 Sep 2018 14:08:44 +0200 Subject: [PATCH] Add mutex to data access --- Cargo.lock | 6 +-- src/player.rs | 119 ++++++++++++++++++++++++++++--------------------- src/youtube.rs | 10 ++++- 3 files changed, 80 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b603413..029a0c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -339,12 +339,12 @@ dependencies = [ "foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", - "openssl-sys 0.9.35 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "openssl-sys" -version = "0.9.35" +version = "0.9.36" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", @@ -802,7 +802,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe" "checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30" "checksum openssl 0.9.24 (registry+https://github.com/rust-lang/crates.io-index)" = "a3605c298474a3aa69de92d21139fb5e2a81688d308262359d85cdd0d12a7985" -"checksum openssl-sys 0.9.35 (registry+https://github.com/rust-lang/crates.io-index)" = "912f301a749394e1025d9dcddef6106ddee9252620e6d0a0e5f8d0681de9b129" +"checksum openssl-sys 0.9.36 (registry+https://github.com/rust-lang/crates.io-index)" = "409d77eeb492a1aebd6eb322b2ee72ff7c7496b4434d98b3bf8be038755de65e" "checksum opus 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e9059a7daf1e6665eb88c4a95ca9ff393a6d276fd66e9d85191280d7e5ec18b" "checksum opus-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fad8b294f482f7972fa466b1c64d5a564e4ee6975599d80483ee4fa83f25b6ec" "checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37" diff --git a/src/player.rs b/src/player.rs index 65985f5..603fd3b 100644 --- a/src/player.rs +++ b/src/player.rs @@ -1,7 +1,5 @@ use parking_lot; -use youtube::convert_file_name; - use serenity; use serenity::client::CACHE; use serenity::model::id::{ChannelId, GuildId}; @@ -29,9 +27,9 @@ pub struct Song { } pub struct MediaData { - playlist: RefCell>, + playlist: Mutex>>, current_song: Mutex>>, - watcher_thread: RefCell>>, + watcher_thread: Mutex>>>, } fn guild_id(channel_id: ChannelId) -> Option { @@ -59,8 +57,13 @@ impl MediaData { self.current_song.lock().unwrap() } + fn playlist_mut(&self) -> MutexGuard>> { + self.playlist.lock().unwrap() + } + fn reset_thread(&self) { - *self.watcher_thread.borrow_mut() = None; + let thread_mutex = self.watcher_thread.lock().unwrap(); + *thread_mutex.borrow_mut() = None; } fn start_thread( @@ -73,7 +76,8 @@ impl MediaData { let media_clone = media.clone(); let manager_clone = manager_lock.clone(); - let mut watcher_mut = media.watcher_thread.borrow_mut(); + let thread_mutex = media.watcher_thread.lock().unwrap(); + let mut watcher_mut = thread_mutex.borrow_mut(); if watcher_mut.is_none() { *watcher_mut = Some(thread::spawn(move || loop { @@ -86,9 +90,11 @@ impl MediaData { let audio = song_lock.lock(); if audio.finished { + let playlist = media_clone.playlist_mut(); + if !Self::next_song( song, - media_clone.playlist.borrow_mut().deref_mut(), + playlist.borrow_mut().deref_mut(), channel_id, &manager_clone, ) { @@ -107,40 +113,42 @@ impl MediaData { continue; } - let mut playlist = media_clone.playlist.borrow_mut(); + { + let playlist_mutex = media_clone.playlist_mut(); + let mut playlist = playlist_mutex.borrow_mut(); - if !playlist.is_empty() { - let mut manager = manager_clone.lock(); + if !playlist.is_empty() { + let mut manager = manager_clone.lock(); - if let Some(handler) = - handler(check_option!(guild_id(channel_id)), &mut manager) - { - let first = playlist.remove(0); + if let Some(handler) = + handler(check_option!(guild_id(channel_id)), &mut manager) + { + let first = playlist.remove(0); - *borrow = Some(handler.play_returning(first.source)); + *borrow = Some(handler.play_returning(first.source)); - super::check_msg(channel_id.say(format!( - "Playing song: {}", - super::youtube::convert_file_name(first.name) - ))); + super::check_msg( + channel_id.say(format!("Playing song: {}", first.name)), + ); + } else { + return; + } } else { + manager_clone + .lock() + .remove(check_option!(guild_id(channel_id))); + + media_clone.reset_thread(); + + println!("left channel"); + return; } - } else { - manager_clone - .lock() - .remove(check_option!(guild_id(channel_id))); - - media_clone.reset_thread(); - - println!("left channel"); - - return; } } - let five_sec = time::Duration::from_secs(5); - thread::sleep(five_sec); + let two_sec = time::Duration::from_secs(2); + thread::sleep(two_sec); })); } } @@ -168,10 +176,7 @@ impl MediaData { *song = handler.play_returning(first.source); - super::check_msg(channel_id.say(format!( - "Playing song: {}", - super::youtube::convert_file_name(first.name) - ))); + super::check_msg(channel_id.say(format!("Playing song: {}", first.name))); return true; } @@ -184,9 +189,9 @@ impl MediaData { impl Default for MediaData { fn default() -> MediaData { MediaData { - playlist: RefCell::new(Vec::new()), + playlist: Mutex::new(RefCell::new(Vec::new())), current_song: Mutex::new(RefCell::new(None)), - watcher_thread: RefCell::new(None), + watcher_thread: Mutex::new(RefCell::new(None)), } } } @@ -284,15 +289,22 @@ impl serenity::framework::standard::Command for Play { Err(why) => { println!("Err starting source: {:?}", why); - super::check_msg(msg.channel_id.say("Error sourcing ffmpeg")); + super::check_msg( + msg.channel_id + .say(format!("Error using youtube-dl: {}", why)), + ); return Ok(()); } }; - self.media.playlist.borrow_mut().append(&mut source); + { + let playlist_mutex = self.media.playlist_mut(); + playlist_mutex.borrow_mut().append(&mut source); + } - let mut manager_lock = ctx.data + let mut manager_lock = ctx + .data .lock() .get::() .cloned() @@ -357,16 +369,19 @@ impl serenity::framework::standard::Command for List { ) -> ::std::result::Result<(), serenity::framework::standard::CommandError> { let mut output = String::new(); - let playlist = self.media.playlist.borrow(); + { + let playlist_mutex = self.media.playlist_mut(); + let playlist = playlist_mutex.borrow(); - output += &format!( - "{} {} queued\n", - playlist.len(), - if playlist.len() == 1 { "song" } else { "songs" } - ); + output += &format!( + "{} {} queued\n", + playlist.len(), + if playlist.len() == 1 { "song" } else { "songs" } + ); - for (i, song) in playlist.iter().enumerate() { - output += &format!("\t{}.\t{}\n", i + 1, convert_file_name(song.name.clone())); + for (i, song) in playlist.iter().enumerate() { + output += &format!("\t{}.\t{}\n", i + 1, song.name.clone()); + } } super::check_msg(msg.channel_id.say(output)); @@ -429,7 +444,10 @@ impl serenity::framework::standard::Command for Stop { msg: &serenity::model::channel::Message, _: serenity::framework::standard::Args, ) -> ::std::result::Result<(), serenity::framework::standard::CommandError> { - self.media.playlist.borrow_mut().clear(); + { + let playlist = self.media.playlist_mut(); + playlist.borrow_mut().clear(); + } { let song = self.media.song_mut(); @@ -437,7 +455,8 @@ impl serenity::framework::standard::Command for Stop { } { - let mut manager_lock = ctx.data + let mut manager_lock = ctx + .data .lock() .get::() .cloned() diff --git a/src/youtube.rs b/src/youtube.rs index d8002c8..46fba46 100644 --- a/src/youtube.rs +++ b/src/youtube.rs @@ -51,9 +51,15 @@ fn convert_output(out: &Output) -> Result, String> { 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(files) + Ok(mp3s) } Err(_) => Err("error converting output".to_string()), @@ -61,7 +67,7 @@ fn convert_output(out: &Output) -> Result, String> { } pub fn youtube_dl(uri: &str) -> Result, String> { - let args = ["-f", "webm[abr>0]/bestaudio/best", uri]; + let args = ["-x", "--audio-format", "mp3", "--audio-quality", "5", uri]; let out = match Command::new("youtube-dl") .args(&args)