diff --git a/openvidu-react/README.md b/openvidu-react/README.md index 1ebe379f..a0ca6146 100644 --- a/openvidu-react/README.md +++ b/openvidu-react/README.md @@ -1,27 +1 @@ -# React + TypeScript + Vite - -This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules. - -Currently, two official plugins are available: - -- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh -- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh - -## Expanding the ESLint configuration - -If you are developing a production application, we recommend updating the configuration to enable type aware lint rules: - -- Configure the top-level `parserOptions` property like this: - -```js - parserOptions: { - ecmaVersion: 'latest', - sourceType: 'module', - project: ['./tsconfig.json', './tsconfig.node.json'], - tsconfigRootDir: __dirname, - }, -``` - -- Replace `plugin:@typescript-eslint/recommended` to `plugin:@typescript-eslint/recommended-type-checked` or `plugin:@typescript-eslint/strict-type-checked` -- Optionally add `plugin:@typescript-eslint/stylistic-type-checked` -- Install [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) and add `plugin:react/recommended` & `plugin:react/jsx-runtime` to the `extends` list +# openvidu-react diff --git a/openvidu-react/src/App.js b/openvidu-react/src/App.js deleted file mode 100644 index b7259f17..00000000 --- a/openvidu-react/src/App.js +++ /dev/null @@ -1,350 +0,0 @@ -import { OpenVidu } from 'openvidu-browser'; - -import axios from 'axios'; -import React, { Component } from 'react'; -import './App.css'; -import UserVideoComponent from './UserVideoComponent'; - -const APPLICATION_SERVER_URL = process.env.NODE_ENV === 'production' ? '' : 'https://demos.openvidu.io/'; - -class App extends Component { - constructor(props) { - super(props); - - // These properties are in the state's component in order to re-render the HTML whenever their values change - this.state = { - mySessionId: 'SessionA', - myUserName: 'Participant' + Math.floor(Math.random() * 100), - session: undefined, - mainStreamManager: undefined, // Main video of the page. Will be the 'publisher' or one of the 'subscribers' - publisher: undefined, - subscribers: [], - }; - - this.joinSession = this.joinSession.bind(this); - this.leaveSession = this.leaveSession.bind(this); - this.switchCamera = this.switchCamera.bind(this); - this.handleChangeSessionId = this.handleChangeSessionId.bind(this); - this.handleChangeUserName = this.handleChangeUserName.bind(this); - this.handleMainVideoStream = this.handleMainVideoStream.bind(this); - this.onbeforeunload = this.onbeforeunload.bind(this); - } - - componentDidMount() { - window.addEventListener('beforeunload', this.onbeforeunload); - } - - componentWillUnmount() { - window.removeEventListener('beforeunload', this.onbeforeunload); - } - - onbeforeunload(event) { - this.leaveSession(); - } - - handleChangeSessionId(e) { - this.setState({ - mySessionId: e.target.value, - }); - } - - handleChangeUserName(e) { - this.setState({ - myUserName: e.target.value, - }); - } - - handleMainVideoStream(stream) { - if (this.state.mainStreamManager !== stream) { - this.setState({ - mainStreamManager: stream - }); - } - } - - deleteSubscriber(streamManager) { - let subscribers = this.state.subscribers; - let index = subscribers.indexOf(streamManager, 0); - if (index > -1) { - subscribers.splice(index, 1); - this.setState({ - subscribers: subscribers, - }); - } - } - - joinSession() { - // --- 1) Get an OpenVidu object --- - - this.OV = new OpenVidu(); - - // --- 2) Init a session --- - - this.setState( - { - session: this.OV.initSession(), - }, - () => { - var mySession = this.state.session; - - // --- 3) Specify the actions when events take place in the session --- - - // On every new Stream received... - mySession.on('streamCreated', (event) => { - // Subscribe to the Stream to receive it. Second parameter is undefined - // so OpenVidu doesn't create an HTML video by its own - var subscriber = mySession.subscribe(event.stream, undefined); - var subscribers = this.state.subscribers; - subscribers.push(subscriber); - - // Update the state with the new subscribers - this.setState({ - subscribers: subscribers, - }); - }); - - // On every Stream destroyed... - mySession.on('streamDestroyed', (event) => { - - // Remove the stream from 'subscribers' array - this.deleteSubscriber(event.stream.streamManager); - }); - - // On every asynchronous exception... - mySession.on('exception', (exception) => { - console.warn(exception); - }); - - // --- 4) Connect to the session with a valid user token --- - - // Get a token from the OpenVidu deployment - this.getToken().then((token) => { - // First param is the token got from the OpenVidu deployment. Second param can be retrieved by every user on event - // 'streamCreated' (property Stream.connection.data), and will be appended to DOM as the user's nickname - mySession.connect(token, { clientData: this.state.myUserName }) - .then(async () => { - - // --- 5) Get your own camera stream --- - - // Init a publisher passing undefined as targetElement (we don't want OpenVidu to insert a video - // element: we will manage it on our own) and with the desired properties - let publisher = await this.OV.initPublisherAsync(undefined, { - audioSource: undefined, // The source of audio. If undefined default microphone - videoSource: undefined, // The source of video. If undefined default webcam - publishAudio: true, // Whether you want to start publishing with your audio unmuted or not - publishVideo: true, // Whether you want to start publishing with your video enabled or not - resolution: '640x480', // The resolution of your video - frameRate: 30, // The frame rate of your video - insertMode: 'APPEND', // How the video is inserted in the target element 'video-container' - mirror: false, // Whether to mirror your local video or not - }); - - // --- 6) Publish your stream --- - - mySession.publish(publisher); - - // Obtain the current video device in use - var devices = await this.OV.getDevices(); - var videoDevices = devices.filter(device => device.kind === 'videoinput'); - var currentVideoDeviceId = publisher.stream.getMediaStream().getVideoTracks()[0].getSettings().deviceId; - var currentVideoDevice = videoDevices.find(device => device.deviceId === currentVideoDeviceId); - - // Set the main video in the page to display our webcam and store our Publisher - this.setState({ - currentVideoDevice: currentVideoDevice, - mainStreamManager: publisher, - publisher: publisher, - }); - }) - .catch((error) => { - console.log('There was an error connecting to the session:', error.code, error.message); - }); - }); - }, - ); - } - - leaveSession() { - - // --- 7) Leave the session by calling 'disconnect' method over the Session object --- - - const mySession = this.state.session; - - if (mySession) { - mySession.disconnect(); - } - - // Empty all properties... - this.OV = null; - this.setState({ - session: undefined, - subscribers: [], - mySessionId: 'SessionA', - myUserName: 'Participant' + Math.floor(Math.random() * 100), - mainStreamManager: undefined, - publisher: undefined - }); - } - - async switchCamera() { - try { - const devices = await this.OV.getDevices() - var videoDevices = devices.filter(device => device.kind === 'videoinput'); - - if (videoDevices && videoDevices.length > 1) { - - var newVideoDevice = videoDevices.filter(device => device.deviceId !== this.state.currentVideoDevice.deviceId) - - if (newVideoDevice.length > 0) { - // Creating a new publisher with specific videoSource - // In mobile devices the default and first camera is the front one - var newPublisher = this.OV.initPublisher(undefined, { - videoSource: newVideoDevice[0].deviceId, - publishAudio: true, - publishVideo: true, - mirror: true - }); - - //newPublisher.once("accessAllowed", () => { - await this.state.session.unpublish(this.state.mainStreamManager) - - await this.state.session.publish(newPublisher) - this.setState({ - currentVideoDevice: newVideoDevice[0], - mainStreamManager: newPublisher, - publisher: newPublisher, - }); - } - } - } catch (e) { - console.error(e); - } - } - - render() { - const mySessionId = this.state.mySessionId; - const myUserName = this.state.myUserName; - - return ( -
- {this.state.session === undefined ? ( -
-
- OpenVidu logo -
-
-

Join a video session

-
-

- - -

-

- - -

-

- -

-
-
-
- ) : null} - - {this.state.session !== undefined ? ( -
-
-

{mySessionId}

- - -
- - {this.state.mainStreamManager !== undefined ? ( -
- - -
- ) : null} -
- {this.state.publisher !== undefined ? ( -
this.handleMainVideoStream(this.state.publisher)}> - -
- ) : null} - {this.state.subscribers.map((sub, i) => ( -
this.handleMainVideoStream(sub)}> - {sub.id} - -
- ))} -
-
- ) : null} -
- ); - } - - - /** - * -------------------------------------------- - * GETTING A TOKEN FROM YOUR APPLICATION SERVER - * -------------------------------------------- - * The methods below request the creation of a Session and a Token to - * your application server. This keeps your OpenVidu deployment secure. - * - * In this sample code, there is no user control at all. Anybody could - * access your application server endpoints! In a real production - * environment, your application server must identify the user to allow - * access to the endpoints. - * - * Visit https://docs.openvidu.io/en/stable/application-server to learn - * more about the integration of OpenVidu in your application server. - */ - async getToken() { - const sessionId = await this.createSession(this.state.mySessionId); - return await this.createToken(sessionId); - } - - async createSession(sessionId) { - const response = await axios.post(APPLICATION_SERVER_URL + 'api/sessions', { customSessionId: sessionId }, { - headers: { 'Content-Type': 'application/json', }, - }); - return response.data; // The sessionId - } - - async createToken(sessionId) { - const response = await axios.post(APPLICATION_SERVER_URL + 'api/sessions/' + sessionId + '/connections', {}, { - headers: { 'Content-Type': 'application/json', }, - }); - return response.data; // The token - } -} - -export default App; diff --git a/openvidu-react/src/App.test.js b/openvidu-react/src/App.test.js deleted file mode 100644 index a754b201..00000000 --- a/openvidu-react/src/App.test.js +++ /dev/null @@ -1,9 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import App from './App'; - -it('renders without crashing', () => { - const div = document.createElement('div'); - ReactDOM.render(, div); - ReactDOM.unmountComponentAtNode(div); -}); diff --git a/openvidu-react/src/OvVideo.js b/openvidu-react/src/OvVideo.js deleted file mode 100644 index f0d48b1e..00000000 --- a/openvidu-react/src/OvVideo.js +++ /dev/null @@ -1,26 +0,0 @@ -import React, { Component } from 'react'; - -export default class OpenViduVideoComponent extends Component { - - constructor(props) { - super(props); - this.videoRef = React.createRef(); - } - - componentDidUpdate(props) { - if (props && !!this.videoRef) { - this.props.streamManager.addVideoElement(this.videoRef.current); - } - } - - componentDidMount() { - if (this.props && !!this.videoRef) { - this.props.streamManager.addVideoElement(this.videoRef.current); - } - } - - render() { - return