mirror of
https://github.com/zedeus/nitter
synced 2024-11-29 13:00:10 +01:00
Initial hls video playback support
This commit is contained in:
parent
bce76ab8d1
commit
f5fef0ff3a
@ -297,7 +297,7 @@ video, .video-container img {
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
background-color: #000000bd;
|
||||
background-color: #0000008d;
|
||||
}
|
||||
|
||||
.video-overlay p {
|
||||
@ -309,6 +309,15 @@ video, .video-container img {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.video-overlay div {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
top: calc(50% - 20px);
|
||||
margin: 0 auto;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.still-image {
|
||||
max-height: 379.5px;
|
||||
max-width: 533px;
|
||||
|
2
public/js/hls.light.min.js
vendored
Normal file
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
15
public/js/hlsPlayback.js
Normal 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();
|
||||
});
|
||||
}
|
@ -37,7 +37,7 @@ proc showSingleTimeline(name, after, agent: string; query: Option[Query];
|
||||
return ""
|
||||
|
||||
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];
|
||||
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),
|
||||
names.join(","), prefs)
|
||||
|
||||
return renderMain(timeline, cfg.title, "Multi")
|
||||
return renderMain(timeline, prefs, cfg.title, "Multi")
|
||||
|
||||
proc showTimeline(name, after: string; query: Option[Query];
|
||||
prefs: Prefs): Future[string] {.async.} =
|
||||
@ -79,7 +79,7 @@ settings:
|
||||
|
||||
routes:
|
||||
get "/":
|
||||
resp renderMain(renderSearch(), cfg.title)
|
||||
resp renderMain(renderSearch(), Prefs(), cfg.title)
|
||||
|
||||
post "/search":
|
||||
if @"query".len == 0:
|
||||
@ -104,7 +104,8 @@ routes:
|
||||
if refUri.path.len > 0 and "/settings" notin refUri.path: refUri.path
|
||||
else: "/"
|
||||
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/?":
|
||||
cond '.' notin @"name"
|
||||
@ -141,15 +142,15 @@ routes:
|
||||
if conversation.tweet.video.isSome():
|
||||
let thumb = get(conversation.tweet.video).thumb
|
||||
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)
|
||||
elif conversation.tweet.gif.isSome():
|
||||
let thumb = get(conversation.tweet.gif).thumb
|
||||
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)
|
||||
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":
|
||||
cond "http" in @"url"
|
||||
|
@ -17,13 +17,17 @@ proc renderNavbar*(title: string): VNode =
|
||||
icon "info-circled", title="About", href="/about"
|
||||
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 =
|
||||
let node = buildHtml(html(lang="en")):
|
||||
head:
|
||||
link(rel="stylesheet", `type`="text/css", href="/css/style.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:
|
||||
if titleText.len > 0:
|
||||
text titleText & " | " & title
|
||||
@ -63,4 +67,4 @@ proc renderError*(error: string): VNode =
|
||||
span: text error
|
||||
|
||||
proc showError*(error, title: string): string =
|
||||
renderMain(renderError(error), title, "Error")
|
||||
renderMain(renderError(error), Prefs(), title, "Error")
|
||||
|
@ -76,9 +76,10 @@ proc renderVideo(video: Video; prefs: Prefs): VNode =
|
||||
video(poster=thumb, controls=""):
|
||||
source(src=source, `type`="video/mp4")
|
||||
of m3u8, vmap:
|
||||
video(poster=thumb)
|
||||
tdiv(class="video-overlay"):
|
||||
p: text "Video playback not supported yet"
|
||||
video(poster=thumb, data-url=source, data-autoload="false")
|
||||
verbatim "<div class=\"video-overlay\" onclick=\"playVideo(this)\">"
|
||||
verbatim "<div class=\"card-overlay-circle\">"
|
||||
verbatim "<span class=\"card-overlay-triangle\"</span></div></div>"
|
||||
else:
|
||||
renderVideoDisabled(video)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user