🚧 wip: http
							parent
							
								
									8e8b2ef17d
								
							
						
					
					
						commit
						086b2942fa
					
				|  | @ -235,6 +235,57 @@ impl Decoder { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| trait Demuxer { | ||||
| 	
 | ||||
| } | ||||
| 
 | ||||
| struct FfmpegDemuxer { | ||||
| 	input_ctx: DemuxContext, | ||||
| 	best_stream_idx: usize, | ||||
| 	decoder: DecodeContext, | ||||
| } | ||||
| 
 | ||||
| impl FfmpegDemuxer { | ||||
| 	pub fn new (filename: &str) -> Result <Self> { | ||||
| 		let input_ctx = ffmpeg_next::format::input (&filename)?; | ||||
| 		let stream = input_ctx | ||||
| 		.streams () | ||||
| 		.best (ffmpeg_next::media::Type::Audio) | ||||
| 		.ok_or_else (|| anyhow! ("can't find good audio stream"))?; | ||||
| 		let best_stream_idx = stream.index (); | ||||
| 		
 | ||||
| 		let decoder = stream.codec ().decoder ().audio ()?; | ||||
| 		
 | ||||
| 		Ok (Self { | ||||
| 			input_ctx, | ||||
| 			best_stream_idx, | ||||
| 			decoder, | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl FfmpegDemuxer { | ||||
| 	fn pump (&mut self) -> Result < | ||||
| } | ||||
| 
 | ||||
| use crate::net_reader::NetReader; | ||||
| 
 | ||||
| struct HttpOggDemuxer { | ||||
| 	ogg_rdr: ogg::reading::PacketReader <std::io::BufReader <NetReader>>, | ||||
| } | ||||
| 
 | ||||
| impl HttpOggDemuxer { | ||||
| 	pub fn new (url: String) -> Result <Self> { | ||||
| 		let net_rdr = NetReader::new (url)?; | ||||
| 		let buf_rdr = std::io::BufReader::new (net_rdr); | ||||
| 		let mut ogg_rdr = ogg::reading::PacketReader::new (buf_rdr); | ||||
| 		
 | ||||
| 		Ok (Self { | ||||
| 			ogg_rdr, | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| #[cfg (test)] | ||||
| mod test { | ||||
| 	use super::*; | ||||
|  |  | |||
							
								
								
									
										72
									
								
								src/main.rs
								
								
								
								
							
							
						
						
									
										72
									
								
								src/main.rs
								
								
								
								
							|  | @ -36,6 +36,7 @@ use fltk::{ | |||
| }; | ||||
| 
 | ||||
| mod decoder; | ||||
| mod net_reader; | ||||
| 
 | ||||
| const BUFFER_SIZE: usize = 5_000; | ||||
| 
 | ||||
|  | @ -68,66 +69,8 @@ fn cmd_debug_net (args: &[String]) -> Result <()> { | |||
| 	let url = args.get (1).ok_or_else (|| anyhow! ("Need a URL"))? | ||||
| 	.to_string (); | ||||
| 	
 | ||||
| 	struct NetReader { | ||||
| 		client: reqwest::blocking::Client, | ||||
| 		url: String, | ||||
| 		len: u64, | ||||
| 		cursor: u64, | ||||
| 	} | ||||
| 	
 | ||||
| 	impl Read for NetReader { | ||||
| 		fn read (&mut self, dest: &mut [u8]) -> io::Result <usize> | ||||
| 		{ | ||||
| 			tracing::trace! ("NetReader reading {}-{}", self.cursor, self.cursor + dest.len () as u64); | ||||
| 			
 | ||||
| 			let range_hdr = format! ("bytes={}-{}", self.cursor, self.cursor + dest.len () as u64 - 1); | ||||
| 			
 | ||||
| 			let mut resp = self.client.get (&self.url) | ||||
| 			.header (reqwest::header::RANGE, range_hdr) | ||||
| 			.send () | ||||
| 			.map_err (|e| io::Error::new (io::ErrorKind::ConnectionRefused, e))?; | ||||
| 			
 | ||||
| 			let mut cursor = std::io::Cursor::new (dest); | ||||
| 			let bytes_moved = resp.copy_to (&mut cursor) | ||||
| 			.map_err (|e| io::Error::new (io::ErrorKind::ConnectionReset, e))?; | ||||
| 			
 | ||||
| 			self.cursor += bytes_moved; | ||||
| 			tracing::trace! ("NetReader read {} bytes", bytes_moved); | ||||
| 			Ok (bytes_moved.try_into ().unwrap ()) | ||||
| 		} | ||||
| 	} | ||||
| 	
 | ||||
| 	impl Seek for NetReader { | ||||
| 		fn seek (&mut self, pos: SeekFrom) -> io::Result <u64> | ||||
| 		{ | ||||
| 			// If your data is as big as 63 bits you'll just have
 | ||||
| 			// to suffer I guess
 | ||||
| 			
 | ||||
| 			let new_cursor = match pos { | ||||
| 				SeekFrom::Start (x) => x as i64, | ||||
| 				SeekFrom::Current (x) => self.cursor as i64 + x, | ||||
| 				SeekFrom::End (x) => self.len as i64 + x, | ||||
| 			}; | ||||
| 			
 | ||||
| 			let new_cursor = u64::try_from (new_cursor).map_err (|e| io::Error::new (io::ErrorKind::InvalidInput, e))?; | ||||
| 			self.cursor = new_cursor; | ||||
| 			
 | ||||
| 			Ok (self.cursor) | ||||
| 		} | ||||
| 	} | ||||
| 	
 | ||||
| 	let client = reqwest::blocking::Client::new (); | ||||
| 	let len = client.head (&url).send ()?.content_length ().ok_or_else (|| anyhow! ("Couldn't get content-length of URL"))?; | ||||
| 	
 | ||||
| 	let net_rdr = NetReader { | ||||
| 		client, | ||||
| 		url, | ||||
| 		cursor: 0, | ||||
| 		len, | ||||
| 	}; | ||||
| 	
 | ||||
| 	let net_rdr = net_reader::NetReader::new (url)?; | ||||
| 	let buf_rdr = std::io::BufReader::new (net_rdr); | ||||
| 	
 | ||||
| 	let mut ogg_rdr = ogg::reading::PacketReader::new (buf_rdr); | ||||
| 	
 | ||||
| 	let mut packet_count = 0; | ||||
|  | @ -311,18 +254,7 @@ fn cmd_gui (args: &[String]) -> Result <()> { | |||
| 	
 | ||||
| 	wind.end (); | ||||
| 	wind.show (); | ||||
| 	/* | ||||
| 	let mut gui = Gui { | ||||
| 		can_decode: false, | ||||
| 		audio_is_streaming: false, | ||||
| 		intend_to_play: false, | ||||
| 		trying_to_stream: false, | ||||
| 		but_pause, | ||||
| 		but_play, | ||||
| 	}; | ||||
| 	
 | ||||
| 	gui.sync (); | ||||
| 	*/ | ||||
| 	let mut shared_state = SharedState::default (); | ||||
| 	let silence = vec! [0; 12_000 * 4 * 2]; | ||||
| 	shared_state.pcm_buffers.produce_bytes (silence); | ||||
|  |  | |||
|  | @ -0,0 +1,75 @@ | |||
| use std::{ | ||||
| 	io::{ | ||||
| 		self, | ||||
| 		Read, | ||||
| 		Seek, | ||||
| 		SeekFrom, | ||||
| 	}, | ||||
| }; | ||||
| 
 | ||||
| use anyhow::{ | ||||
| 	Result, | ||||
| 	anyhow, | ||||
| }; | ||||
| 
 | ||||
| pub struct NetReader { | ||||
| 	client: reqwest::blocking::Client, | ||||
| 	url: String, | ||||
| 	len: u64, | ||||
| 	cursor: u64, | ||||
| } | ||||
| 
 | ||||
| impl NetReader { | ||||
| 	pub fn new (url: String) -> Result <Self> { | ||||
| 		let client = reqwest::blocking::Client::new (); | ||||
| 		let len = client.head (&url).send ()?.content_length ().ok_or_else (|| anyhow! ("Couldn't get content-length of URL"))?; | ||||
| 		
 | ||||
| 		Ok (NetReader { | ||||
| 			client, | ||||
| 			url, | ||||
| 			cursor: 0, | ||||
| 			len, | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Read for NetReader { | ||||
| 	fn read (&mut self, dest: &mut [u8]) -> io::Result <usize> | ||||
| 	{ | ||||
| 		tracing::trace! ("NetReader reading {}-{}", self.cursor, self.cursor + dest.len () as u64); | ||||
| 		
 | ||||
| 		let range_hdr = format! ("bytes={}-{}", self.cursor, self.cursor + dest.len () as u64 - 1); | ||||
| 		
 | ||||
| 		let mut resp = self.client.get (&self.url) | ||||
| 		.header (reqwest::header::RANGE, range_hdr) | ||||
| 		.send () | ||||
| 		.map_err (|e| io::Error::new (io::ErrorKind::ConnectionRefused, e))?; | ||||
| 		
 | ||||
| 		let mut cursor = std::io::Cursor::new (dest); | ||||
| 		let bytes_moved = resp.copy_to (&mut cursor) | ||||
| 		.map_err (|e| io::Error::new (io::ErrorKind::ConnectionReset, e))?; | ||||
| 		
 | ||||
| 		self.cursor += bytes_moved; | ||||
| 		tracing::trace! ("NetReader read {} bytes", bytes_moved); | ||||
| 		Ok (bytes_moved.try_into ().unwrap ()) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| impl Seek for NetReader { | ||||
| 	fn seek (&mut self, pos: SeekFrom) -> io::Result <u64> | ||||
| 	{ | ||||
| 		// If your data is as big as 63 bits you'll just have
 | ||||
| 		// to suffer I guess
 | ||||
| 		
 | ||||
| 		let new_cursor = match pos { | ||||
| 			SeekFrom::Start (x) => x as i64, | ||||
| 			SeekFrom::Current (x) => self.cursor as i64 + x, | ||||
| 			SeekFrom::End (x) => self.len as i64 + x, | ||||
| 		}; | ||||
| 		
 | ||||
| 		let new_cursor = u64::try_from (new_cursor).map_err (|e| io::Error::new (io::ErrorKind::InvalidInput, e))?; | ||||
| 		self.cursor = new_cursor; | ||||
| 		
 | ||||
| 		Ok (self.cursor) | ||||
| 	} | ||||
| } | ||||
		Loading…
	
		Reference in New Issue
	
	 _
						_