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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
						 | 
				
			
			@ -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