Skip to content

Commit 3273f76

Browse files
committed
feat: album art almost
1 parent 4457c39 commit 3273f76

4 files changed

Lines changed: 79 additions & 17 deletions

File tree

player/src/gui.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ pub struct MainWindow {
3434
pub visualizer: Visualizer,
3535
pub bitrate_bar: BitrateBar,
3636
pub volume_slider: HorSlider,
37+
pub art_frame: Frame,
3738
}
3839
impl MainWindow {
3940
pub fn make_window(s: Sender<UIEvent>) -> Self {
@@ -138,9 +139,9 @@ impl MainWindow {
138139
display.set_align(Align::ImageBackdrop);
139140
display.set_color(Color::Blue);
140141

141-
/* let mut art_frame = Frame::new(228, 34, 31, 31, "");
142+
let mut art_frame = Frame::new(228, 34, 31, 31, "");
142143
art_frame.set_frame(FrameType::DownBox);
143-
display.add(&art_frame); */
144+
display.add(&art_frame);
144145

145146
let mut lbl_title = Frame::new(105, 35, 150, 16, "nothing playing");
146147
lbl_title.set_align(Align::Left | Align::Inside);
@@ -202,7 +203,8 @@ impl MainWindow {
202203
lbl_data1,
203204
visualizer,
204205
bitrate_bar,
205-
volume_slider
206+
volume_slider,
207+
art_frame,
206208
}
207209
}
208210

player/src/main.rs

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
use aes_gcm_siv::Aes256GcmSiv;
22
use fltk::app;
3+
use fltk::image::JpegImage;
4+
use fltk::prelude::{BrowserExt, ImageExt, ValuatorExt, WidgetBase, WidgetExt, WindowExt};
35
use fltk::window::DoubleWindow;
46
use futures::StreamExt;
57
use protocol::network::FrameStream;
6-
use protocol::{AudioData, AuthenticateRequest, GetInfo, Message, Track};
8+
use protocol::{AudioData, AuthenticateRequest, GetInfo, Message, Track, TrackArt};
79
use std::collections::{HashMap, VecDeque};
810
use std::error::Error;
911
use std::path::PathBuf;
1012
use tokio::sync::mpsc::UnboundedSender;
11-
1213
use tokio::time::timeout;
1314
use tokio::{net::TcpStream, sync::mpsc};
1415

@@ -19,7 +20,6 @@ mod transmit;
1920
use transmit::{AudioInfoReader, TransmitCommand, TransmitThread, TransmitThreadHandle};
2021

2122
mod gui;
22-
use fltk::prelude::{BrowserExt, ValuatorExt, WidgetBase, WidgetExt, WindowExt};
2323

2424
struct Connection {
2525
stream: FrameStream,
@@ -633,8 +633,8 @@ async fn main() -> std::io::Result<()> {
633633
.unwrap_or(&"[no title]".to_string())
634634
);
635635
queue_gui.queue_browser.add(&line);
636-
// also update display
637636

637+
// also update display
638638
gui.lbl_title.set_label(
639639
track
640640
.metadata
@@ -648,7 +648,42 @@ async fn main() -> std::io::Result<()> {
648648
.artist
649649
.as_ref()
650650
.unwrap_or(&"[unknown artist]".to_string()),
651-
)
651+
);
652+
653+
if let Some(art) = track.metadata.art {
654+
if let Err(err) = match art {
655+
TrackArt::Png(data) => fltk::image::PngImage::from_data(
656+
&data,
657+
)
658+
.and_then(|mut img| {
659+
img.scale(29, 29, false, true);
660+
661+
// uhh just make this be the same as jpeg once u fix the other thing
662+
// or refactor it properly to not be duplicated
663+
// its just annoying to change both just test with one type at a time
664+
// gui.art_frame.draw(|| {
665+
// img.draw(
666+
// gui.art_frame.x(),
667+
// gui.art_frame.y(),
668+
// 29,
669+
// 29,
670+
// );
671+
// });
672+
673+
Ok(())
674+
}),
675+
TrackArt::Jpeg(data) => JpegImage::from_data(&data)
676+
.and_then(|mut img| {
677+
img.scale(29, 29, false, true);
678+
gui.art_frame.draw(move |f| {
679+
img.draw(f.x() + 2, f.y() + 1, 29, 29);
680+
});
681+
Ok(())
682+
}),
683+
} {
684+
eprintln!("failed to load image: {:?}", err);
685+
}
686+
}
652687
}
653688
for track in queue {
654689
let line = format!(

player/src/transmit.rs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use symphonia::core::meta::{MetadataOptions, StandardTagKey};
1212
use symphonia::core::probe::{Hint, ProbeResult};
1313
use tokio::time::Interval;
1414

15-
use protocol::{AudioData, Message};
15+
use protocol::{AudioData, Message, TrackArt};
1616
use protocol::{AudioFrame, TrackMetadata};
1717

1818
pub struct AudioInfoReader {
@@ -84,24 +84,32 @@ impl AudioInfoReader {
8484

8585
// read track metadata
8686
let mut track_md = TrackMetadata::default();
87-
8887
track_md.duration = (duration as f64 / spec.rate as f64) as usize;
8988

90-
let mut md = self.probe_result.format.metadata();
91-
if let Some(current) = md.skip_to_latest() {
92-
let tags = current.tags();
93-
Self::fill_metadata(&mut track_md, tags);
89+
let mut format_md = self.probe_result.format.metadata();
90+
if let Some(rev) = format_md.skip_to_latest() {
91+
let tags = rev.tags();
92+
let visuals = rev.visuals();
93+
94+
Self::fill_metadata(&mut track_md, tags, visuals);
9495
} else if let Some(mut md) = self.probe_result.metadata.get() {
95-
let tags = md.skip_to_latest().unwrap().tags();
96-
Self::fill_metadata(&mut track_md, tags);
96+
let rev = md.skip_to_latest().unwrap();
97+
let tags = rev.tags();
98+
let visuals = rev.visuals();
99+
100+
Self::fill_metadata(&mut track_md, tags, visuals);
97101
} else {
98102
println!("really no metadata to speak of...");
99103
}
100104

101105
Ok((spec.rate, spec.channels.count(), track_md))
102106
}
103107

104-
fn fill_metadata(md: &mut TrackMetadata, tags: &[symphonia::core::meta::Tag]) {
108+
fn fill_metadata(
109+
md: &mut TrackMetadata,
110+
tags: &[symphonia::core::meta::Tag],
111+
visuals: &[symphonia::core::meta::Visual],
112+
) {
105113
for tag in tags {
106114
match tag.std_key {
107115
Some(StandardTagKey::TrackTitle) => {
@@ -123,6 +131,16 @@ impl AudioInfoReader {
123131
_ => {}
124132
}
125133
}
134+
135+
// just assume there's only one visual in the file?
136+
if let Some(v) = visuals.first() {
137+
match v.media_type.as_str() {
138+
"image/png" => md.art = Some(TrackArt::Png(v.data.clone().into())),
139+
"image/jpeg" => md.art = Some(TrackArt::Jpeg(v.data.clone().into())),
140+
141+
_ => println!("unhandled media_type for visual: {}", v.media_type),
142+
}
143+
}
126144
}
127145
}
128146

protocol/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ pub struct Track {
3030
pub metadata: TrackMetadata,
3131
}
3232

33+
#[derive(Serialize, Deserialize, Clone, Debug)]
34+
pub enum TrackArt {
35+
Png(Vec<u8>),
36+
Jpeg(Vec<u8>),
37+
}
38+
3339
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
3440
pub struct TrackMetadata {
3541
pub duration: usize,
@@ -38,6 +44,7 @@ pub struct TrackMetadata {
3844
pub artist: Option<String>,
3945
pub album: Option<String>,
4046
pub album_artist: Option<String>,
47+
pub art: Option<TrackArt>,
4148
}
4249

4350
#[derive(Serialize, Deserialize, Clone, Debug)]

0 commit comments

Comments
 (0)