Impl reading binary data for albumart

This commit is contained in:
Stephen Seo 2021-09-16 11:44:36 +09:00
parent 8338902d50
commit 410b854574

View file

@ -1,4 +1,4 @@
use std::io::{Read, Write}; use std::io::{BufReader, Read, Write};
use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream}; use std::net::{IpAddr, Ipv4Addr, SocketAddr, TcpStream};
use std::str::FromStr; use std::str::FromStr;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
@ -18,6 +18,7 @@ struct Opt {
struct Shared { struct Shared {
art_data: Vec<u8>, art_data: Vec<u8>,
art_data_size: usize,
current_song: String, current_song: String,
current_song_length: f64, current_song_length: f64,
current_song_position: f64, current_song_position: f64,
@ -31,6 +32,7 @@ impl Shared {
fn new(stream: TcpStream) -> Self { fn new(stream: TcpStream) -> Self {
Self { Self {
art_data: Vec::new(), art_data: Vec::new(),
art_data_size: 0,
current_song: String::new(), current_song: String::new(),
current_song_length: 0.0, current_song_length: 0.0,
current_song_position: 0.0, current_song_position: 0.0,
@ -188,7 +190,8 @@ fn info_loop(shared_data: Arc<Mutex<Shared>>) -> Result<(), String> {
let mut song_title_get_time: Instant = Instant::now() - Duration::from_secs(10); let mut song_title_get_time: Instant = Instant::now() - Duration::from_secs(10);
let mut song_pos_get_time: Instant = Instant::now() - Duration::from_secs(10); let mut song_pos_get_time: Instant = Instant::now() - Duration::from_secs(10);
let mut song_length_get_time: Instant = Instant::now() - Duration::from_secs(10); let mut song_length_get_time: Instant = Instant::now() - Duration::from_secs(10);
loop { let mut current_binary_size: usize = 0;
'main: loop {
if !shared_data if !shared_data
.lock() .lock()
.map_err(|_| String::from("Failed to get shared_data.thread_running"))? .map_err(|_| String::from("Failed to get shared_data.thread_running"))?
@ -205,8 +208,26 @@ fn info_loop(shared_data: Arc<Mutex<Shared>>) -> Result<(), String> {
if let Ok(count) = read_result { if let Ok(count) = read_result {
let mut read_vec: Vec<u8> = Vec::from(buf); let mut read_vec: Vec<u8> = Vec::from(buf);
read_vec.resize(count, 0); read_vec.resize(count, 0);
loop { 'outer: loop {
let count = read_vec.len(); let mut count = read_vec.len();
if current_binary_size > 0 {
if current_binary_size <= count {
lock.art_data
.extend_from_slice(&read_vec[0..current_binary_size]);
read_vec = read_vec.split_off(current_binary_size + 1);
count = read_vec.len();
current_binary_size = 0;
println!(
"art_data len is {} after fully reading",
lock.art_data.len()
);
} else {
lock.art_data.extend_from_slice(&read_vec[0..count]);
current_binary_size -= count;
println!("art_data len is {}", lock.art_data.len());
continue 'main;
}
}
let read_line_result = read_line(&mut read_vec, count, &mut saved, init); let read_line_result = read_line(&mut read_vec, count, &mut saved, init);
if let Ok(mut line) = read_line_result { if let Ok(mut line) = read_line_result {
line = saved_str + &line; line = saved_str + &line;
@ -227,7 +248,13 @@ fn info_loop(shared_data: Arc<Mutex<Shared>>) -> Result<(), String> {
if line.starts_with("OK") { if line.starts_with("OK") {
break; break;
} else if line.starts_with("file: ") { } else if line.starts_with("file: ") {
lock.current_song = line.split_off(6); let song_file = line.split_off(6);
if song_file != lock.current_song {
lock.current_song = song_file;
lock.art_data.clear();
lock.art_data_size = 0;
println!("Got different song file, clearing art_data...");
}
lock.dirty = true; lock.dirty = true;
song_title_get_time = Instant::now(); song_title_get_time = Instant::now();
} else if line.starts_with("elapsed: ") { } else if line.starts_with("elapsed: ") {
@ -246,6 +273,18 @@ fn info_loop(shared_data: Arc<Mutex<Shared>>) -> Result<(), String> {
lock.dirty = true; lock.dirty = true;
song_length_get_time = Instant::now(); song_length_get_time = Instant::now();
} }
} else if line.starts_with("size: ") {
let parse_artsize_result = usize::from_str(&line.split_off(6));
if let Ok(value) = parse_artsize_result {
lock.art_data_size = value;
lock.dirty = true;
}
} else if line.starts_with("binary: ") {
let parse_artbinarysize_result =
usize::from_str(&line.split_off(8));
if let Ok(value) = parse_artbinarysize_result {
current_binary_size = value;
}
} }
} }
} else if let Err((msg, read_line_in_progress)) = read_line_result { } else if let Err((msg, read_line_in_progress)) = read_line_result {
@ -288,6 +327,17 @@ fn info_loop(shared_data: Arc<Mutex<Shared>>) -> Result<(), String> {
if let Err(e) = write_result { if let Err(e) = write_result {
println!("Got error requesting status: {}", e); println!("Got error requesting status: {}", e);
} }
} else if (lock.art_data.is_empty() || lock.art_data.len() != lock.art_data_size)
&& !lock.current_song.is_empty()
{
let title = lock.current_song.clone();
let art_data_length = lock.art_data.len();
let write_result = lock.stream.write(
format!("readpicture \"{}\" {}\n", title, art_data_length).as_bytes(),
);
if let Err(e) = write_result {
println!("Got error requesting albumart: {}", e);
}
} }
} else { } else {
println!("Failed to acquire lock for writing to stream"); println!("Failed to acquire lock for writing to stream");
@ -342,7 +392,7 @@ fn main() -> Result<(), String> {
get_info_from_shared(shared_data.clone(), false) get_info_from_shared(shared_data.clone(), false)
.expect("Should be able to get info from shared"); .expect("Should be able to get info from shared");
thread::sleep(Duration::from_secs(2)); thread::sleep(Duration::from_secs(10));
println!("Stopping thread..."); println!("Stopping thread...");
shared_data shared_data