Started wrapper
This commit is contained in:
parent
b5c9401d01
commit
96ac035bc9
61
Cargo.lock
generated
61
Cargo.lock
generated
@ -369,6 +369,30 @@ version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ffe3a660c3a1b10e96f304a9413d673b2118d62e4520f7ddf4a4faccfe8b9b9"
|
||||
|
||||
[[package]]
|
||||
name = "flume"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"nanorand",
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
@ -386,8 +410,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -550,6 +576,16 @@ dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.22"
|
||||
@ -597,6 +633,15 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "nanorand"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ndk"
|
||||
version = "0.8.0"
|
||||
@ -924,6 +969,12 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.206"
|
||||
@ -999,6 +1050,15 @@ version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.8.0"
|
||||
@ -1010,6 +1070,7 @@ name = "sweetmusic"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"file-format",
|
||||
"flume",
|
||||
"metadata",
|
||||
"rand",
|
||||
"regex",
|
||||
|
@ -5,6 +5,7 @@ edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
file-format = "0.25.0"
|
||||
flume = "0.11.0"
|
||||
metadata = "0.1.9"
|
||||
rand = "0.8.5"
|
||||
regex = "1.10.6"
|
||||
|
@ -43,6 +43,7 @@ pub mod audioplayer {
|
||||
///If true, the player will loop back to the beginning of the playlist when it's done
|
||||
pub repeating: bool,
|
||||
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------Enums
|
||||
|
125
src/audiowrapper.rs
Normal file
125
src/audiowrapper.rs
Normal file
@ -0,0 +1,125 @@
|
||||
pub mod audiowrapper {
|
||||
|
||||
use std::thread::*;
|
||||
use std::error::Error;
|
||||
use std::time::Duration;
|
||||
use std::io::BufReader;
|
||||
use std::fs::File;
|
||||
use std::any::Any;
|
||||
|
||||
use flume::{Receiver, Sender};
|
||||
use rodio::{Decoder, OutputStream, Sink, Source};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::playlist::playlist::*;
|
||||
use crate::songmeta::songmeta::*;
|
||||
|
||||
|
||||
//A wrapper around a rodio sink that allows for better controls.
|
||||
//Can't use sink queues so I implement myself...
|
||||
//Reads songs in threads, one at a time so we can stop, play, pause, insert songs in playlist, etc.
|
||||
#[derive(Debug)]
|
||||
pub struct AudioWrapper {
|
||||
tx: Sender<ThreadCom>,
|
||||
rx: Receiver<ThreadCom>,
|
||||
pub playlist: Playlist,
|
||||
handle: Option<JoinHandle<()>>,
|
||||
}
|
||||
|
||||
//Used for handling communication with the thread
|
||||
enum ThreadCom {
|
||||
Stop,
|
||||
Pause,
|
||||
Unpause,
|
||||
SendPos,
|
||||
Pos(Duration),
|
||||
SetVol(f32),
|
||||
GetVol,
|
||||
}
|
||||
|
||||
impl AudioWrapper {
|
||||
pub fn new() -> Self {
|
||||
let (tx, rx) = flume::unbounded();
|
||||
Self {
|
||||
tx: tx,
|
||||
rx: rx,
|
||||
playlist: Playlist::new(),
|
||||
handle: None,
|
||||
}
|
||||
}
|
||||
|
||||
//Inner function used in a thread to read music
|
||||
fn sub_sink(path: String, tx: Sender<ThreadCom>, rx: Receiver<ThreadCom>) {
|
||||
let path = Path::new(&path);
|
||||
let (stream, stream_handle) = OutputStream::try_default().unwrap();
|
||||
let sink = Sink::try_new(&stream_handle).unwrap();
|
||||
let file = BufReader::new(File::open(&path).unwrap());
|
||||
let source = Decoder::new(file).unwrap();
|
||||
sink.append(source);
|
||||
|
||||
loop {
|
||||
|
||||
let recv = rx.try_recv();
|
||||
|
||||
match recv {
|
||||
Ok(v) => {
|
||||
match v {
|
||||
ThreadCom::Stop => {
|
||||
sink.stop();
|
||||
break;
|
||||
},
|
||||
ThreadCom::Pause => {
|
||||
sink.pause();
|
||||
},
|
||||
ThreadCom::Unpause => {
|
||||
sink.play();
|
||||
},
|
||||
ThreadCom::SendPos => {
|
||||
tx.try_send(ThreadCom::Pos(sink.get_pos()));
|
||||
},
|
||||
ThreadCom::SetVol(w) => {
|
||||
sink.set_volume(w);
|
||||
},
|
||||
ThreadCom::GetVol => {
|
||||
tx.try_send(ThreadCom::SetVol(sink.volume()));
|
||||
},
|
||||
ThreadCom::Pos(w) => {
|
||||
let _ = sink.try_seek(w);
|
||||
}
|
||||
};
|
||||
},
|
||||
Err(_) => (),
|
||||
};
|
||||
|
||||
//Finished
|
||||
if sink.len() < 1 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///Reads ONE song by starting a sink in a new thread.
|
||||
///Stop any previous song playing.
|
||||
pub fn play_at(&mut self, index: usize){
|
||||
self.playlist.check_index(index.clone()).unwrap();
|
||||
self.stop();
|
||||
let path = self.playlist.songs[index].path.clone();
|
||||
let tx2 = self.tx.clone();
|
||||
let rx2 = self.rx.clone();
|
||||
let handle = spawn(|| {
|
||||
AudioWrapper::sub_sink(path, tx2, rx2);
|
||||
});
|
||||
self.handle = Some(handle);
|
||||
}
|
||||
|
||||
pub fn stop(&mut self) {
|
||||
match &self.handle {
|
||||
Some(h) => {
|
||||
self.tx.try_send(ThreadCom::Stop).unwrap();
|
||||
self.handle.take().expect("Called stop on non-running thread").join().expect("Could not join");
|
||||
},
|
||||
None => (),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
50
src/main.rs
50
src/main.rs
@ -7,48 +7,22 @@ use crate::playlist::playlist::*;
|
||||
pub mod audioplayer;
|
||||
use crate::audioplayer::audioplayer::*;
|
||||
|
||||
pub mod audiowrapper;
|
||||
use crate::audiowrapper::audiowrapper::*;
|
||||
|
||||
use std::thread::sleep;
|
||||
use std::time::Duration;
|
||||
|
||||
fn main() {
|
||||
let mysong = SongMeta::frompath(&String::from("/home/justine/Music/one.mp3")).unwrap();
|
||||
let mysong2 = SongMeta::frompath(&String::from("/home/justine/Music/two.mp3")).unwrap();
|
||||
let mysong3 = SongMeta::frompath(&String::from("/home/justine/Music/three.mp3")).unwrap();
|
||||
|
||||
|
||||
let mut playlist = Playlist::new();
|
||||
playlist.songs.push(mysong);
|
||||
playlist.songs.push(mysong2);
|
||||
playlist.songs.push(mysong3);
|
||||
|
||||
let mut player = AudioPlayer::new().unwrap();
|
||||
|
||||
|
||||
player.playlist = playlist;
|
||||
player.play_at(0);
|
||||
dbg!(player.get_state());
|
||||
sleep(Duration::from_secs(3));
|
||||
|
||||
dbg!("SKIPPING FORW TWICE");
|
||||
player.skip_forward();
|
||||
player.skip_forward();
|
||||
sleep(Duration::from_secs(3));
|
||||
|
||||
dbg!("BACKW 5");
|
||||
player.skip_backwards();
|
||||
player.skip_backwards();
|
||||
player.skip_backwards();
|
||||
player.skip_backwards();
|
||||
player.skip_backwards();
|
||||
|
||||
player.unpause();
|
||||
player.set_vol(0.9);
|
||||
|
||||
loop {
|
||||
println!("{:?} - {:?}", player.get_state(), player.get_vol());
|
||||
sleep(Duration::from_secs(1));
|
||||
}
|
||||
|
||||
let mut wrap = AudioWrapper::new();
|
||||
let mut pl = Playlist::new();
|
||||
pl.add_song_from_path(&String::from("/home/justine/Music/1.mp3")).unwrap();
|
||||
wrap.playlist = pl;
|
||||
wrap.play_at(0);
|
||||
sleep(Duration::from_secs(5));
|
||||
wrap.stop();
|
||||
sleep(Duration::from_secs(5));
|
||||
dbg!(wrap);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user