Implement Throttle filter (fails because not executed on runtime)

This commit is contained in:
Tangent 128 2018-04-14 04:45:35 -04:00
parent 9123d63343
commit e77a3d0e98
4 changed files with 33 additions and 14 deletions

View File

@ -13,6 +13,7 @@ use webmetro::{
Chunk, Chunk,
WebmStream WebmStream
}, },
error::WebmetroError,
fixers::ChunkStream, fixers::ChunkStream,
stream_parser::StreamEbml stream_parser::StreamEbml
}; };
@ -28,11 +29,10 @@ pub fn options() -> App<'static, 'static> {
pub fn run(args: &ArgMatches) -> Result<(), Box<Error>> { pub fn run(args: &ArgMatches) -> Result<(), Box<Error>> {
let stdin = io::stdin(); let stdin = io::stdin();
let mut chunk_stream: Box<Stream<Item = Chunk, Error = Box<Error>>> = Box::new( let mut chunk_stream: Box<Stream<Item = Chunk, Error = WebmetroError>> = Box::new(
StdinStream::new(stdin.lock()) StdinStream::new(stdin.lock())
.parse_ebml() .parse_ebml()
.chunk_webm() .chunk_webm()
.map_err(|err| Box::new(err) as Box<Error>)
.fix_timecodes() .fix_timecodes()
); );
@ -40,8 +40,9 @@ pub fn run(args: &ArgMatches) -> Result<(), Box<Error>> {
chunk_stream = Box::new(chunk_stream.throttle()); chunk_stream = Box::new(chunk_stream.throttle());
} }
let result = chunk_stream.fold((), |_, chunk| { chunk_stream.fold((), |_, chunk| {
io::stdout().write_all(chunk.as_ref()) io::stdout().write_all(chunk.as_ref())
}).wait(); }).wait()?;
result
Ok(())
} }

View File

@ -1,9 +1,10 @@
use std::time::Instant; use std::time::{Duration, Instant};
use futures::Async; use futures::prelude::*;
use futures::stream::Stream; use tokio::timer::Delay;
use chunk::Chunk; use chunk::Chunk;
use error::WebmetroError;
pub struct ChunkTimecodeFixer<S> { pub struct ChunkTimecodeFixer<S> {
stream: S, stream: S,
@ -86,16 +87,29 @@ impl<S: Stream<Item = Chunk>> Stream for StartingPointFinder<S>
pub struct Throttle<S> { pub struct Throttle<S> {
stream: S, stream: S,
start_time: Instant start_time: Instant,
sleep: Delay
} }
impl<S: Stream<Item = Chunk>> Stream for Throttle<S> impl<S: Stream<Item = Chunk, Error = WebmetroError>> Stream for Throttle<S>
{ {
type Item = S::Item; type Item = S::Item;
type Error = S::Error; type Error = WebmetroError;
fn poll(&mut self) -> Result<Async<Option<Self::Item>>, Self::Error> { fn poll(&mut self) -> Result<Async<Option<Self::Item>>, WebmetroError> {
self.stream.poll() match self.sleep.poll() {
Err(err) => return Err(WebmetroError::Unknown(Box::new(err))),
Ok(Async::NotReady) => return Ok(Async::NotReady),
Ok(Async::Ready(())) => { /* can continue */ }
}
let next_chunk = self.stream.poll();
if let Ok(Async::Ready(Some(Chunk::ClusterHead(ref cluster_head)))) = next_chunk {
// snooze until real time has "caught up" to the stream
let offset = Duration::from_millis(cluster_head.end);
self.sleep.reset(self.start_time + offset);
}
next_chunk
} }
} }
@ -118,9 +132,11 @@ pub trait ChunkStream where Self : Sized + Stream<Item = Chunk> {
} }
fn throttle(self) -> Throttle<Self> { fn throttle(self) -> Throttle<Self> {
let now = Instant::now();
Throttle { Throttle {
stream: self, stream: self,
start_time: Instant::now() start_time: now,
sleep: Delay::new(now)
} }
} }
} }

View File

@ -2,6 +2,7 @@
extern crate bytes; extern crate bytes;
extern crate futures; extern crate futures;
extern crate odds; extern crate odds;
extern crate tokio;
pub mod ebml; pub mod ebml;
pub mod error; pub mod error;

View File

@ -1,6 +1,7 @@
#[macro_use] extern crate clap; #[macro_use] extern crate clap;
extern crate futures; extern crate futures;
extern crate hyper; extern crate hyper;
extern crate tokio;
extern crate webmetro; extern crate webmetro;
mod commands; mod commands;