mirror of
https://github.com/ThatGuySam/doesitarm.git
synced 2026-05-18 06:44:46 -07:00
Add basic player component
This commit is contained in:
parent
5fd7d47a84
commit
3bd4340682
3 changed files with 165 additions and 9 deletions
51
components-eleventy/video/player.js
Normal file
51
components-eleventy/video/player.js
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
export default async function ( video, options = {} ) {
|
||||
const {
|
||||
width = '325px',
|
||||
classes = 'w-full flex-shrink-0 flex-grow-0 border-2 border-transparent rounded-2xl overflow-hidden'
|
||||
} = options
|
||||
|
||||
// Setup inline player script
|
||||
await this.usingComponent( 'node_modules/can-autoplay/build/can-autoplay.min.js' )
|
||||
|
||||
await this.usingComponent( 'helpers/lite-youtube.js' )
|
||||
|
||||
// Setup inline lazysizes
|
||||
await this.usingComponent( 'node_modules/lazysizes/lazysizes.min.js' )
|
||||
|
||||
// console.log('video', video)
|
||||
|
||||
return /* html */`
|
||||
<lite-youtube
|
||||
class="video-canvas w-screen flex flex-col justify-center items-center bg-black pt-16"
|
||||
style="left:50%;right:50%;margin-left:-50vw;margin-right:-50vw;"
|
||||
>
|
||||
<div class="ratio-wrapper w-full max-w-4xl">
|
||||
<div class="relative overflow-hidden w-full pb-16/9">
|
||||
<div class="player-poster cursor-pointer">
|
||||
<picture>
|
||||
<source sizes="(max-width: 640px) 100vw, 640px" data-srcset="https://i.ytimg.com/vi_webp/IJbmCNGPAbc/default.webp 120w, https://i.ytimg.com/vi_webp/IJbmCNGPAbc/mqdefault.webp 320w, https://i.ytimg.com/vi_webp/IJbmCNGPAbc/hqdefault.webp 480w, https://i.ytimg.com/vi_webp/IJbmCNGPAbc/sddefault.webp 640w" type="image/webp">
|
||||
<source sizes="(max-width: 640px) 100vw, 640px" data-srcset="https://i.ytimg.com/vi/IJbmCNGPAbc/default.jpg 120w, https://i.ytimg.com/vi/IJbmCNGPAbc/mqdefault.jpg 320w, https://i.ytimg.com/vi/IJbmCNGPAbc/hqdefault.jpg 480w, https://i.ytimg.com/vi/IJbmCNGPAbc/sddefault.jpg 640w" type="image/jpeg">
|
||||
<img data-src="https://i.ytimg.com/vi/IJbmCNGPAbc/default.jpg" alt="M1 Macs + Windows 10 GAMING and PERFORMANCE Improvements with Parallels 16.5!" class="absolute inset-0 h-full w-full object-cover lazyload">
|
||||
</picture>
|
||||
<div class="video-card-overlay absolute inset-0 flex flex-col justify-center items-center bg-gradient-to-tr from-black to-transparent p-4" style="--gradient-from-color:rgba(0, 0, 0, 1); --gradient-to-color:rgba(0, 0, 0, 0.7);">
|
||||
<div class="cover-top h-full"></div>
|
||||
<div class="play-circle bg-white-2 bg-blur flex justify-center items-center outline-0 rounded-full ease p-4">
|
||||
<svg viewBox="0 0 18 18" style="width:18px;height:18px;margin-left:3px">
|
||||
<path fill="currentColor" d="M15.562 8.1L3.87.225c-.818-.562-1.87 0-1.87.9v15.75c0 .9 1.052 1.462 1.87.9L15.563 9.9c.584-.45.584-1.35 0-1.8z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="cover-bottom h-full">
|
||||
<div class="page-heading h-full flex items-end md:p-4">
|
||||
<h1 class="title text-xs text-left md:text-2xl font-bold">M1 Macs + Windows 10 GAMING and PERFORMANCE Improvements with Parallels 16.5!</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="video-timestamps w-full max-w-4xl">
|
||||
<div class="featured-apps overflow-x-auto overflow-y-visible whitespace-no-wrap py-2 space-x-2"><button data-time="00:00" class-groups="[object Object]" class="inline-block text-xs rounded-lg py-1 px-2 border-2 border-white focus:outline-none border-opacity-0 neumorphic-shadow-inner">00:00 What is Parallels?</button><button data-time="00:35" class-groups="[object Object]" class="inline-block text-xs rounded-lg py-1 px-2 border-2 border-white focus:outline-none border-opacity-0 neumorphic-shadow-inner">00:35 What’s New In Version 16.5?</button><button data-time="01:42" class-groups="[object Object]" class="inline-block text-xs rounded-lg py-1 px-2 border-2 border-white focus:outline-none border-opacity-0 neumorphic-shadow-inner">01:42 Performance Improvements</button><button data-time="03:11" class-groups="[object Object]" class="inline-block text-xs rounded-lg py-1 px-2 border-2 border-white focus:outline-none border-opacity-0 neumorphic-shadow-inner">03:11 Windows 10 Gaming Improvements</button><button data-time="05:11" class-groups="[object Object]" class="inline-block text-xs rounded-lg py-1 px-2 border-2 border-white focus:outline-none border-opacity-0 neumorphic-shadow-inner">05:11 Does Valorant Work?</button></div>
|
||||
</div>
|
||||
</lite-youtube>
|
||||
`
|
||||
}
|
||||
107
helpers/lite-youtube.js
Normal file
107
helpers/lite-youtube.js
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
// https://github.com/paulirish/lite-youtube-embed/blob/master/src/lite-yt-embed.js
|
||||
|
||||
// import canAutoPlay from 'can-autoplay'
|
||||
|
||||
|
||||
/**
|
||||
* A lightweight youtube embed. Still should feel the same to the user, just MUCH faster to initialize and paint.
|
||||
*
|
||||
* Thx to these as the inspiration
|
||||
* https://storage.googleapis.com/amp-vs-non-amp/youtube-lazy.html
|
||||
* https://autoplay-youtube-player.glitch.me/
|
||||
*
|
||||
* Once built it, I also found these:
|
||||
* https://github.com/ampproject/amphtml/blob/master/extensions/amp-youtube (👍👍)
|
||||
* https://github.com/Daugilas/lazyYT
|
||||
* https://github.com/vb/lazyframe
|
||||
*/
|
||||
class LiteYTEmbed extends HTMLElement {
|
||||
constructor() {
|
||||
// Always call super first in constructor
|
||||
super()
|
||||
|
||||
// write element functionality in here
|
||||
|
||||
// console.log('canAutoplay', canAutoplay)
|
||||
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.videoId = this.getAttribute('videoid')
|
||||
|
||||
console.log('canAutoplay from connectedCallback', canAutoplay)
|
||||
|
||||
// On hover (or tap), warm up the TCP connections we're (likely) about to use.
|
||||
this.addEventListener('pointerover', LiteYTEmbed.warmConnections, {once: true})
|
||||
|
||||
// Once the user clicks, add the real iframe and drop our play button
|
||||
// TODO: In the future we could be like amp-youtube and silently swap in the iframe during idle time
|
||||
// We'd want to only do this for in-viewport or near-viewport ones: https://github.com/ampproject/amphtml/pull/5003
|
||||
this.addEventListener('click', e => this.addIframe())
|
||||
}
|
||||
|
||||
// // TODO: Support the the user changing the [videoid] attribute
|
||||
// attributeChangedCallback() {
|
||||
// }
|
||||
|
||||
/**
|
||||
* Add a <link rel={preload | preconnect} ...> to the head
|
||||
*/
|
||||
static addPrefetch(kind, url, as) {
|
||||
const linkEl = document.createElement('link')
|
||||
linkEl.rel = kind
|
||||
linkEl.href = url
|
||||
if (as) {
|
||||
linkEl.as = as
|
||||
}
|
||||
document.head.append(linkEl)
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin pre-connecting to warm up the iframe load
|
||||
* Since the embed's network requests load within its iframe,
|
||||
* preload/prefetch'ing them outside the iframe will only cause double-downloads.
|
||||
* So, the best we can do is warm up a few connections to origins that are in the critical path.
|
||||
*
|
||||
* Maybe `<link rel=preload as=document>` would work, but it's unsupported: http://crbug.com/593267
|
||||
* But TBH, I don't think it'll happen soon with Site Isolation and split caches adding serious complexity.
|
||||
*/
|
||||
static warmConnections() {
|
||||
if (LiteYTEmbed.preconnected) return
|
||||
|
||||
// The iframe document and most of its subresources come right off youtube.com
|
||||
LiteYTEmbed.addPrefetch('preconnect', 'https://www.youtube-nocookie.com')
|
||||
// The botguard script is fetched off from google.com
|
||||
LiteYTEmbed.addPrefetch('preconnect', 'https://www.google.com')
|
||||
|
||||
// Not certain if these ad related domains are in the critical path. Could verify with domain-specific throttling.
|
||||
LiteYTEmbed.addPrefetch('preconnect', 'https://googleads.g.doubleclick.net')
|
||||
LiteYTEmbed.addPrefetch('preconnect', 'https://static.doubleclick.net')
|
||||
|
||||
LiteYTEmbed.preconnected = true
|
||||
}
|
||||
|
||||
addIframe() {
|
||||
const params = new URLSearchParams(this.getAttribute('params') || [])
|
||||
params.append('autoplay', '1')
|
||||
|
||||
const iframeEl = document.createElement('iframe')
|
||||
iframeEl.width = 560
|
||||
iframeEl.height = 315
|
||||
// No encoding necessary as [title] is safe. https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#:~:text=Safe%20HTML%20Attributes%20include
|
||||
iframeEl.title = this.playLabel
|
||||
iframeEl.allow = 'accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture'
|
||||
iframeEl.allowFullscreen = true
|
||||
// AFAIK, the encoding here isn't necessary for XSS, but we'll do it only because this is a URL
|
||||
// https://stackoverflow.com/q/64959723/89484
|
||||
iframeEl.src = `https://www.youtube-nocookie.com/embed/${encodeURIComponent(this.videoId)}?${params.toString()}`
|
||||
this.append(iframeEl)
|
||||
|
||||
this.classList.add('lyt-activated')
|
||||
|
||||
// Set focus for a11y
|
||||
this.querySelector('iframe').focus()
|
||||
}
|
||||
}
|
||||
// Register custom element
|
||||
window.customElements.define('lite-youtube', LiteYTEmbed)
|
||||
|
|
@ -2,7 +2,9 @@ import dotenv from 'dotenv'
|
|||
|
||||
import config from '../nuxt.config'
|
||||
|
||||
import VideoPlayer from '../components-eleventy/video/player.js'
|
||||
import VideoRow from '../components-eleventy/video/row.js'
|
||||
|
||||
import { getRouteType } from '../helpers/app-derived'
|
||||
|
||||
// Setup dotenv
|
||||
|
|
@ -33,7 +35,6 @@ class TV {
|
|||
|
||||
pagination: {
|
||||
data: 'eleventy-endpoints',
|
||||
// data: 'collections.tv',
|
||||
size: 1,
|
||||
alias: 'tvEntry',
|
||||
before: function( endpoint ) {
|
||||
|
|
@ -89,6 +90,8 @@ class TV {
|
|||
|
||||
// console.log('video.payload', Object.keys(video.payload))
|
||||
|
||||
const playerHtml = await this.boundComponent(VideoPlayer)()
|
||||
|
||||
const rowHtml = await this.boundComponent(VideoRow)( relatedVideos )
|
||||
|
||||
// const rowHtml = renderedRow.join('')
|
||||
|
|
@ -96,14 +99,9 @@ class TV {
|
|||
return /* html */`
|
||||
<section class="container pb-16">
|
||||
<div class="flex flex-col items-center text-center space-y-6">
|
||||
<div class="video-canvas w-screen flex flex-col justify-center items-center bg-black pt-16" style="left:50%;right:50%;margin-left:-50vw;margin-right:-50vw;">
|
||||
<div class="ratio-wrapper w-full max-w-4xl">
|
||||
<div class="relative overflow-hidden w-full pb-16/9">
|
||||
<iframe id="youtube-player-${ video.id }-17212" src="https://www.youtube-nocookie.com/embed/${ video.id }?enablejsapi=1&autoplay=1&modestbranding=1&playsinline=1" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen class="absolute h-full w-full"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
|
||||
${ playerHtml }
|
||||
|
||||
<div class="md:flex w-full justify-between space-y-4 md:space-y-0 md:px-10">
|
||||
<h1 class="title text-lg md:text-2xl font-bold">${ video.name }</h1>
|
||||
<div class="channel-credit"><a href="https://www.youtube.com/channel/UCptwuAv0XQHo1OQUSaO6NHw" target="_blank" rel="noopener" role="button" class="relative inline-flex items-center rounded-md px-4 py-2 leading-5 font-bold text-white border border-transparent focus:outline-none focus:border-indigo-600 neumorphic-shadow focus:shadow-outline-indigo bg-darker hover:bg-indigo-400 active:bg-indigo-600 transition duration-150 ease-in-out">Subscribe to Max Tech</a></div>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue