use async_channel::Receiver;
use std::io::{Read, Seek, SeekFrom};
use symphonia::core::io::MediaSource;
pub struct ChannelReaderMediaSource {
receiver: Receiver<Vec<u8>>,
buffer: Vec<u8>,
pos: usize,
}
impl ChannelReaderMediaSource {
pub fn new(receiver: Receiver<Vec<u8>>) -> Self {
Self {
receiver,
buffer: Vec::new(),
pos: 0,
}
}
}
impl Read for ChannelReaderMediaSource {
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
while self.pos >= self.buffer.len() {
match self.receiver.recv_blocking() {
Ok(chunk) => {
self.buffer = chunk;
self.pos = 0;
}
Err(_) => return Ok(0),
}
}
let n = (self.buffer.len() - self.pos).min(buf.len());
buf[..n].copy_from_slice(&self.buffer[self.pos..self.pos + n]);
self.pos += n;
Ok(n)
}
}
impl Seek for ChannelReaderMediaSource {
fn seek(&mut self, _: SeekFrom) -> std::io::Result<u64> {
Err(std::io::Error::new(
std::io::ErrorKind::Unsupported,
"stream not seekable",
))
}
}
impl MediaSource for ChannelReaderMediaSource {
fn is_seekable(&self) -> bool {
false
}
fn byte_len(&self) -> Option<u64> {
None
}
}