Initial hls video playback support

This commit is contained in:
Zed 2019-08-19 20:25:00 +02:00
parent bce76ab8d1
commit f5fef0ff3a
6 changed files with 45 additions and 13 deletions

View file

@ -297,7 +297,7 @@ video, .video-container img {
top: 0; top: 0;
left: 0; left: 0;
z-index: 1; z-index: 1;
background-color: #000000bd; background-color: #0000008d;
} }
.video-overlay p { .video-overlay p {
@ -309,6 +309,15 @@ video, .video-container img {
font-size: 20px; font-size: 20px;
} }
.video-overlay div {
position: relative;
z-index: 0;
top: calc(50% - 20px);
margin: 0 auto;
width: 40px;
height: 40px;
}
.still-image { .still-image {
max-height: 379.5px; max-height: 379.5px;
max-width: 533px; max-width: 533px;

2
public/js/hls.light.min.js vendored Normal file

File diff suppressed because one or more lines are too long

15
public/js/hlsPlayback.js Normal file
View file

@ -0,0 +1,15 @@
function playVideo(overlay) {
const video = overlay.parentElement.querySelector('video');
video.setAttribute("controls", "");
overlay.style.display = "none";
const url = video.getAttribute("data-url");
var hls = new Hls({autoStartLoad: false});
hls.loadSource(url);
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, function () {
hls.loadLevel = hls.levels.length - 1;
hls.startLoad();
video.play();
});
}

View file

@ -37,7 +37,7 @@ proc showSingleTimeline(name, after, agent: string; query: Option[Query];
return "" return ""
let profileHtml = renderProfile(profile, timeline, await railFut, prefs) let profileHtml = renderProfile(profile, timeline, await railFut, prefs)
return renderMain(profileHtml, cfg.title, pageTitle(profile), pageDesc(profile)) return renderMain(profileHtml, prefs, cfg.title, pageTitle(profile), pageDesc(profile))
proc showMultiTimeline(names: seq[string]; after, agent: string; query: Option[Query]; proc showMultiTimeline(names: seq[string]; after, agent: string; query: Option[Query];
prefs: Prefs): Future[string] {.async.} = prefs: Prefs): Future[string] {.async.} =
@ -50,7 +50,7 @@ proc showMultiTimeline(names: seq[string]; after, agent: string; query: Option[Q
var timeline = renderMulti(await getTimelineSearch(get(q), after, agent), var timeline = renderMulti(await getTimelineSearch(get(q), after, agent),
names.join(","), prefs) names.join(","), prefs)
return renderMain(timeline, cfg.title, "Multi") return renderMain(timeline, prefs, cfg.title, "Multi")
proc showTimeline(name, after: string; query: Option[Query]; proc showTimeline(name, after: string; query: Option[Query];
prefs: Prefs): Future[string] {.async.} = prefs: Prefs): Future[string] {.async.} =
@ -79,7 +79,7 @@ settings:
routes: routes:
get "/": get "/":
resp renderMain(renderSearch(), cfg.title) resp renderMain(renderSearch(), Prefs(), cfg.title)
post "/search": post "/search":
if @"query".len == 0: if @"query".len == 0:
@ -104,7 +104,8 @@ routes:
if refUri.path.len > 0 and "/settings" notin refUri.path: refUri.path if refUri.path.len > 0 and "/settings" notin refUri.path: refUri.path
else: "/" else: "/"
if refUri.query.len > 0: path &= &"?{refUri.query}" if refUri.query.len > 0: path &= &"?{refUri.query}"
resp renderMain(renderPreferences(cookiePrefs(), path), cfg.title, "Preferences") let prefs = cookiePrefs()
resp renderMain(renderPreferences(prefs, path), prefs, cfg.title, "Preferences")
get "/@name/?": get "/@name/?":
cond '.' notin @"name" cond '.' notin @"name"
@ -141,15 +142,15 @@ routes:
if conversation.tweet.video.isSome(): if conversation.tweet.video.isSome():
let thumb = get(conversation.tweet.video).thumb let thumb = get(conversation.tweet.video).thumb
let vidUrl = getVideoEmbed(conversation.tweet.id) let vidUrl = getVideoEmbed(conversation.tweet.id)
resp renderMain(html, cfg.title, title, desc, images = @[thumb], resp renderMain(html, prefs, cfg.title, title, desc, images = @[thumb],
`type`="video", video=vidUrl) `type`="video", video=vidUrl)
elif conversation.tweet.gif.isSome(): elif conversation.tweet.gif.isSome():
let thumb = get(conversation.tweet.gif).thumb let thumb = get(conversation.tweet.gif).thumb
let vidUrl = getVideoEmbed(conversation.tweet.id) let vidUrl = getVideoEmbed(conversation.tweet.id)
resp renderMain(html, cfg.title, title, desc, images = @[thumb], resp renderMain(html, prefs, cfg.title, title, desc, images = @[thumb],
`type`="video", video=vidUrl) `type`="video", video=vidUrl)
else: else:
resp renderMain(html, cfg.title, title, desc, images=conversation.tweet.photos) resp renderMain(html, prefs, cfg.title, title, desc, images=conversation.tweet.photos)
get "/pic/@sig/@url": get "/pic/@sig/@url":
cond "http" in @"url" cond "http" in @"url"

View file

@ -17,13 +17,17 @@ proc renderNavbar*(title: string): VNode =
icon "info-circled", title="About", href="/about" icon "info-circled", title="About", href="/about"
icon "cog-2", title="Preferences", href="/settings" icon "cog-2", title="Preferences", href="/settings"
proc renderMain*(body: VNode; title="Nitter"; titleText=""; desc=""; proc renderMain*(body: VNode; prefs: Prefs; title="Nitter"; titleText=""; desc="";
`type`="article"; video=""; images: seq[string] = @[]): string = `type`="article"; video=""; images: seq[string] = @[]): string =
let node = buildHtml(html(lang="en")): let node = buildHtml(html(lang="en")):
head: head:
link(rel="stylesheet", `type`="text/css", href="/css/style.css") link(rel="stylesheet", `type`="text/css", href="/css/style.css")
link(rel="stylesheet", `type`="text/css", href="/css/fontello.css") link(rel="stylesheet", `type`="text/css", href="/css/fontello.css")
if prefs.hlsPlayback:
script(src="/js/hls.light.min.js")
script(src="/js/hlsPlayback.js")
title: title:
if titleText.len > 0: if titleText.len > 0:
text titleText & " | " & title text titleText & " | " & title
@ -63,4 +67,4 @@ proc renderError*(error: string): VNode =
span: text error span: text error
proc showError*(error, title: string): string = proc showError*(error, title: string): string =
renderMain(renderError(error), title, "Error") renderMain(renderError(error), Prefs(), title, "Error")

View file

@ -76,9 +76,10 @@ proc renderVideo(video: Video; prefs: Prefs): VNode =
video(poster=thumb, controls=""): video(poster=thumb, controls=""):
source(src=source, `type`="video/mp4") source(src=source, `type`="video/mp4")
of m3u8, vmap: of m3u8, vmap:
video(poster=thumb) video(poster=thumb, data-url=source, data-autoload="false")
tdiv(class="video-overlay"): verbatim "<div class=\"video-overlay\" onclick=\"playVideo(this)\">"
p: text "Video playback not supported yet" verbatim "<div class=\"card-overlay-circle\">"
verbatim "<span class=\"card-overlay-triangle\"</span></div></div>"
else: else:
renderVideoDisabled(video) renderVideoDisabled(video)