Include a simple built-in HTML player
This commit is contained in:
parent
3bb6641a53
commit
1ce026eb2e
3 changed files with 59 additions and 2 deletions
|
@ -1,15 +1,18 @@
|
||||||
use std::net::ToSocketAddrs;
|
use std::net::ToSocketAddrs;
|
||||||
use std::sync::{Arc, Mutex, Weak};
|
use std::sync::{Arc, Mutex, Weak};
|
||||||
|
use std::time::{SystemTime, UNIX_EPOCH, Duration};
|
||||||
|
|
||||||
use bytes::{Buf, Bytes};
|
use bytes::{Buf, Bytes};
|
||||||
use clap::Args;
|
use clap::Args;
|
||||||
use futures::{prelude::*, stream::FuturesUnordered, Stream};
|
use futures::{prelude::*, stream::FuturesUnordered, Stream};
|
||||||
|
use html_escape::encode_double_quoted_attribute;
|
||||||
use hyper::{
|
use hyper::{
|
||||||
header::{CACHE_CONTROL, CONTENT_TYPE},
|
header::{CACHE_CONTROL, CONTENT_TYPE},
|
||||||
Body, Response,
|
Body, Response,
|
||||||
};
|
};
|
||||||
use stream::iter;
|
use stream::iter;
|
||||||
use warp::{self, path, Filter};
|
use warp::reply::{html, with_header};
|
||||||
|
use warp::{self, path, Filter, Reply};
|
||||||
use weak_table::WeakValueHashMap;
|
use weak_table::WeakValueHashMap;
|
||||||
use webmetro::{
|
use webmetro::{
|
||||||
channel::{Channel, Handle, Listener, Transmitter},
|
channel::{Channel, Handle, Listener, Transmitter},
|
||||||
|
@ -59,6 +62,21 @@ fn media_response(body: Body) -> Response<Body> {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn player_css() -> impl Reply {
|
||||||
|
let css = include_str!("../data/player.css");
|
||||||
|
with_header(css, CONTENT_TYPE, "text/css")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn player_html(channel: impl AsRef<str>) -> impl Reply {
|
||||||
|
let timestamp = SystemTime::now().duration_since(UNIX_EPOCH).unwrap_or(Duration::ZERO).as_nanos();
|
||||||
|
let player = format!(
|
||||||
|
include_str!("../data/player.html"),
|
||||||
|
channel = encode_double_quoted_attribute(channel.as_ref()),
|
||||||
|
cachebust = timestamp
|
||||||
|
);
|
||||||
|
html(player)
|
||||||
|
}
|
||||||
|
|
||||||
/// Hosts an HTTP-based relay server
|
/// Hosts an HTTP-based relay server
|
||||||
#[derive(Args, Debug)]
|
#[derive(Args, Debug)]
|
||||||
pub struct RelayArgs {
|
pub struct RelayArgs {
|
||||||
|
@ -107,7 +125,11 @@ pub async fn run(args: RelayArgs) -> Result<(), WebmetroError> {
|
||||||
Response::new(Body::wrap_stream(post_stream(channel, stream)))
|
Response::new(Body::wrap_stream(post_stream(channel, stream)))
|
||||||
});
|
});
|
||||||
|
|
||||||
let routes = head.or(get).or(post_put);
|
let live = head.or(get).or(post_put);
|
||||||
|
let watch = path!("watch" / String).map(player_html);
|
||||||
|
let css = path!("static" / "css").map(player_css);
|
||||||
|
|
||||||
|
let routes = live.or(watch).or(css);
|
||||||
|
|
||||||
let mut server_futures: FuturesUnordered<_> = addrs
|
let mut server_futures: FuturesUnordered<_> = addrs
|
||||||
.map(|addr| warp::serve(routes.clone()).try_bind(addr))
|
.map(|addr| warp::serve(routes.clone()).try_bind(addr))
|
||||||
|
|
20
src/data/player.css
Normal file
20
src/data/player.css
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
body {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
background: #111;
|
||||||
|
color: #777;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 16px;
|
||||||
|
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
|
||||||
|
}
|
||||||
|
section {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: column;
|
||||||
|
}
|
||||||
|
video {
|
||||||
|
max-width: 100vw;
|
||||||
|
}
|
15
src/data/player.html
Normal file
15
src/data/player.html
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Watchog Stream</title>
|
||||||
|
<meta name="viewport" content="initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="../static/css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<section>
|
||||||
|
<video controls autoplay src="../live/{channel}?t={cachebust}"></video>
|
||||||
|
<p>The stream should begin automatically when ready;
|
||||||
|
if the video stutters, try pausing it for a second or two to allow a small buffer.</p>
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in a new issue