Merge pull request #14 from innocuous-symmetry/video-player
Video player
This commit is contained in:
@@ -64,6 +64,19 @@ img, video {
|
|||||||
color: rgb(97, 49, 95);
|
color: rgb(97, 49, 95);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gallery-statement {
|
||||||
|
color: rgb(228, 180, 226);
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-statement a {
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gallery-statement a:active {
|
||||||
|
color:rgb(97, 49, 95);
|
||||||
|
}
|
||||||
|
|
||||||
.num-comments {
|
.num-comments {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
background-color: #7196be;
|
background-color: #7196be;
|
||||||
@@ -80,6 +93,20 @@ img, video {
|
|||||||
color:rgb(228, 180, 226);
|
color:rgb(228, 180, 226);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Video player */
|
||||||
|
|
||||||
|
.video-player {
|
||||||
|
display: inline-flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#post-audio {
|
||||||
|
position: relative;
|
||||||
|
height: 3.5rem;
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
|
||||||
/* Handles comment styles on toggle */
|
/* Handles comment styles on toggle */
|
||||||
|
|
||||||
.comments-visible {
|
.comments-visible {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
// import { useDispatch } from "react-redux";
|
|
||||||
import Discussion from "../discussion/Discussion";
|
import Discussion from "../discussion/Discussion";
|
||||||
|
import VideoPlayer from "../video/VideoPlayer";
|
||||||
import './Post.css';
|
import './Post.css';
|
||||||
|
|
||||||
export default function Post({data, key}) {
|
export default function Post({data, key}) {
|
||||||
@@ -14,11 +14,6 @@ export default function Post({data, key}) {
|
|||||||
let media = data.post_hint === 'image' && data.url;
|
let media = data.post_hint === 'image' && data.url;
|
||||||
let permalink = data.permalink;
|
let permalink = data.permalink;
|
||||||
let selftext = data.selftext;
|
let selftext = data.selftext;
|
||||||
let video = data.is_video ? `${data.url}/DASH_1080.mp4` : null; // to do: handle media edge cases, especially video
|
|
||||||
|
|
||||||
// fallback_url: "https://v.redd.it/0rditq5l49g81/DASH_1080.mp4?source=fallback"
|
|
||||||
// url: "https://v.redd.it/0rditq5l49g81"
|
|
||||||
// id: "sm2wym"
|
|
||||||
|
|
||||||
const limit = 300;
|
const limit = 300;
|
||||||
const [body, setBody] = useState(selftext);
|
const [body, setBody] = useState(selftext);
|
||||||
@@ -75,7 +70,7 @@ export default function Post({data, key}) {
|
|||||||
if (data.crosspost_parent_list[0].is_video) {
|
if (data.crosspost_parent_list[0].is_video) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<video controls src={data.crosspost_parent_list[0].media.reddit_video.fallback_url}>This video is not supported by your browser.</video>
|
<VideoPlayer data={data} src={data.crosspost_parent_list[0].url} />
|
||||||
<p className="crosspost-from">Crosspost from {data.crosspost_parent_list[0].subreddit_name_prefixed}</p>
|
<p className="crosspost-from">Crosspost from {data.crosspost_parent_list[0].subreddit_name_prefixed}</p>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
@@ -90,6 +85,10 @@ export default function Post({data, key}) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render function below:
|
||||||
|
// Each is preceded by a conditional so the program does not throw an error
|
||||||
|
// before the fetch requests' promises are fulfilled.
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -99,23 +98,17 @@ export default function Post({data, key}) {
|
|||||||
<a className="title" href={`https://reddit.com${permalink}`}>{title}</a>
|
<a className="title" href={`https://reddit.com${permalink}`}>{title}</a>
|
||||||
: <p>[untitled]</p>}
|
: <p>[untitled]</p>}
|
||||||
|
|
||||||
{media ? <img alt={title} src={media} /> : ''}
|
{media ? <img alt={title} src={media} /> : null}
|
||||||
{data.crosspost_parent_list ? handleCrosspost() : ''}
|
|
||||||
|
{data.crosspost_parent_list ? handleCrosspost() : null}
|
||||||
|
|
||||||
{data.gallery_data ?
|
{data.gallery_data ?
|
||||||
<p>View the gallery of photos corresponding to this post <a href={data.url}>here</a>.</p>
|
<p className="gallery-statement">View the gallery of photos corresponding to this post <a href={data.url}>here</a>.</p>
|
||||||
: null}
|
: null}
|
||||||
|
|
||||||
{video ?
|
{data.is_video ?
|
||||||
<video
|
<VideoPlayer data={data} />
|
||||||
controls
|
: null}
|
||||||
poster={data.thumbnail}
|
|
||||||
preload="auto"
|
|
||||||
src={video}>
|
|
||||||
|
|
||||||
Your video is not supported by the browser.
|
|
||||||
</video>
|
|
||||||
: ''}
|
|
||||||
|
|
||||||
{body ?
|
{body ?
|
||||||
<p onMouseOver={handleHover} onMouseOut={handleMouseOut}>{body}</p>
|
<p onMouseOver={handleHover} onMouseOut={handleMouseOut}>{body}</p>
|
||||||
|
|||||||
90
src/features/video/VideoPlayer.js
Normal file
90
src/features/video/VideoPlayer.js
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
import { useState, useEffect, useRef } from 'react';
|
||||||
|
|
||||||
|
export default function VideoPlayer({data, src}) {
|
||||||
|
const vidControls = useRef();
|
||||||
|
const vid = useRef();
|
||||||
|
const aud = useRef(); // identifies location of video/audio in DOM
|
||||||
|
|
||||||
|
const [playing, setPlaying] = useState(false); // handles play/pause logic
|
||||||
|
const [audio, setAudio] = useState(null);
|
||||||
|
|
||||||
|
const crossPostSrc = src;
|
||||||
|
|
||||||
|
let url; // contains video source, routed accordingly by logic below
|
||||||
|
|
||||||
|
if (crossPostSrc) {
|
||||||
|
url = crossPostSrc; // ... for crossposts
|
||||||
|
} else if (data.url) {
|
||||||
|
url = data.url; // ... for local posts, where the url
|
||||||
|
} else { // can be accessed at data.url
|
||||||
|
url = null; // otherwise, is null
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => { // checks the endpoint where audio may be found
|
||||||
|
let checking = true; // if the fetch request throws an error, audio is set to null;
|
||||||
|
const checkForAudio = async() => { // otherwise, audio is set to the endpoint, which is evaluated
|
||||||
|
try { // below as truthy, and rendered in the page
|
||||||
|
await fetch(`${url}/DASH_audio.mp4`)
|
||||||
|
.then((response) => {
|
||||||
|
let status = response.status;
|
||||||
|
if (status > 400) {
|
||||||
|
setAudio(null);
|
||||||
|
} else {
|
||||||
|
setAudio(`${url}/DASH_audio.mp4`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch(e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checking) {
|
||||||
|
checkForAudio();
|
||||||
|
checking = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
checking = false;
|
||||||
|
}
|
||||||
|
}, [url, audio]);
|
||||||
|
|
||||||
|
useEffect(() => { // this section handles simultaneous playback of audio and video
|
||||||
|
if (!audio) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (playing) {
|
||||||
|
vid.current.play(); // synchronizes play/pause between two components
|
||||||
|
vid.current.currentTime = aud.current.currentTime; // according to section of state
|
||||||
|
} else if (!playing) {
|
||||||
|
vid.current.pause();
|
||||||
|
}
|
||||||
|
}, [playing, audio, aud, vid]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="video-player">
|
||||||
|
|
||||||
|
{
|
||||||
|
!audio ?
|
||||||
|
|
||||||
|
<>
|
||||||
|
<video id="post-video-no-audio" ref={vidControls} controls src={`${url}/DASH_1080.mp4` || `${url}/DASH_1080.mp4?source=fallback`}>
|
||||||
|
This video is not supported by your browser.
|
||||||
|
</video>
|
||||||
|
</>
|
||||||
|
|
||||||
|
:
|
||||||
|
|
||||||
|
<>
|
||||||
|
<video id="post-video" ref={vid} autoPlay={playing ? true : false} src={`${url}/DASH_1080.mp4`}>
|
||||||
|
This video is not supported by your browser.
|
||||||
|
</video>
|
||||||
|
<video id="post-audio" ref={aud} controls onPlay={() => setPlaying(true)} onPause={() => setPlaying(false)} src={audio}>
|
||||||
|
This video is not supported by your browser.
|
||||||
|
</video>
|
||||||
|
</>
|
||||||
|
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user