vimeo / player.js

Interact with and control an embedded Vimeo Player.
https://player.vimeo.com/api/demo
MIT License
1.43k stars 261 forks source link

player methods not running on React Native Webview #808

Open isaac-tcs opened 2 years ago

isaac-tcs commented 2 years ago

Expected Behavior

const player = new Vimeo.Player(iframe);
player.on('pause', function (data) {
  alert("stop");
});

should show an alert. Or any method that player has should run.

Actual Behavior

player methods are not running

Steps to Reproduce

This is somewhat duplicate with #315 I am trying to get events from the player on my react native project but it seems like the methods are not working inside the react native's webview. I tested it using codepen and it works fine on the browser.

codepen: https://codepen.io/isaac-tcs/pen/jOaGmXz

Below is my code that I changed some part from https://github.com/MetaLabs-inc/react-native-vimeo-iframe

export default videoId => `
  <html><head>
  <title></title>
  <script src="https://player.vimeo.com/api/player.js"></script>
  </head>
  <body style="height: 100%; width: 100%;" data-new-gr-c-s-check-loaded="14.996.0" data-gr-ext-installed="" cz-shortcut-listen="true">

  <script>
  var PLAYER_ID = "player";
  function webViewBridge() {
    const vid = ${videoId};

    if (!vid) {
      return;
    }

    let iframe;
    iframe = document.createElement("iframe");
    iframe.src =
    'https://vimeo.com/event/' + vid + '/embed';
    iframe.width = "100%";
    iframe.height = "98%";
    iframe.frameBorder = "0";
    iframe.webkitallowfullscreen = true;
    iframe.allowfullscreen = true;
    iframe.mozallowfullscreen = true;
    iframe.allow="autoplay;fullscreen;"
    iframe.id = PLAYER_ID;
    document.body.appendChild(iframe);

    const player = new Vimeo.Player(iframe);

    setTimeout(()=> {                                   // it only shows the alert and won't pause
        alert("stoppppppp");
        player.pause();
    }, 5000);

    const sendEvent = (evt, data) => {
      var payload = {
        name: evt,
        data: data,
      };
        // window.ReactNativeWebView.postMessage(JSON.stringify(payload));
    };

    alert('load');                                 // it show alert

    player.pause().then(function() {
        alert('load');
    })

    player.on('loaded', function () {
        alert('load');                                                      // won't show
        player.on('play', function (data) {
            alert("llll");                                                 // won't show
            sendEvent("play", data);
        });

        player.on('pause', function (data) {
            alert("llll");                                                  // won't show
            sendEvent("pause", data);
        });

        player.on("playing", function (data) {
            sendEvent("playProgress", data);
        });

        player.on('ended', function (data) {
            sendEvent("finish", data);
        })

        sendEvent("ready");
    });

  }

  webViewBridge();
    </script>
  </body></html>
  `;
  const INJECTEDJAVASCRIPT =
    "const meta = document.createElement('meta'); meta.setAttribute('content', 'width=device-width, initial-scale=1, maximum-scale=0.99, user-scalable=0'); meta.setAttribute('name', 'viewport'); document.getElementsByTagName('head')[0].appendChild(meta);";

    <WebView
      allowsFullscreenVideo={true}
      onLoadEnd={() => console.log('live load enddddddddddddddddd')}
      source={{
        html: LivePlayer(videoId),
      }}
      javaScriptEnabled={true}
      ref={ref}
      onMessage={onBridgeMessage}
      bounces={false}
      scrollEnabled={false}
      scalesPageToFit={scalesPageToFit}
      onError={error => console.error(error)}
      style={[
        {
          marginTop: -8,
          marginLeft: -10,
        },
        style,
      ]}
      containerStyle={containerStyle}
      setBuiltInZoomControls={false}
      setDisplayZoomControls={false}
      automaticallyAdjustContentInsets
      onNavigationStateChange={a => console.log(a?.url)}
      injectedJavaScript={INJECTEDJAVASCRIPT}
    />
isaac-tcs commented 2 years ago

I tried below and again it worked fine on browser but not it webiew. I guess this is not the issue of this library rather react native webview.

        window.onmessage = function (event) {
          if (event.data.event == "play") {
            sendEvent(event.data.event, event.data.data);
          }
          if (event.data.event == "pause") {
            sendEvent(event.data.event, event.data.data);
          }
          if (event.data.event == "ready") {
            sendEvent(event.data.event, event.data.data);
          }
          if (event.data.event == "timeupdate") {
            sendEvent('playing', event.data.data);
          }
          if (event.data.event == "ended") {
            sendEvent('end', event.data.data);
          }
        };
mikniin commented 2 years ago

I am actually seeing the same with React app and live events on a webapp. Regular videos work nicely. I've been trying to change my own functionality from npm packaged player and oEmbed to the iframe approach as presented here, but no help. Live events (in our case, not recurring event) just cannot be controlled from javascript at all. No events, and play command doesn't work.

Right now only thing I can use to track if video is being played is to put the iframe in a "modal", connect on iframe load event and monitor when the modal is closed.

I will try to see if just plain html page and and CDN based player can track the events from player for live event.