aboutsummaryrefslogtreecommitdiff
path: root/server/src/routes/ui/style/js-player.js
blob: 7c3bb43a28121de4d71b1c9fe60b98b61ec2ba97 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
    This file is part of jellything (https://codeberg.org/metamuffin/jellything)
    which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
    Copyright (C) 2023 metamuffin <metamuffin.org>
*/

globalThis.addEventListener("load", () => {
    for (const e of document.getElementsByTagName("video"))
        patch_video(e)
})

function patch_video(e) {
    // move the video to a div
    const d = document.createElement("div")
    const p = e.parentElement
    p.removeChild(e)
    d.appendChild(e)
    p.prepend(d)

    e.removeAttribute("controls")
    d.classList.add("js-player")

    const controls = document.createElement("div")
    controls.classList.add("controls")

    const pause_button = document.createElement("button")
    pause_button.textContent = "|>"

    const fullscreen_button = document.createElement("button")
    fullscreen_button.textContent = "X"

    const status_display = document.createElement("p")
    status_display.classList.add("status")

    const pri = document.createElement("div")
    pri.classList.add("pri")
    const pri_current = document.createElement("div")
    pri_current.style.width = "0px"
    pri_current.classList.add("pri-current")
    pri.append(pri_current)

    controls.append(pause_button, status_display, pri, fullscreen_button)
    d.append(controls)


    e.onloadedmetadata = () => {

    }
    e.ondurationchange = () => {

    }
    e.ontimeupdate = () => {
        status_display.innerHTML = display_time(e.currentTime) + "<br/>" + display_time(e.currentTime - e.duration); // TODO can we have <br> with textContent?!
        pri_current.style.width = (e.currentTime / e.duration * 100) + "%"
    }
    e.onplay = () => {
        pause_button.textContent = "..."
    }
    e.onwaiting = () => {
        pause_button.textContent = "..."
    }
    e.onplaying = () => {
        pause_button.textContent = "||"
    }
    e.onpause = () => {
        pause_button.textContent = "|>"
    }
    const toggle_playing = () => e.paused ? e.play() : e.pause()

    mouse_idle(e, 1000, idle => {
        controls.style.opacity = idle ? 0 : 1
        e.style.cursor = idle ? "none" : "default"
    })

    e.addEventListener("click", toggle_playing)
    pause_button.addEventListener("click", toggle_playing)
    fullscreen_button.addEventListener("click", () => {
        if (document.fullscreenElement) document.exitFullscreen()
        else document.documentElement.requestFullscreen()
    })
    const seek_ev = ev => {
        const r = pri.getBoundingClientRect()
        const p = (ev.clientX - r.left) / (r.right - r.left)
        e.currentTime = p * e.duration
    }
    pri.addEventListener("mousedown", ev => {
        seek_ev(ev)
    })
    document.body.addEventListener("keydown", k => {
        if (k.code == "Period") e.seekToNextFrame()
        else if (k.code == "Space") toggle_playing()
        else if (k.code == "ArrowLeft") e.currentTime -= 5
        else if (k.code == "ArrowRight") e.currentTime += 5
        else if (k.code == "ArrowUp") e.currentTime -= 60
        else if (k.code == "ArrowDown") e.currentTime += 60
        else return;
        k.preventDefault()
    })
}

function mouse_idle(e, timeout, cb) {
    let ct;
    let idle = false
    e.onmouseleave = () => { clearTimeout(ct) }
    e.onmousemove = () => {
        clearTimeout(ct)
        if (idle) {
            idle = false
            cb(idle)
        }
        ct = setTimeout(() => {
            idle = true
            cb(idle)
        }, timeout)
    }
}

function display_time(t) {
    if (t < 0) return "-" + display_time(-t)
    let h = 0, m = 0, s = 0;
    while (t > 3600) t -= 3600, h++;
    while (t > 60) t -= 60, m++;
    while (t > 1) t -= 1, s++;
    return (h ? h + "h" : "") + (m ? m + "m" : "") + (s ? s + "s" : "")
}