moesh
moesh

Reputation: 319

How can I use wistia inline player with react?

I am trying to load in an inline video player from wistia, and the docs say to use this code :

<script src="https://fast.wistia.com/embed/medias/<hashedid>.jsonp" async></script><script src="https://fast.wistia.com/assets/external/E-v1.js" async></script><div class="wistia_responsive_padding" style="padding:56.0% 0 0 0;position:relative;"><div class="wistia_responsive_wrapper" style="height:100%;left:0;position:absolute;top:0;width:100%;"><div class="wistia_embed wistia_async_<hashedid> videoFoam=true" style="height:100%;width:100%">&nbsp;</div></div></div>

I have changed the style syntax to jsx as well as class to className * see below

        <script src="https://fast.wistia.com/embed/medias/<hashed_id>.jsonp" async></script>
        <script src="https://fast.wistia.com/assets/external/E-v1.js" async></script>
        <div className="wistia_responsive_padding" style={{padding:"56.0% 0 0 0",position:"relative"}}>
        <div className="wistia_responsive_wrapper" style={{height:"100%",left:0,position:"absolute",top:0,width:"100%"}}>
        <div className="wistia_embed wistia_async_<hashed_id> videoFoam=true" style={{height:"100%",width:"100%"}}>

Still this isn't letting the browser render the player, I believe this may be due to the script tags, but am not sure how to fix this. How can I make my video appear? * Note if I was to use regular html that inline video player would work for me & also I can't use the iframe code because that uses htm l5 player for mobile devices rather than wistia (atleast when I tried it)

Upvotes: 4

Views: 6411

Answers (3)

Polshgiant
Polshgiant

Reputation: 3664

Here's a function component version based on Wistia's template (as of September 2023) in case anyone is interested:

import { useEffect, useRef } from "react";

export default function WistiaEmbed({
  videoId,
  width = undefined, // Wistia's default is no width specified
  responsive = true,
  padding = "56.25% 0 0", // Wistia's default
}: {
  videoId: string;
  width?: string;
  padding?: string;
  responsive?: boolean;
  
}) {
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (containerRef.current == null) { return; }

    const script1 = document.createElement("script");

    script1.src = `https://fast.wistia.com/embed/medias/${videoId}.jsonp`;
    script1.async = true;
    containerRef.current.append(script1);

    const script2 = document.createElement("script");
    script2.src = "https://fast.wistia.com/assets/external/E-v1.js";
    script2.async = true;
    containerRef.current.append(script2);

    // Shouldn't need cleanup...React should cleanup automatically
    // since the script tags are in the component
    // return () => {
    //   script1.remove();
    //   script2.remove();
    // };
  }, [videoId]);

  if (!responsive) {
    return <div ref={containerRef}
      className={`wistia_embed wistia_async_${videoId}`}
      style={{
        height: '366px',
        width: '600px',
      }}>
      &nbsp;
    </div>;
  }

  return (
    <div
      ref={containerRef}
      className="wistia_responsive_padding"
      style={{
        padding: padding,
        position: "relative",
        width: width,
      }}>
      <div
        className="wistia_responsive_wrapper"
        style={{
          position: "absolute",
          height: "100%",
          left: 0,
          top: 0,
          width: "100%",
        }}>
        <div
          className={`wistia_embed wistia_async_${videoId} videoFoam=true`}
          style={{
            height: "100%",
            position: "relative",
            width: "100%",
          }}>
          <div
            className="wistia_swatch"
            style={{
              height: "100%",
              left: 0,
              opacity: 0,
              overflow: "hidden",
              position: "absolute",
              top: 0,
              transition: "opacity 200ms",
              width: "100%",
            }}>
            <img
              src={`https://fast.wistia.com/embed/medias/${videoId}/swatch`}
              style={{
                filter: "blur(5px)",
                height: "100%",
                objectFit: "contain",
                width: "100%",
              }}
              alt=""
              aria-hidden="true"
              onLoad={(e) => {
                (e.target as any).parentNode.style.opacity = 1;
              }}
            />
          </div>
        </div>
      </div>
    </div>
  );
}

Upvotes: 2

Marshall Moutenot
Marshall Moutenot

Reputation: 121

Here is a more up to date component you can use. The hashedId is a prop.

import React, {Component} from 'react';

class WistiaEmbed extends Component {
  constructor(props) {
    super(props);
    const {hashedId, ...embedOptions} = {...this.props};
    if (typeof window !== `undefined`) {
      window._wq = window._wq || [];
      window._wq.push({
        id: hashedId,
        options: embedOptions,
        onHasData: (video) => {
          this.handle = video;
        },
      });
    }
  }

  _renderCommon() {
    const {hashedId} = this.props;
    return (
      <div
        class="wistia_swatch"
        style={{
          height: '100%',
          left: 0,
          opacity: 0,
          overflow: 'hidden',
          position: 'absolute',
          top: 0,
          transition: 'opacity 200ms',
          width: '100%',
        }}
      >
        <img
          src={`https://fast.wistia.com/embed/medias/${hashedId}/swatch`}
          style={{filter: 'blur(5px)', height: '100%', objectFit: 'contain', width: '100%'}}
          alt=""
          aria-hidden="true"
          onload="this.parentNode.style.opacity=1;"
        />
      </div>
    );
  }

  _renderResponsive() {
    const {hashedId, padding} = this.props;

    return (
      <div className="wistia_responsive_padding" style={{padding, position: 'relative'}}>
        <div
          className="wistia_responsive_wrapper"
          style={{height: '100%', left: '0', position: 'absolute', top: 0, width: '100%'}}
        >
          <div
            className={`wistia_embed wistia_async_${hashedId} videoFoam=true`}
            style={{height: '100%', width: '100%', position: 'relative'}}
          >
            {this._renderCommon()}
          </div>
        </div>
      </div>
    );
  }

  _renderFixed() {
    const {width, height, hashedId} = this.props;
    return (
      <div
        class={`wistia_embed wistia_async_${hashedId}`}
        style={`height:${height || 480}px;position:relative;width:${width || 640}px`}
      >
        {this._renderCommon()}
      </div>
    );
  }

  render() {
    const {isResponsive} = this.props;
    return isResponsive ? this._renderResponsive() : this._renderFixed;
  }

  componentDidMount() {
    if (!document.getElementById('wistia_script')) {
      var wistiaScript = document.createElement('script');
      wistiaScript.id = 'wistia_script';
      wistiaScript.type = 'text/javascript';
      wistiaScript.src = 'https://fast.wistia.com/assets/external/E-v1.js';
      wistiaScript.async = true;
      document.body.appendChild(wistiaScript);
    }
  }

  componentWillUnmount() {
    this.handle && this.handle.remove();
  }
}

WistiaEmbed.defaultProps = {
  isResponsive: true,
};

export default WistiaEmbed;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Upvotes: 2

Novia Lim
Novia Lim

Reputation: 261

Create a separate component and import it.

export default
class YourVideo extends React.Component {

componentWillMount() {
    const script1 = document.createElement("script");
    const script2 = document.createElement("script");

    script1.src = "https://fast.wistia.com/embed/medias/videolink.jsonp";
    script1.async = true;

    script2.src = "https://fast.wistia.com/assets/external/E-v1.js";
    script2.async = true;

    document.body.appendChild(script1);
    document.body.appendChild(script2);
}

render() {
    return (
        <div>
            <div className="wistia_embed wistia_async_videolink videoFoam=true"/>
        </div>
        );
    };
}

Upvotes: 14

Related Questions