feat: load sounds from a directory and let requests specify which sound they want to use

ptr.pet f84ac379 434eefeb

verified
Changed files
+61 -15
sounds
src
+1
.gitignore
···
/target
result
···
/target
result
+
sounds
+60 -15
src/main.rs
···
use std::{
io::{BufRead, BufReader, Write},
-
net::TcpListener,
};
use quad_snd::*;
-
-
const CLICK: &[u8] = include_bytes!("./sound.ogg");
fn main() {
let ctx = AudioContext::new();
-
let click = Sound::load(&ctx, CLICK);
let port = std::env::var("PORT")
.ok()
···
let listener = TcpListener::bind(("0.0.0.0", port)).expect("cant bind");
for stream in listener.incoming() {
-
let Ok(mut stream) = stream else {
continue;
};
-
click.play(&ctx, PlaySoundParams::default());
-
// exhaust connection to not get "connection reset by peer"
-
BufReader::new(&stream)
-
.lines()
-
.flatten()
-
.take_while(|line| !line.is_empty())
-
.for_each(drop);
-
// this never "fails"
-
let response = "HTTP/1.1 200 OK\r\n\r\n";
-
let _ = stream.write_all(response.as_bytes());
}
}
···
use std::{
+
collections::HashMap,
io::{BufRead, BufReader, Write},
+
net::{TcpListener, TcpStream},
};
use quad_snd::*;
fn main() {
let ctx = AudioContext::new();
+
let sounds = std::fs::read_dir("sounds")
+
.expect("cant read sounds")
+
.flat_map(|f| {
+
let p = f.ok()?.path();
+
let n = p.file_stem()?.to_string_lossy().into_owned();
+
Some((
+
n,
+
Sound::load(&ctx, &std::fs::read(p).expect("can't load sound")),
+
))
+
})
+
.collect::<HashMap<String, Sound>>();
+
+
let handle_request = |mut stream: TcpStream| {
+
let mut lines = BufReader::new(&stream)
+
.lines()
+
.flatten()
+
.take_while(|line| !line.is_empty());
+
+
let request_line = lines.next()?;
+
let query = parse_query_from_request(request_line.as_str());
+
let kind = query.get("kind").cloned().unwrap_or("sound");
+
+
if let Some(sound) = sounds.get(kind) {
+
sound.play(&ctx, PlaySoundParams::default());
+
}
+
+
// exhaust connection to not get "connection reset by peer"
+
lines.for_each(drop);
+
// this never "fails"
+
let response = "HTTP/1.1 200 OK\r\n\r\n";
+
let _ = stream.write_all(response.as_bytes());
+
+
Some(())
+
};
let port = std::env::var("PORT")
.ok()
···
let listener = TcpListener::bind(("0.0.0.0", port)).expect("cant bind");
for stream in listener.incoming() {
+
let Ok(stream) = stream else {
continue;
};
+
handle_request(stream);
}
}
+
+
fn parse_query_from_request(request_line: &str) -> HashMap<&str, &str> {
+
request_line
+
.split_whitespace()
+
.nth(1)
+
.and_then(|path| path.split_once('?'))
+
.map(|(_, query)| {
+
query
+
.split('&')
+
.filter_map(|param| {
+
if let Some((key, value)) = param.split_once('=') {
+
Some((key, value))
+
} else if !param.is_empty() {
+
Some((param, ""))
+
} else {
+
None
+
}
+
})
+
.collect()
+
})
+
.unwrap_or_default()
+
}
src/sound.ogg sounds/sound.ogg