Skip to content

Instantly share code, notes, and snippets.

@neilgupta
Created July 20, 2020 13:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neilgupta/2368403736ce1b81570632f5973b9e87 to your computer and use it in GitHub Desktop.
Save neilgupta/2368403736ce1b81570632f5973b9e87 to your computer and use it in GitHub Desktop.
HLS-compatible video player
.VideoButtons {
text-align: center;
margin: 3em auto 5.5em auto;
}
.VideoButtons span {
margin: 1em;
}
@media only screen and (max-width: 550px) {
.VideoButtons span {
display: block;
margin: 2em auto;
}
}
#posterWrapper {
position: relative;
}
#posterWrapper:hover svg {
cursor: pointer;
}
#posterWrapper:hover path {
fill: #6F3CD1;
}
import React, { PureComponent } from 'react'
import Hls from 'hls.js'
import './styles.css'
import VideoPosterImg from '../images/VideoPosterImg'
import media from '../../media/HiomeDemo.mp4'
class Video extends PureComponent {
componentDidMount() {
const video = document.getElementById('heroVid')
const src = '/hls/WelcomeHiome.m3u8'
if (video.canPlayType('application/vnd.apple.mpegurl')) {
// native HLS support
video.src = src
} else if (Hls.isSupported()) {
// fallback to hls.js
const hls = new Hls();
hls.loadSource(src)
hls.attachMedia(video)
} else {
// fallback to downloading whole media file like a chump
video.src = media
}
}
getElementY(element) {
const el = element.getBoundingClientRect()
// center video in screen
return window.pageYOffset + el.top + (el.bottom - el.top)/2 - window.innerHeight/2
}
doScrolling(element, duration) {
const startingY = window.pageYOffset
const elementY = this.getElementY(element)
// If element is close to page's bottom then window will scroll only to some position above the element.
const targetY = document.body.scrollHeight - elementY < window.innerHeight ? document.body.scrollHeight - window.innerHeight : elementY
const diff = targetY - startingY
if (!diff) return
// Easing function: easeInOutCubic from https://gist.github.com/gre/1650294
const easing = (t) => ( t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1 )
let start
// Bootstrap our animation - it will get called right before next frame shall be rendered.
window.requestAnimationFrame(function step(timestamp) {
if (!start) start = timestamp
// Elapsed miliseconds since start of scrolling.
const time = timestamp - start
// Get percent of completion in range [0, 1].
let percent = Math.min(time / duration, 1)
// Apply the easing.
percent = easing(percent)
// Do the scroll.
window.scrollTo(0, startingY + diff * percent)
// Proceed to next step if there's time left.
if (time < duration) {
window.requestAnimationFrame(step)
}
})
}
play = () => {
this.playing()
this.doScrolling(document.getElementById("heroVid"), 1000)
}
playing = () => {
const poster = document.getElementById('posterWrapper')
const video = document.getElementById('heroVid')
poster.style.display = 'none'
video.style.display = 'block'
video.play()
const watchBtn = document.getElementById('watch')
watchBtn.style.transition = "background-color 1s ease-in-out, color 1s ease-in-out, border-color 1s ease-in-out"
watchBtn.classList.add('disabled')
}
renderButton() {
return (
<div className="VideoButtons">
<span>
<button id="watch" className="secondary" onClick={this.play}>Watch Video</button>
</span>
<span>
<a className="primary" href="/order" title="I'm ready to smarten my home!">Order Now</a>
</span>
</div>
)
}
render() {
return (
<>
{this.renderButton()}
<div id="posterWrapper" onClick={this.playing}>
<img src={VideoPosterImg} alt="Welcome Hiome" style={{
width: `100%`,
height: `auto`,
paddingBottom: `56.25%`,
boxShadow: `2px 2px 15px #ccc`,
backgroundColor: `#ccc`
}} />
<svg fill="#000" style={{
position: `absolute`,
top: `40%`,
left: `45%`,
width: `10%`
}} xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 100 100"><g><g><path d="M50,2.5C23.8,2.5,2.5,23.8,2.5,50S23.8,97.5,50,97.5c26.2,0,47.5-21.3,47.5-47.5S76.2,2.5,50,2.5z M65.3,52.4L42.9,67.3 c-1.9,1.3-4.5-0.1-4.5-2.4V35.1c0-2.3,2.6-3.7,4.5-2.4l22.4,14.9C67,48.7,67,51.3,65.3,52.4z"></path></g></g></svg>
</div>
<video controls width="100%" preload="auto" id="heroVid" style={{
boxShadow: `2px 2px 15px #ccc`,
marginBottom: `2rem`,
backgroundColor: `#ccc`,
display: `none`
}}>
Sorry, your browser doesn't support embedded videos. <a href="https://www.youtube.com/watch?v=PLBdi5frOGA">Watch it on YouTube</a>.
</video>
</>
)
}
}
export default Video
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment