opentok-react icon indicating copy to clipboard operation
opentok-react copied to clipboard

OTPublisher rapid videoSource change errors

Open ber8749 opened this issue 6 years ago • 6 comments

Hello,

I have stumbled upon a scenario in which the OTPublisher component generates a number of JavaScript console errors as a result of rapidly changing the videoSource property between different devices. The errors I am encountering are detailed below:

  • OpenTok:Publisher:warn The publisher 85712da5-0f62-4955-983d-bf878250ecbd is trying to unpublish from a session valid-session-id it is not attached to (it is attached to no session)
  • OpenTok:Publisher:error onStreamAvailableError Error: Did not pass Error as second argument: function(e,t,n){if(-1===a.indexOf(e))return new Error("Attempt to use invalid error name ("+e+"). Original message: "+t.message);if(!(t instanceof Error||/^\[object .*Error\]$/.test(Object.prototype.toString.call(t))))return new Error("Did not pass Error as second argument: "+t);var r=new o(void 0,t.message);if(r.name=e,!t.stack)try{throw t}catch(e){}return r.stack=t.stack,n&&(r.code=n),i.send(r),r}
  • OpenTok:Publisher:error OT.Publisher State Change Failed: 'Destroyed' cannot transition to 'Failed'
  • OpenTok:Publisher:warn Received connectivity event: "Failure" without "Attempt"
  • OpenTok:GlobalExceptionHandler:error OT.exception :: title: Unable to Publish (1500) msg: GetUserMedia

I am currently using macOS Mojave v.10.14.6 (18G103) and Chrome Version 76.0.3809.132.

I am currently using both my internal MacBook FaceTime camera and a generic USB camera. It appears as though at least 2 different cameras are necessary to replicate this issue, I was not able to replicate it with a single camera.

You can reproduce this error using the code below. Simply click on the "Cycle Camera" button multiple times in quick succession until you start seeing JavaScript errors in your console:

import React from "react";
import ReactDOM from "react-dom";
import { OTSession, OTPublisher } from "opentok-react";

class App extends React.Component {
  state = {
    audioSource: undefined,
    videoSource: undefined
  };

  getDeviceIds = (kind) => {
    const deviceIds = this.devices
      .filter(device => device.kind === kind)
      .map(device => device.deviceId);
    return deviceIds;
  }

  componentDidMount() {
    window.OT.getDevices((error, devices) => {
      if (error) {
        console.log('getDevices error:', error);
        return;
      }
      this.devices = devices;
      this.audioDeviceIds = this.getDeviceIds('audioInput');
      this.videoDeviceIds = this.getDeviceIds('videoInput');
      this.audioIndex = 0;
      this.videoIndex = 0;
    }); 
  }

  cycleCamera = () => {    
    const videoSource = this.videoDeviceIds[this.videoIndex];
    this.setState({ videoSource });   
    this.videoIndex = this.videoIndex === this.videoDeviceIds.length ? 0 : this.videoIndex + 1; 
  }

  cycleMicrophone = () => {
    const audioSource = this.audioDeviceIds[this.audioIndex];
    this.setState({ audioSource });
    this.audioIndex = this.audioIndex === this.audioDeviceIds.length ? 0 : this.audioIndex + 1;
  }

  render() {
    return (
      <div className="App">
        <h1>OTPublisher Device Test</h1>
        <button
          onClick={ this.cycleCamera }
        >
          Cycle Camera
        </button>
        <button
          onClick={ this.cycleMicrophone }
        >
          Cycle Microphone
        </button>
        
         <OTSession
           apiKey="valid-api-key" 
           sessionId="valid-session-id" 
           token="valid-session-token"
         >
           <OTPublisher 
            properties={
              {
                audioSource: this.state.audioSource,
                videoSource: this.state.videoSource
              }
            }
           />
         </OTSession>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

OR, simply modify directly on CodeSandbox:

Edit OTPublisher Device Error

I am very interested in know if there is any way I can prevent these errors from happening.

Thank you!

ber8749 avatar Oct 15 '19 19:10 ber8749

@ber8749 Hi! Did you solve this issue?

franzus5 avatar Nov 15 '19 10:11 franzus5

Hello @franzus5,

No, unfortunately I have not yet been able to resolve this issue.

I have created a sample app with the code above to hopefully assist anyone who is interested in helping to resolve this issue:

Edit OTPublisher Device Error

ber8749 avatar Nov 15 '19 12:11 ber8749

This is related to https://github.com/opentok/opentok-react/blob/master/src/OTPublisher.js#L38. 🤔

enricop89 avatar Jun 24 '20 14:06 enricop89

Related to this code, I've had a similar issue switching between screen sharing and camera on Chrome Windows where the whole browser would freeze. Worked around it by setting maxResolution = {width: 1920, height: 1080} for the screen sharing video source as Tokbox support reported a problem with Chrome Windows hardware acceleration that should be fixed in Chrome 83 when switching off screen sharing. For me limiting the resolution solved the issue even with Chrome 81. This might or might not be related to the issue, but it would probably be worth a try as it seemed to me the issue is related to the browser, not the opentok-react library.

ttraenkler avatar Jun 24 '20 14:06 ttraenkler

@ttraenkler thanks for the comment but the screen sharing freezing issue is not related to this one (it's a Chrome issue).

The issue above is related to the quick sequence calls of destroyPublisher and createPublisher on https://github.com/opentok/opentok-react/blob/master/src/OTPublisher.js#L38

enricop89 avatar Jun 25 '20 12:06 enricop89

i got freezing issue in mobile device. i have implemented opentok in ionic 5. please help.

sunilmanipara avatar Apr 22 '21 11:04 sunilmanipara