Started wrapper

This commit is contained in:
justine 2024-08-13 09:50:26 +02:00
parent b5c9401d01
commit 96ac035bc9
5 changed files with 200 additions and 38 deletions

61
Cargo.lock generated
View File

@ -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",

View File

@ -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"

View File

@ -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
View 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 => (),
};
}
}
}

View File

@ -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);
}