Skip to content

Commit

Permalink
Merge pull request #15 from tarkah/feature/player-customization
Browse files Browse the repository at this point in the history
Add customization features to native & web players
  • Loading branch information
tarkah authored Jan 28, 2020
2 parents 6b5d535 + 1aed352 commit 241f947
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 38 deletions.
13 changes: 13 additions & 0 deletions embed/config/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,16 @@
# Default format is: "[*] - [Artist] - [Title]"
#
#song_format: "[*] - [Artist] - [Title]"

# Settings to customize look of the player
#
#player:

# Set lyrics to fit entire screen
#fullscreen: false

# Scale lyrics by this factor, default is 1.5
#scale: 1.5

# Disables the rainbow background. Will be black instead.
#disable_background: false
14 changes: 10 additions & 4 deletions frontend/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,15 @@ impl Model {
}

fn view_page(&self) -> Html {
let port_ws = if let Some(config) = &self.config {
config.port_ws
let (port_ws, fullscreen, scale, disable_background) = if let Some(config) = &self.config {
(
config.port_ws,
config.player.fullscreen,
config.player.scale,
config.player.disable_background,
)
} else {
9000
(9000, false, 1.5, false)
};

html! {
Expand All @@ -147,7 +152,8 @@ impl Model {
AppRoute::Artist(id) => html!{<ArtistPage artist_id=id />},
AppRoute::Artists => html!{<ArtistsPage />},
AppRoute::Queue => html!{<QueuePage />},
AppRoute::Player => html!{<PlayerPage port_ws=port_ws />},
AppRoute::Player => html!{<PlayerPage port_ws=port_ws fullscreen=fullscreen
scale=scale disable_background=disable_background/>},
AppRoute::NotFound(Permissive(None)) => html!{"Page not found"},
AppRoute::NotFound(Permissive(Some(missed_route))) => html!{format!("Page '{}' not found", missed_route)},
_ => html!{"Page not found"},
Expand Down
10 changes: 9 additions & 1 deletion frontend/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ pub enum SortDirection {
Desc,
}

#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct Config {
pub song_path: PathBuf,
pub data_path: PathBuf,
Expand All @@ -114,4 +114,12 @@ pub struct Config {
pub port: u16,
pub port_ws: u16,
pub song_format: String,
pub player: PlayerConfig,
}

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct PlayerConfig {
pub fullscreen: bool,
pub scale: f32,
pub disable_background: bool,
}
70 changes: 52 additions & 18 deletions frontend/src/pages/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,22 @@ pub enum Msg {
pub struct Props {
#[props(required)]
pub port_ws: u16,
#[props(required)]
pub fullscreen: bool,
#[props(required)]
pub scale: f32,
#[props(required)]
pub disable_background: bool,
}

pub struct PlayerPage {
link: ComponentLink<Self>,
#[allow(dead_code)]
player_agent: Box<dyn Bridge<player::PlayerAgent>>,
port_ws: u16,
fullscreen: bool,
scale: f32,
disable_background: bool,
window: Window,
player_canvas: Option<HtmlCanvasElement>,
hidden_canvas: Option<HtmlCanvasElement>,
Expand Down Expand Up @@ -59,6 +68,9 @@ impl Component for PlayerPage {
window,
player_agent,
port_ws: props.port_ws,
fullscreen: props.fullscreen,
scale: props.scale,
disable_background: props.disable_background,
player_canvas: None,
hidden_canvas: None,
player_render_context: None,
Expand Down Expand Up @@ -194,36 +206,58 @@ impl PlayerPage {
}

fn render_frame(&mut self, image_data: ImageData, background: (f32, f32, f32, f32)) {
let x = if self.fullscreen {
0.0
} else {
self.width as f64 / 2.0 - (300.0 * self.scale as f64) / 2.0
};
let y = if self.fullscreen {
0.0
} else {
self.height as f64 / 2.0 - (216.0 * self.scale as f64) / 2.0
};
let width = if self.fullscreen {
self.width as f64
} else {
300.0 * self.scale as f64
};
let height = if self.fullscreen {
self.height as f64
} else {
216.0 * self.scale as f64
};

let player_render_context = self.player_render_context.as_ref().unwrap();
let hidden_render_context = self.hidden_render_context.as_ref().unwrap();
let hidden_canvas = self.hidden_canvas.as_ref().unwrap();

let _ = hidden_render_context.put_image_data(&image_data, 0.0, 0.0);

let color: JsString = format!(
"rgba({}, {}, {}, {})",
background.0, background.1, background.2, background.3
)
.as_str()
.into();
player_render_context.set_fill_style(&color);
player_render_context.fill_rect(0.0, 0.0, self.width as f64, self.height as f64);
if !self.fullscreen {
let color = if self.disable_background {
format!("rgba({}, {}, {}, {})", 0, 0, 0, 1)
} else {
format!(
"rgba({}, {}, {}, {})",
background.0, background.1, background.2, background.3
)
};

let color: JsString = color.as_str().into();
player_render_context.set_fill_style(&color);
player_render_context.fill_rect(0.0, 0.0, self.width as f64, self.height as f64);
}

let color: JsString = format!("rgba({}, {}, {}, {})", 0, 0, 0, 1).as_str().into();
player_render_context.set_fill_style(&color);
player_render_context.fill_rect(
self.width as f64 / 2.0 - (300.0 * 1.5) / 2.0,
self.height as f64 / 2.0 - (216.0 * 1.5) / 2.0,
300.0 * 1.5,
216.0 * 1.5,
);
player_render_context.fill_rect(x, y, width, height);

let _ = player_render_context.draw_image_with_html_canvas_element_and_dw_and_dh(
&hidden_canvas,
self.width as f64 / 2.0 - (300.0 * 1.5) / 2.0,
self.height as f64 / 2.0 - (216.0 * 1.5) / 2.0,
300.0 * 1.5,
216.0 * 1.5,
x,
y,
width,
height,
);
}

Expand Down
21 changes: 20 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ lazy_static! {
};
}

#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct Config {
pub song_path: PathBuf,
pub data_path: PathBuf,
Expand All @@ -45,6 +45,7 @@ pub struct Config {
pub port: u16,
pub port_ws: u16,
pub song_format: String,
pub player: PlayerConfig,
}

impl Default for Config {
Expand All @@ -57,6 +58,24 @@ impl Default for Config {
port: 8080,
port_ws: 9000,
song_format: "[*] - [Artist] - [Title]".to_owned(),
player: PlayerConfig::default(),
}
}
}

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
pub struct PlayerConfig {
pub fullscreen: bool,
pub scale: f32,
pub disable_background: bool,
}

impl Default for PlayerConfig {
fn default() -> PlayerConfig {
PlayerConfig {
fullscreen: false,
scale: 1.5,
disable_background: false,
}
}
}
Expand Down
53 changes: 39 additions & 14 deletions src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use karaoke::{
collection::Kfile,
embed::Assets,
queue::PLAY_QUEUE,
CONFIG,
};
use rodio::{Sink, Source};
use std::{
Expand Down Expand Up @@ -192,14 +193,32 @@ impl Player {
let cdg = File::open(&kfile.cdg_path)?;
let mut scsi = cdg::SubchannelStreamIter::new(BufReader::new(cdg));

//Size of cdg render texture, scaled at 1.5x
//Size of cdg render texture, scaled at 1.5x (default)
let cdg_x: f32 = 300.0;
let cdg_y: f32 = 216.0;
let cdg_scale = 1.5;
let cdg_scale = CONFIG.player.scale;
let cdg_width = if CONFIG.player.fullscreen {
self.dimensions.width as f32
} else {
cdg_x * cdg_scale
};
let cdg_height = if CONFIG.player.fullscreen {
self.dimensions.height as f32
} else {
cdg_y * cdg_scale
};

//Calculate center cdg image
let cdg_x_center = self.dimensions.width as f32 * 0.5 - (cdg_x * cdg_scale) * 0.5;
let cdg_y_center = self.dimensions.height as f32 * 0.5 - (cdg_y * cdg_scale) * 0.5;
let cdg_x_center = if CONFIG.player.fullscreen {
0.0
} else {
self.dimensions.width as f32 * 0.5 - cdg_width * 0.5
};
let cdg_y_center = if CONFIG.player.fullscreen {
0.0
} else {
self.dimensions.height as f32 * 0.5 - cdg_height * 0.5
};

//Counter and frequency for rainbow effect
let mut i: f32 = 0.0;
Expand Down Expand Up @@ -261,14 +280,20 @@ impl Player {
if sectors_since > 0 {
let mut frame = self.display.draw();

//Get background color from rainbow cycle, clear to window
let background_data = rainbow_cycle(&mut i, size);
frame.clear_color(
background_data.0,
background_data.1,
background_data.2,
background_data.3,
);
if !CONFIG.player.fullscreen {
//Get background color from rainbow cycle, clear to window
let background_data = if CONFIG.player.disable_background {
(0.0, 0.0, 0.0, 1.0)
} else {
rainbow_cycle(&mut i, size)
};
frame.clear_color(
background_data.0,
background_data.1,
background_data.2,
background_data.3,
);
}

//Get updated cdg frame from interpreter, copy into RGBA image,
//update to texture, blit texture to frame surface with rectangle dimensions
Expand All @@ -281,8 +306,8 @@ impl Player {
let cdg_rect = glium::BlitTarget {
left: cdg_x_center as u32,
bottom: cdg_y_center as u32,
width: (cdg_x * cdg_scale) as i32,
height: (cdg_y * cdg_scale) as i32,
width: cdg_width as i32,
height: cdg_height as i32,
};
cdg_image.as_surface().blit_whole_color_to(
&frame,
Expand Down

0 comments on commit 241f947

Please sign in to comment.