embed improvements

- autoplay=true param
- mute on autoplay
- thumb poster on embeds (unless autoplay)
- twitter player card for audio too
This commit is contained in:
jessop 2020-02-04 16:14:08 -05:00 committed by Sean Yesmunt
parent 9defd7cd22
commit 9f1d4e3688
3 changed files with 49 additions and 18 deletions

View file

@ -88,7 +88,10 @@ function buildClaimOgMetadata(uri, claim, overrideOptions = {}) {
// below should be canonical_url, but not provided by chainquery yet // below should be canonical_url, but not provided by chainquery yet
head += `<meta property="og:url" content="${URL}/${claim.name}:${claim.claim_id}"/>`; head += `<meta property="og:url" content="${URL}/${claim.name}:${claim.claim_id}"/>`;
if (claim.source_media_type && claim.source_media_type.startsWith('video/')) { if (
claim.source_media_type &&
(claim.source_media_type.startsWith('video/') || claim.source_media_type.startsWith('audio/'))
) {
const videoUrl = generateEmbedUrl(claim.name, claim.claim_id); const videoUrl = generateEmbedUrl(claim.name, claim.claim_id);
head += `<meta property="og:video" content="${videoUrl}" />`; head += `<meta property="og:video" content="${videoUrl}" />`;
head += `<meta property="og:video:secure_url" content="${videoUrl}" />`; head += `<meta property="og:video:secure_url" content="${videoUrl}" />`;

View file

@ -5,15 +5,22 @@ import { selectVolume, selectMute } from 'redux/selectors/app';
import { savePosition, doSetPlayingUri } from 'redux/actions/content'; import { savePosition, doSetPlayingUri } from 'redux/actions/content';
import { makeSelectContentPositionForUri } from 'redux/selectors/content'; import { makeSelectContentPositionForUri } from 'redux/selectors/content';
import VideoViewer from './view'; import VideoViewer from './view';
import { withRouter } from 'react-router';
const select = (state, props) => ({ const select = (state, props) => {
volume: selectVolume(state), const { search } = props.location;
position: makeSelectContentPositionForUri(props.uri)(state), const urlParams = new URLSearchParams(search);
muted: selectMute(state), const autoplay = urlParams.get('autoplay');
hasFileInfo: Boolean(makeSelectFileInfoForUri(props.uri)(state)), return {
thumbnail: makeSelectThumbnailForUri(props.uri)(state), autoplayParam: autoplay,
claim: makeSelectClaimForUri(props.uri)(state), volume: selectVolume(state),
}); position: makeSelectContentPositionForUri(props.uri)(state),
muted: selectMute(state),
hasFileInfo: Boolean(makeSelectFileInfoForUri(props.uri)(state)),
thumbnail: makeSelectThumbnailForUri(props.uri)(state),
claim: makeSelectClaimForUri(props.uri)(state),
};
};
const perform = dispatch => ({ const perform = dispatch => ({
changeVolume: volume => dispatch(doChangeVolume(volume)), changeVolume: volume => dispatch(doChangeVolume(volume)),
@ -22,7 +29,9 @@ const perform = dispatch => ({
setPlayingUri: uri => dispatch(doSetPlayingUri(uri)), setPlayingUri: uri => dispatch(doSetPlayingUri(uri)),
}); });
export default connect( export default withRouter(
select, connect(
perform select,
)(VideoViewer); perform
)(VideoViewer)
);

View file

@ -29,6 +29,8 @@ type VideoJSOptions = {
playbackRates: Array<number>, playbackRates: Array<number>,
responsive: boolean, responsive: boolean,
poster?: string, poster?: string,
muted?: boolean,
poseter?: string,
}; };
const VIDEO_JS_OPTIONS: VideoJSOptions = { const VIDEO_JS_OPTIONS: VideoJSOptions = {
controls: true, controls: true,
@ -52,18 +54,34 @@ type Props = {
hasFileInfo: boolean, hasFileInfo: boolean,
onEndedCB: any, onEndedCB: any,
claim: Claim, claim: Claim,
autoplayParam: ?boolean,
}; };
function VideoViewer(props: Props) { function VideoViewer(props: Props) {
const { contentType, source, onEndedCB, changeVolume, changeMute, volume, muted, thumbnail, claim } = props; const {
contentType,
source,
onEndedCB,
changeVolume,
changeMute,
volume,
muted,
thumbnail,
claim,
autoplayParam,
} = props;
const claimId = claim && claim.claim_id; const claimId = claim && claim.claim_id;
const videoRef = useRef(); const videoRef = useRef();
const isAudio = contentType.includes('audio'); const isAudio = contentType.includes('audio');
const embedded = useContext(EmbedContext); const embedded = useContext(EmbedContext);
if (embedded) { if (embedded && !autoplayParam) {
VIDEO_JS_OPTIONS.autoplay = false; VIDEO_JS_OPTIONS.autoplay = false;
} }
if (autoplayParam) {
VIDEO_JS_OPTIONS.muted = true;
}
let forceTypes = [ let forceTypes = [
'video/quicktime', 'video/quicktime',
'application/x-ext-mkv', 'application/x-ext-mkv',
@ -128,14 +146,15 @@ function VideoViewer(props: Props) {
plugins: { eventTracking: true }, plugins: { eventTracking: true },
}; };
if (isAudio) { // thumb looks bad in app, and if autoplay, flashing poster is annoying
if (isAudio || (embedded && !autoplayParam)) {
videoJsOptions.poster = thumbnail; videoJsOptions.poster = thumbnail;
} }
if (!requireRedraw) { if (!requireRedraw) {
player = videojs(videoNode, videoJsOptions, function() { player = videojs(videoNode, videoJsOptions, function() {
player.volume(volume); if (!autoplayParam) player.volume(volume);
player.muted(muted); player.muted(autoplayParam || muted);
}); });
} }