Skip to content

Commit

Permalink
chore: add open source code to telnyx video meet and add a new README…
Browse files Browse the repository at this point in the history
… with infos teaching how to run the code
  • Loading branch information
DeividVeloso committed Sep 23, 2021
1 parent ea4fbe8 commit bae6d97
Show file tree
Hide file tree
Showing 51 changed files with 11,176 additions and 2 deletions.
3 changes: 3 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
TELNYX_API_HOST=https://api.telnyx.com/v2
TELNYX_API_KEY=

25 changes: 25 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = {
env: {
browser: true,
es6: true,
node: true,
},
extends: ['eslint:recommended', 'plugin:react/recommended'],
globals: {
Atomics: 'readonly',
SharedArrayBuffer: 'readonly',
React: 'writable',
},
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 2018,
sourceType: 'module',
},
plugins: ['react'],
rules: {
'react/react-in-jsx-scope': 'off',
'no-unused-vars': 'warn',
},
};
38 changes: 38 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
yarn.lock

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local

# vercel
.vercel

# vscode
.vscode
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v14
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"singleQuote": true,
"jsxSingleQuote": true,
"arrowParens": "always"
}
92 changes: 90 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,90 @@
# telnyx-meet
Public video meet app example using @telnyx/video SDK
# Telnyx Meet App
Video meet app example using @telnyx/video SDK

## How it works?

This application demonstrates a simple interactive video conference
built using the [@telnyx/video](https://www.npmjs.com/package/@telnyx/video) SDK.

You can join in a video conference room and have a meeting with many participants publishing and subscribing to audio and video streams. You can also share your screen into the meeting.



## Getting Started

In this guide, you’ll learn how to get started with the Telnyx Meet App by using Telnyx SDKs and the Telnyx Portal.

Just follow these steps:

1. Sign up for a Telnyx Account
2. Create an API KEY
3. Create a Room ID
4. Run the code
5. Deploy on Vercel

---

## Step 1: Sign Up for a Telnyx Mission Control Portal Account

Head to [telnyx.com/sign-up](https://telnyx.com/sign-up) to sign up for your free Telnyx account.

It’ll give you access to our Mission Control Portal where you can set up and manage your API KEY, and more.


## Step 2: Create an API KEY

Go to [API Keys](https://portal.telnyx.com/#/app/api-keys) section and click on `Create API Key` button. It will generate a key for you. Copy and save this key in a safe place and don't share it with anyone it is a sensitive value.

You need this API Key to consume the API `https://api.telnyx.com/v2/rooms` to manage your room ids.

## ![create api key](screenshots/api-key.png)

## Step 3: Create a Room ID

You should read this documentation [video/Rooms](https://developers.telnyx.com/docs/api/v2/video/Rooms) to learn how to create a new video room id. When you get your `roomId` you can join in a video meet conference.

## Step 4: Run the code

After you have cloned this repo:

```bash
% git clone https://github.com/team-telnyx/telnyx-meet.git
```

Create a new copy of `.env.sample` with the name `.env.local` and set the env var `TELNYX_API_KEY` with your Telnyx API KEY value.

Your `.env.local` file should look like this:
```js
TELNYX_API_HOST=https://api.telnyx.com/v2
TELNYX_API_KEY="KEYae7df0................"
```

Run the commands

1 - `yarn` or `npm i` to install the dependencies.

2 - `yarn dev` or `npm run dev` will initialize the server.

3 - Access the `http://localhost:3000/rooms`

4 - Fill the input `Room UUID` with your generated `roomId` from step 3.

5 - Click on `Join Room` button to access the meeting.

## ![telnyx meet](screenshots/telnyx-meet.png)

## Step 5: Deploy on Vercel

You can deploy this app to the cloud with [Vercel](https://vercel.com) ([Documentation](https://nextjs.org/docs/deployment)).

#### **Deploy Your Local Project**

To deploy your local project to Vercel, push it to GitHub/GitLab/Bitbucket and [import to Vercel](https://vercel.com/new).

**Important**: When you import your project on Vercel, make sure to click on **Environment Variables** and set them to match your `.env.local` file.

#### **Deploy from Our Template**

Alternatively, you can deploy using our template by clicking on the Deploy button below.

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/team-telnyx/telnyx-meet.git&project-name=telnyx-meet&repository-name=telnyx-meet&env=TELNYX_API_HOST,TELNYX_API_KEY&envDescription=Required%20to%20connect%20the%20app%20with%20TelnyxMeet&envLink=https://vercel.link/cms-cosmic-env)
10 changes: 10 additions & 0 deletions components/AppHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Link from 'next/link';
import { Anchor, Header, Nav } from 'grommet';

export default function AppHeader({ ...unhandledProps }) {
return (
<Header pad='small' {...unhandledProps}>
<Anchor href='/' weight='bold' size='large' label='video meet' />
</Header>
);
}
61 changes: 61 additions & 0 deletions components/AudioTrack.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import React, { useRef, useEffect } from 'react';

export default function AudioTrack({
id,
audioTrack,
audioOutputDeviceId,
}: {
id: string;
audioTrack: MediaStreamTrack;
audioOutputDeviceId?: MediaDeviceInfo['deviceId'];
}) {
const mediaWrapperRef = useRef<HTMLDivElement>(null);

useEffect(() => {
if (!audioTrack || !mediaWrapperRef.current) {
return;
}

const audioEl = document.createElement('audio');
audioEl.id = `${id}-audio`;
audioEl.autoplay = true;

const mediaStream = new MediaStream([audioTrack]);

if (audioOutputDeviceId) {
console.debug('audioOutputDeviceId: ', audioOutputDeviceId);

// NOTE: Make sure the src is set before setSinkId!!!
audioEl.srcObject = mediaStream;

// @ts-expect-error
audioEl.setSinkId(audioOutputDeviceId).then(() => {
if (!mediaWrapperRef.current) {
return;
}

mediaWrapperRef.current.appendChild(audioEl);
// @ts-expect-error
console.debug('Audio output changed to ' + audioEl.sinkId);
});
} else {
audioEl.srcObject = mediaStream;
mediaWrapperRef.current.appendChild(audioEl);
console.debug('Audio output changed to default output');
}

return () => {
const existingAudioEl = document.getElementById(`${id}-audio`);
if (existingAudioEl) {
existingAudioEl.remove();
}

if (audioEl && audioEl.srcObject) {
audioEl.srcObject = null;
audioEl.remove();
}
};
}, [audioTrack, audioOutputDeviceId]);

return <div ref={mediaWrapperRef} />;
}
55 changes: 55 additions & 0 deletions components/ErrorDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from 'react';

import { Box, Button, Text, Layer, Heading } from 'grommet';
import { FormClose } from 'grommet-icons';

const ErrorDialog = ({
onClose,
title,
body,
}: {
onClose: (
event:
| React.MouseEvent<HTMLElement, MouseEvent>
| React.KeyboardEvent<HTMLElement>
) => void;
title: string;
body: string;
}) => {
return (
<Layer
position='center'
onClickOutside={onClose}
onEsc={onClose}
data-testid='room-controls-error'
>
<Box pad='medium' gap='small' width='medium'>
<Button alignSelf='end' icon={<FormClose />} onClick={onClose} />
<Heading level={3} margin='none'>
{title}
</Heading>
<Text>{body}</Text>
<Box
as='footer'
gap='small'
direction='row'
align='center'
justify='end'
pad={{ top: 'medium', bottom: 'small' }}
/>
<Button
label={
<Text color='white'>
<strong>Dismiss</strong>
</Text>
}
onClick={onClose}
primary
color='status-critical'
/>
</Box>
</Layer>
);
};

export default ErrorDialog;
Loading

0 comments on commit bae6d97

Please sign in to comment.