Implement Throttle filter (fails because not executed on runtime)
This commit is contained in:
parent
9123d63343
commit
e77a3d0e98
4 changed files with 33 additions and 14 deletions
|
@ -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(())
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
extern crate bytes;
|
||||
extern crate futures;
|
||||
extern crate odds;
|
||||
extern crate tokio;
|
||||
|
||||
pub mod ebml;
|
||||
pub mod error;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#[macro_use] extern crate clap;
|
||||
extern crate futures;
|
||||
extern crate hyper;
|
||||
extern crate tokio;
|
||||
extern crate webmetro;
|
||||
|
||||
mod commands;
|
||||
|
|
Loading…
Reference in a new issue