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

View File

@ -1,9 +1,10 @@
use std::time::Instant;
use std::time::{Duration, Instant};
use futures::Async;
use futures::stream::Stream;
use futures::prelude::*;
use tokio::timer::Delay;
use chunk::Chunk;
use error::WebmetroError;
pub struct ChunkTimecodeFixer<S> {
stream: S,
@ -86,16 +87,29 @@ impl<S: Stream<Item = Chunk>> Stream for StartingPointFinder<S>
pub struct Throttle<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 Error = S::Error;
type Error = WebmetroError;
fn poll(&mut self) -> Result<Async<Option<Self::Item>>, Self::Error> {
self.stream.poll()
fn poll(&mut self) -> Result<Async<Option<Self::Item>>, WebmetroError> {
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> {
let now = Instant::now();
Throttle {
stream: self,
start_time: Instant::now()
start_time: now,
sleep: Delay::new(now)
}
}
}

View File

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

View File

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