Use webm chunker operator in loop_server

This commit is contained in:
Tangent 128 2017-10-04 02:11:19 -04:00
parent e0346ae30a
commit 0902a810e5

View file

@ -3,24 +3,21 @@ extern crate hyper;
extern crate lab_ebml; extern crate lab_ebml;
use futures::future::FutureResult; use futures::future::FutureResult;
use futures::stream::{once, iter, Stream}; use futures::stream::{iter, Stream};
use lab_ebml::chunk::Chunk; use lab_ebml::chunk::{Chunk, WebmStream};
use lab_ebml::Schema; use lab_ebml::Schema;
use lab_ebml::timecode_fixer::ChunkStream; use lab_ebml::timecode_fixer::ChunkStream;
use lab_ebml::webm::*; use lab_ebml::webm::*;
use lab_ebml::webm::WebmElement::*;
use hyper::{Get, StatusCode}; use hyper::{Get, StatusCode};
use hyper::header::ContentType; use hyper::header::ContentType;
use hyper::server::{Http, Request, Response, Service}; use hyper::server::{Http, Request, Response, Service};
use std::env::args; use std::env::args;
use std::io::Cursor;
use std::net::ToSocketAddrs; use std::net::ToSocketAddrs;
use std::sync::Arc;
const SRC_FILE: &'static [u8] = include_bytes!("../data/test1.webm"); const SRC_FILE: &'static [u8] = include_bytes!("../data/test1.webm");
#[derive(Clone)] #[derive(Clone)]
struct WebmServer(Chunk, Vec<Chunk>); struct WebmServer;
type BodyStream<B> = Box<Stream<Item = Chunk<B>, Error = hyper::Error>>; type BodyStream<B> = Box<Stream<Item = Chunk<B>, Error = hyper::Error>>;
@ -32,13 +29,11 @@ impl Service for WebmServer {
fn call(&self, req: Request) -> Self::Future { fn call(&self, req: Request) -> Self::Future {
let response = match (req.method(), req.path()) { let response = match (req.method(), req.path()) {
(&Get, "/loop") => { (&Get, "/loop") => {
let results: Vec<Result<Chunk, ()>> = self.1.iter().map(|x| Ok(x.clone())).collect(); let stream: BodyStream<Vec<u8>> = iter(Webm.parse(SRC_FILE).into_iter().map(|x| Ok(x)))
let stream: BodyStream<Vec<u8>> = Box::new( .chunk_webm()
once(Ok(self.0.clone())) .chain(iter(Webm.parse(SRC_FILE).into_iter().map(|x| Ok(x))).chunk_webm())
.chain(iter(results.into_iter().cycle().take(20)))
.map_err(|_| hyper::Error::Incomplete)
.fix_timecodes() .fix_timecodes()
); .boxed();
Response::new() Response::new()
.with_header(ContentType("video/webm".parse().unwrap())) .with_header(ContentType("video/webm".parse().unwrap()))
.with_body(stream) .with_body(stream)
@ -54,62 +49,5 @@ impl Service for WebmServer {
pub fn main() { pub fn main() {
let addr = args().nth(1).unwrap().to_socket_addrs().unwrap().next().unwrap(); let addr = args().nth(1).unwrap().to_socket_addrs().unwrap().next().unwrap();
let webm_service = create_loop(); Http::new().bind(&addr, move || Ok(WebmServer)).unwrap().run().unwrap();
Http::new().bind(&addr, move || Ok(webm_service.clone())).unwrap().run().unwrap();
}
fn create_loop() -> WebmServer {
let mut header = None;
let mut reading_head = true;
let mut cluster_header = None;
let mut cluster_timecode = 0;
let mut chunks = Vec::new();
let mut buffer = Cursor::new(Vec::new());
for element in Webm.parse(SRC_FILE) {
match element {
Cluster => {
if reading_head {
header = Some(Chunk::Headers {bytes: Arc::new(buffer.into_inner())});
} else {
if let Some(chunk) = cluster_header.take() {
chunks.push(chunk);
}
chunks.push(Chunk::ClusterBody {bytes: Arc::new(buffer.into_inner())});
}
buffer = Cursor::new(Vec::new());
reading_head = false;
},
Timecode(timecode) => {
cluster_timecode = timecode;
cluster_header = Some(Chunk::<Vec<u8>>::new_cluster_head(timecode));
},
SimpleBlock(ref block) => {
if let Some(ref mut chunk) = cluster_header {
if (block.flags & 0b10000000) != 0 {
// TODO: this is incorrect, condition needs to also affirm we're the first video block of the cluster
chunk.mark_keyframe(true);
}
chunk.observe_simpleblock_timecode(block.timecode);
}
encode_webm_element(&SimpleBlock(*block), &mut buffer).unwrap();
},
Info => continue,
Void => continue,
Unknown(_) => continue,
ref other => {
encode_webm_element(other, &mut buffer).unwrap();
},
}
}
// finish last cluster
if let Some(chunk) = cluster_header.take() {
chunks.push(chunk);
}
chunks.push(Chunk::ClusterBody {bytes: Arc::new(buffer.into_inner())});
WebmServer(header.unwrap(), chunks)
} }