57 lines
2.4 KiB
JavaScript
57 lines
2.4 KiB
JavaScript
import { attachVideoPip } from './archipelago-video.mjs'
|
|
|
|
// Controls the original remote video, never a clone or a second media player.
|
|
const toolbar = document.createElement('aside')
|
|
toolbar.setAttribute('aria-label', 'Call picture-in-picture')
|
|
toolbar.style.cssText = 'position:fixed;right:1rem;bottom:1rem;z-index:40;max-width:22rem;padding:.6rem;background:Canvas;color:CanvasText;border:1px solid;border-radius:.5rem'
|
|
const select = document.createElement('select')
|
|
select.setAttribute('aria-label', 'Call video for picture-in-picture')
|
|
const button = document.createElement('button')
|
|
button.type = 'button'; button.textContent = 'Picture-in-picture'
|
|
const status = document.createElement('p')
|
|
status.setAttribute('role', 'status'); status.setAttribute('aria-live', 'polite')
|
|
toolbar.append(select, button, status)
|
|
document.body.append(toolbar)
|
|
let videos = []
|
|
let disposed = false
|
|
function refresh() {
|
|
if (disposed) return
|
|
const next = [...document.querySelectorAll('video[data-track]')].filter(video => video.isConnected && video.srcObject)
|
|
if (next.length === videos.length && next.every((video, i) => video === videos[i])) return
|
|
const selected = videos[Number(select.value)]
|
|
if (selected && !next.includes(selected)) stopPresentation()
|
|
videos = next
|
|
select.replaceChildren(...videos.map((video, i) => {
|
|
const option = document.createElement('option')
|
|
option.value = String(i); option.textContent = `Call video ${i + 1}`
|
|
option.selected = video === selected
|
|
return option
|
|
}))
|
|
toolbar.hidden = !videos.length
|
|
}
|
|
toolbar.hidden = true
|
|
const dashboard = new URL(location.href); dashboard.port = ''; dashboard.pathname = '/'
|
|
const pip = attachVideoPip({ button, status, getVideo: () => videos[Number(select.value) || 0], dashboardOrigin: dashboard.origin })
|
|
function stopPresentation() {
|
|
pip.stop()
|
|
}
|
|
select.addEventListener('change', stopPresentation)
|
|
const observer = new MutationObserver(refresh)
|
|
observer.observe(document.body, { childList: true, subtree: true })
|
|
refresh()
|
|
function pagehide(event) {
|
|
if (disposed) return
|
|
stopPresentation()
|
|
if (event.persisted) return
|
|
disposed = true
|
|
observer.disconnect()
|
|
pip.dispose()
|
|
select.removeEventListener('change', stopPresentation)
|
|
window.removeEventListener('pagehide', pagehide)
|
|
window.removeEventListener('pageshow', refresh)
|
|
toolbar.remove()
|
|
videos = []
|
|
}
|
|
window.addEventListener('pagehide', pagehide)
|
|
window.addEventListener('pageshow', refresh)
|