Implement continuous mode

This commit is contained in:
Cadence Ember 2021-04-26 00:02:59 +12:00
parent e4f6ffe122
commit 2b2f8bf84a
No known key found for this signature in database
GPG Key ID: BC1C2C61CF521B17
7 changed files with 130 additions and 14 deletions

View File

@ -183,21 +183,35 @@ module.exports = [
const user = getUser(req)
const settings = user.getSettingsOrDefaults()
const id = url.searchParams.get("v")
// Media fragment
const t = url.searchParams.get("t")
let mediaFragment = converters.tToMediaFragment(t)
// Continuous mode
const continuous = url.searchParams.get("continuous") === "1"
const swp = url.searchParams.get("session-watched")
const sessionWatched = swp ? swp.split(" ") : []
const sessionWatchedNext = sessionWatched.concat([id]).join("+")
if (continuous) settings.quality = 0 // autoplay with synced streams does not work
if (req.method === "GET") {
if (settings.local) {
if (settings.local) { // skip to the local fetching page, which will then POST video data in a moment
return render(200, "pug/local-video.pug", {id})
}
const instanceOrigin = settings.instance
const outURL = `${instanceOrigin}/api/v1/videos/${id}`
const video = await request(outURL).then(res => res.json())
return renderVideo(video, {user, settings, id, instanceOrigin}, {mediaFragment})
var instanceOrigin = settings.instance
var outURL = `${instanceOrigin}/api/v1/videos/${id}`
var video = await request(outURL).then(res => res.json())
} else { // req.method === "POST"
const video = JSON.parse(new URLSearchParams(body.toString()).get("video"))
const instanceOrigin = "http://localhost:3000"
return renderVideo(video, {user, settings, id, instanceOrigin}, {mediaFragment})
var instanceOrigin = "http://localhost:3000"
var video = JSON.parse(new URLSearchParams(body.toString()).get("video"))
}
return renderVideo(video, {
user, settings, id, instanceOrigin
}, {
mediaFragment, continuous, sessionWatched, sessionWatchedNext
})
}
}
]

View File

@ -0,0 +1,34 @@
import {q, ejs, ElemJS} from "/static/js/elemjs/elemjs.js"
const video = q("#video")
console.log
video.addEventListener("ended", () => {
if (data.continuous) {
const first = data.recommendedVideos[0]
window.location.assign(`/watch?v=${first.videoId}&continuous=1`)
}
})
class ContinuousControls extends ElemJS {
constructor() {
super(q("#continuous-controls"))
this.button = ejs(q("#continuous-stop"))
this.button.on("click", this.onClick.bind(this))
}
onClick(event) {
event.preventDefault()
this.element.style.display = "none"
data.continuous = false
q("#continuous-related-videos").remove()
q("#standard-related-videos").style.display = ""
const url = new URL(location)
url.searchParams.delete("continuous")
url.searchParams.delete("session-watched")
history.replaceState(null, "", url.toString())
}
}
new ContinuousControls(q("#continuous-stop"))

View File

@ -1,6 +1,8 @@
mixin video_list_item(className, video, instanceOrigin, options = {})
div(class={[className]: true, "video-list-item--watched": video.watched})
- let link = `/watch?v=${video.videoId}`
if options.continuous
- link += `&continuous=1&session-watched=${sessionWatchedNext}`
a(href=link tabindex="-1").thumbnail
img(src=`/vi/${video.videoId}/mqdefault.jpg` width=320 height=180 alt="").image
if video.second__lengthText != undefined

View File

@ -9,16 +9,22 @@ block head
else
title Error - CloudTube
script(type="module" src=getStaticURL("html", "/static/js/player.js"))
script const data = !{JSON.stringify(video)}
script const data = !{JSON.stringify({...video, continuous})}
block content
unless error
if continuous
- const first = video.recommendedVideos[0]
if first
script(type="module" src=getStaticURL("html", "/static/js/continuous.js"))
noscript
meta(http-equiv="refresh" content=`${video.lengthSeconds+5};url=/watch?v=${first.videoId}&continuous=1`)
main.video-page
.main-video-section
.video-container
- const format = formats[0]
if format
video(controls preload="auto" width=format.second__width height=format.second__height data-itag=format.itag)#video.video
video(controls preload="auto" width=format.second__width height=format.second__height data-itag=format.itag autoplay=continuous)#video.video
source(src=format.url+mediaFragment type=format.type)
each t in video.captions
track(label=t.label kind="subtitles" srclang=t.languageCode src=t.url)
@ -44,6 +50,15 @@ block content
#live-event-notice
#audio-loading-display
if continuous
div#continuous-controls.continuous
.continuous__description
.continuous__title Continuous mode: next video autoplays
noscript
.continuous__script-warning Without JavaScript, it will trigger on a timer, not on video completion.
.continuous__buttons
a(href=`/watch?v=${video.videoId}`)#continuous-stop.border-look Turn off
.button-container
+subscribe_button(video.authorId, subscribed, `/watch?v=${video.videoId}`).border-look
//- button.border-look#theatre Theatre
@ -60,11 +75,29 @@ block content
.description!= video.descriptionHtml
aside.related-videos
h2.related-header Related videos
//- Standard view
aside(style=continuous ? "display: none" : "")#standard-related-videos.related-videos
.related-cols
h2.related-header Related videos
.continuous-start
a(href=`/watch?v=${video.videoId}&continuous=1` nofollow) Continuous mode
each r in video.recommendedVideos
+video_list_item("related-video", r, instanceOrigin)
//- Continuous view
if continuous
aside.related-videos#continuous-related-videos
- let column = video.recommendedVideos.filter(v => !sessionWatched.includes(v.videoId))
if column.length
.related-cols
h2.related-header Autoplay next
+video_list_item("related-video", column.shift(), instanceOrigin, {continuous: true})
if column.length
.related-cols
h2.related-header Related videos
each r in column
+video_list_item("related-video", r, instanceOrigin, {continuous: true}) // keep on continuous mode for all recommendations
else
//- error
main.video-error-page

View File

@ -8,6 +8,7 @@ $bg-accent-area: #44474b
$fg-bright: #fff
$fg-main: #ddd
$fg-dim: #bbb
$fg-warning: #ffb98f
$edge-grey: #808080

View File

@ -69,6 +69,29 @@
border-radius: 3px
background: linear-gradient(to right, #1a1 var(--rating), #bbb var(--rating))
.continuous
display: flex
align-items: center
justify-content: space-between
margin: 16px 4px
padding: 12px
border-radius: 4px
background-color: c.$bg-darkest
&__description
margin-left: 12px
&__title
font-size: 20px
&__script-warning
font-size: 15px
color: c.$fg-warning
&__buttons
display: flex
flex-shrink: 0
.description
font-size: 17px
word-break: break-word
@ -80,8 +103,17 @@
.subscribe-form
display: inline-block
.related-cols
display: flex
align-items: center
justify-content: space-between
margin-bottom: 8px
.continuous-start
font-size: 15px
.related-header
margin: 4px 0px 12px 2px
margin: 4px 0px 4px 2px
font-weight: normal
font-size: 26px

View File

@ -7,7 +7,7 @@ let constants = {
user_settings: {
instance: {
type: "string",
default: "https://second.cadence.moe"
default: "http://localhost:3000"
},
save_history: {
type: "boolean",