Made some changes to error handling in the Player and other minor changes

This commit is contained in:
G2-Games 2024-01-12 22:46:33 -06:00
parent c78f77165e
commit 278f37dd6a
4 changed files with 33 additions and 21 deletions

View file

@ -33,3 +33,4 @@ quick-xml = "0.31.0"
leb128 = "0.2.5" leb128 = "0.2.5"
urlencoding = "2.1.3" urlencoding = "2.1.3"
m3u8-rs = "5.0.5" m3u8-rs = "5.0.5"
thiserror = "1.0.56"

View file

@ -6,7 +6,7 @@ use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, PartialEq, Eq)] #[derive(Serialize, Deserialize, PartialEq, Eq)]
pub struct Config { pub struct Config {
pub db_path: Box<PathBuf>, pub db_path: PathBuf,
} }
impl Default for Config { impl Default for Config {
@ -14,7 +14,7 @@ impl Default for Config {
let path = PathBuf::from("./music_database"); let path = PathBuf::from("./music_database");
Config { Config {
db_path: Box::new(path), db_path: path,
} }
} }
} }

View file

@ -1,6 +1,6 @@
// Crate things // Crate things
//use crate::music_controller::config::Config; //use crate::music_controller::config::Config;
use crate::music_storage::library::{Tag, URI}; use crate::music_storage::library::URI;
use crossbeam_channel::bounded; use crossbeam_channel::bounded;
use std::error::Error; use std::error::Error;
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard}; use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
@ -11,8 +11,9 @@ use gst::{ClockTime, Element};
use gstreamer as gst; use gstreamer as gst;
use gstreamer::prelude::*; use gstreamer::prelude::*;
// Time things // Extra things
use chrono::Duration; use chrono::Duration;
use thiserror::Error;
#[derive(Debug)] #[derive(Debug)]
pub enum PlayerCmd { pub enum PlayerCmd {
@ -59,6 +60,22 @@ impl TryInto<gst::State> for PlayerState {
type Error = Box<dyn Error>; type Error = Box<dyn Error>;
} }
#[derive(Error, Debug)]
pub enum PlayerError {
#[error("player initialization failed")]
Init(#[from] glib::Error),
#[error("element factory failed to create playbin3")]
Factory(#[from] glib::BoolError),
#[error("could not change playback state")]
StateChange(#[from] gst::StateChangeError),
#[error("failed to build gstreamer item")]
Build,
#[error("poison error")]
Poison,
#[error("general player error")]
General,
}
/// An instance of a music player with a GStreamer backend /// An instance of a music player with a GStreamer backend
pub struct Player { pub struct Player {
source: Option<URI>, source: Option<URI>,
@ -73,22 +90,16 @@ pub struct Player {
paused: Arc<RwLock<bool>>, paused: Arc<RwLock<bool>>,
} }
impl Default for Player {
fn default() -> Self {
Self::new()
}
}
impl Player { impl Player {
pub fn new() -> Self { pub fn new() -> Result<Self, PlayerError> {
// Initialize GStreamer // Initialize GStreamer, maybe figure out how to nicely fail here
gst::init().unwrap(); gst::init()?;
let ctx = glib::MainContext::default(); let ctx = glib::MainContext::default();
let _guard = ctx.acquire(); let _guard = ctx.acquire();
let mainloop = glib::MainLoop::new(Some(&ctx), false); let mainloop = glib::MainLoop::new(Some(&ctx), false);
let playbin_arc = Arc::new(RwLock::new( let playbin_arc = Arc::new(RwLock::new(
gst::ElementFactory::make("playbin3").build().unwrap(), gst::ElementFactory::make("playbin3").build()?,
)); ));
let playbin = playbin_arc.clone(); let playbin = playbin_arc.clone();
@ -99,13 +110,13 @@ impl Player {
// Set up the Playbin flags to only play audio // Set up the Playbin flags to only play audio
let flags = flags_class let flags = flags_class
.builder_with_value(flags) .builder_with_value(flags)
.unwrap() .ok_or(PlayerError::Build)?
.set_by_nick("audio") .set_by_nick("audio")
.set_by_nick("download") .set_by_nick("download")
.unset_by_nick("video") .unset_by_nick("video")
.unset_by_nick("text") .unset_by_nick("text")
.build() .build()
.unwrap(); .ok_or(PlayerError::Build)?;
playbin playbin
.write() .write()
@ -125,7 +136,7 @@ impl Player {
let start_update = Arc::clone(&start); let start_update = Arc::clone(&start);
let end_update = Arc::clone(&end); let end_update = Arc::clone(&end);
let (message_tx, message_rx) = bounded(1); //TODO: Maybe figure out a better method than making this bounded let (message_tx, message_rx) = bounded(1); //TODO: Maybe figure out a better method than making this bounded
std::thread::spawn(move || { std::thread::spawn(move || { //TODO: Figure out how to return errors nicely in threads
loop { loop {
let mut pos_temp = playbin_arc let mut pos_temp = playbin_arc
.read() .read()
@ -223,7 +234,7 @@ impl Player {
}); });
let source = None; let source = None;
Self { Ok(Self {
source, source,
playbin, playbin,
message_rx, message_rx,
@ -233,7 +244,7 @@ impl Player {
paused, paused,
position, position,
buffer, buffer,
} })
} }
pub fn source(&self) -> &Option<URI> { pub fn source(&self) -> &Option<URI> {

View file

@ -332,13 +332,13 @@ impl MusicLibrary {
match global_config.db_path.exists() { match global_config.db_path.exists() {
true => { true => {
library = read_library(*global_config.db_path.clone())?; library = read_library(global_config.db_path.clone())?;
} }
false => { false => {
// Create the database if it does not exist // Create the database if it does not exist
// possibly from the backup file // possibly from the backup file
if backup_path.exists() { if backup_path.exists() {
library = read_library(*backup_path.clone())?; library = read_library(backup_path.clone())?;
write_library(&library, global_config.db_path.to_path_buf(), false)?; write_library(&library, global_config.db_path.to_path_buf(), false)?;
} else { } else {
write_library(&library, global_config.db_path.to_path_buf(), false)?; write_library(&library, global_config.db_path.to_path_buf(), false)?;