mirror of
https://github.com/talwat/lowfi
synced 2025-03-20 12:02:20 +00:00
feat: add buffer size option
This commit is contained in:
parent
968c1ee670
commit
34577efe8f
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -1453,7 +1453,7 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "lowfi"
|
||||
version = "1.6.3-dev"
|
||||
version = "1.6.4-dev"
|
||||
dependencies = [
|
||||
"Inflector",
|
||||
"arc-swap",
|
||||
|
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "lowfi"
|
||||
version = "1.6.3-dev"
|
||||
version = "1.6.4-dev"
|
||||
edition = "2021"
|
||||
description = "An extremely simple lofi player."
|
||||
license = "MIT"
|
||||
|
10
src/main.rs
10
src/main.rs
@ -12,7 +12,7 @@ mod tracks;
|
||||
mod scrape;
|
||||
|
||||
/// An extremely simple lofi player.
|
||||
#[derive(Parser)]
|
||||
#[derive(Parser, Clone)]
|
||||
#[command(about, version)]
|
||||
#[allow(
|
||||
clippy::struct_excessive_bools,
|
||||
@ -45,7 +45,11 @@ struct Args {
|
||||
|
||||
/// Use a custom track list
|
||||
#[clap(long, short, alias = "list", short_alias = 'l')]
|
||||
tracklist: Option<String>,
|
||||
track_list: Option<String>,
|
||||
|
||||
/// Song buffer size.
|
||||
#[clap(long, short = 's', alias = "buffer", default_value_t = 5)]
|
||||
buffer_size: usize,
|
||||
|
||||
/// The command that was ran.
|
||||
/// This is [None] if no command was specified.
|
||||
@ -54,7 +58,7 @@ struct Args {
|
||||
}
|
||||
|
||||
/// Defines all of the extra commands lowfi can run.
|
||||
#[derive(Subcommand)]
|
||||
#[derive(Subcommand, Clone)]
|
||||
enum Commands {
|
||||
/// Scrapes the lofi girl website file server for files.
|
||||
Scrape {
|
||||
|
@ -102,13 +102,13 @@ pub async fn play(args: Args) -> eyre::Result<()> {
|
||||
|
||||
// Initialize the UI, as well as the internal communication channel.
|
||||
let (tx, rx) = mpsc::channel(8);
|
||||
let ui = task::spawn(ui::start(Arc::clone(&player), tx.clone(), args));
|
||||
let ui = task::spawn(ui::start(Arc::clone(&player), tx.clone(), args.clone()));
|
||||
|
||||
// Sends the player an "init" signal telling it to start playing a song straight away.
|
||||
tx.send(Messages::Init).await?;
|
||||
|
||||
// Actually starts the player.
|
||||
Player::play(Arc::clone(&player), tx.clone(), rx).await?;
|
||||
Player::play(Arc::clone(&player), tx.clone(), rx, args.buffer_size).await?;
|
||||
|
||||
// Save the volume.txt file for the next session.
|
||||
PersistentVolume::save(player.sink.volume()).await?;
|
||||
|
@ -71,9 +71,6 @@ pub enum Messages {
|
||||
/// The time to wait in between errors.
|
||||
const TIMEOUT: Duration = Duration::from_secs(3);
|
||||
|
||||
/// The amount of songs to buffer up.
|
||||
const BUFFER_SIZE: usize = 5;
|
||||
|
||||
/// Main struct responsible for queuing up & playing tracks.
|
||||
// TODO: Consider refactoring [Player] from being stored in an [Arc], into containing many smaller [Arc]s.
|
||||
// TODO: In other words, this would change the type from `Arc<Player>` to just `Player`.
|
||||
@ -178,7 +175,7 @@ impl Player {
|
||||
let volume = PersistentVolume::load().await?;
|
||||
|
||||
// Load the track list.
|
||||
let list = List::load(args.tracklist.as_ref()).await?;
|
||||
let list = List::load(args.track_list.as_ref()).await?;
|
||||
|
||||
// We should only shut up alsa forcefully on Linux if we really have to.
|
||||
#[cfg(target_os = "linux")]
|
||||
@ -207,7 +204,7 @@ impl Player {
|
||||
.build()?;
|
||||
|
||||
let player = Self {
|
||||
tracks: RwLock::new(VecDeque::with_capacity(5)),
|
||||
tracks: RwLock::new(VecDeque::with_capacity(args.buffer_size)),
|
||||
current: ArcSwapOption::new(None),
|
||||
client,
|
||||
sink,
|
||||
@ -294,10 +291,12 @@ impl Player {
|
||||
/// skip tracks or pause.
|
||||
///
|
||||
/// This will also initialize a [Downloader] as well as an MPRIS server if enabled.
|
||||
/// The [Downloader]s internal buffer size is determined by `buf_size`.
|
||||
pub async fn play(
|
||||
player: Arc<Self>,
|
||||
tx: Sender<Messages>,
|
||||
mut rx: Receiver<Messages>,
|
||||
buf_size: usize,
|
||||
) -> eyre::Result<()> {
|
||||
// Initialize the mpris player.
|
||||
//
|
||||
@ -313,7 +312,7 @@ impl Player {
|
||||
})?;
|
||||
|
||||
// `itx` is used to notify the `Downloader` when it needs to download new tracks.
|
||||
let downloader = Downloader::new(Arc::clone(&player));
|
||||
let downloader = Downloader::new(Arc::clone(&player), buf_size);
|
||||
let (itx, downloader) = downloader.start();
|
||||
|
||||
// Start buffering tracks immediately.
|
||||
|
@ -8,7 +8,7 @@ use tokio::{
|
||||
time::sleep,
|
||||
};
|
||||
|
||||
use super::{Player, BUFFER_SIZE, TIMEOUT};
|
||||
use super::{Player, TIMEOUT};
|
||||
|
||||
/// This struct is responsible for downloading tracks in the background.
|
||||
///
|
||||
@ -24,6 +24,9 @@ pub struct Downloader {
|
||||
/// A copy of the internal sender, which can be useful for keeping
|
||||
/// track of it.
|
||||
tx: Sender<()>,
|
||||
|
||||
/// The size of the internal download buffer.
|
||||
buf_size: usize,
|
||||
}
|
||||
|
||||
impl Downloader {
|
||||
@ -37,9 +40,14 @@ impl Downloader {
|
||||
///
|
||||
/// This also sends a [`Sender`] which can be used to notify
|
||||
/// when the downloader needs to begin downloading more tracks.
|
||||
pub fn new(player: Arc<Player>) -> Self {
|
||||
pub fn new(player: Arc<Player>, buf_size: usize) -> Self {
|
||||
let (tx, rx) = mpsc::channel(8);
|
||||
Self { player, rx, tx }
|
||||
Self {
|
||||
player,
|
||||
rx,
|
||||
tx,
|
||||
buf_size,
|
||||
}
|
||||
}
|
||||
|
||||
/// Actually starts & consumes the [Downloader].
|
||||
@ -50,7 +58,7 @@ impl Downloader {
|
||||
// Loop through each update notification.
|
||||
while self.rx.recv().await == Some(()) {
|
||||
// For each update notification, we'll push tracks until the buffer is completely full.
|
||||
while self.player.tracks.read().await.len() < BUFFER_SIZE {
|
||||
while self.player.tracks.read().await.len() < self.buf_size {
|
||||
let data = self.player.list.random(&self.player.client).await;
|
||||
match data {
|
||||
Ok(track) => self.player.tracks.write().await.push_back(track),
|
||||
|
Loading…
x
Reference in New Issue
Block a user