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::sync::{Arc, Mutex, Weak};
|
||||
use std::time::{SystemTime, UNIX_EPOCH, Duration};
|
||||
|
||||
use bytes::{Buf, Bytes};
|
||||
use clap::Args;
|
||||
use futures::{prelude::*, stream::FuturesUnordered, Stream};
|
||||
use html_escape::encode_double_quoted_attribute;
|
||||
use hyper::{
|
||||
header::{CACHE_CONTROL, CONTENT_TYPE},
|
||||
Body, Response,
|
||||
};
|
||||
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 webmetro::{
|
||||
channel::{Channel, Handle, Listener, Transmitter},
|
||||
|
@ -59,6 +62,21 @@ fn media_response(body: Body) -> Response<Body> {
|
|||
.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
|
||||
#[derive(Args, Debug)]
|
||||
pub struct RelayArgs {
|
||||
|
@ -107,7 +125,11 @@ pub async fn run(args: RelayArgs) -> Result<(), WebmetroError> {
|
|||
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
|
||||
.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