diff --git a/.env.template b/.env.template index b1294e9..f453fa7 100644 --- a/.env.template +++ b/.env.template @@ -20,3 +20,8 @@ TURN_SERVER_CREDENTIAL=uWdWNmkhvyqTEswO # API API_KEY_SECRET=call_me_api_key_secret # change me + +# API endpoint for fetching random images (e.g., Unsplash or other services): https://unsplash.com/developers +# RANDOM_IMAGE_URL='https://api.unsplash.com/photos/random?query=nature&orientation=landscape&client_id=YOUR-ACCESS-KEY'; + +RANDOM_IMAGE_URL='' \ No newline at end of file diff --git a/README.md b/README.md index 2e0edbb..4a9b64a 100644 --- a/README.md +++ b/README.md @@ -10,17 +10,17 @@ This project enables easy one-to-one video calls directly from your web browser This project allows you to: -- `Sign in` with a username. -- `Make video calls` by entering the recipient's username. -- `Toggle` your video feed visibility. -- `Hang up` the call when done. -- `Rest API` to get all connected users. +- `Sign in` with a username. +- `Make video calls` by entering the recipient's username. +- `Toggle` your video feed visibility. +- `Hang up` the call when done. +- `Rest API` to get all connected users. --- ### Quick Start -- #### Using NodeJs +- #### Using NodeJs ![nodejs](public/assets/nodejs.png) @@ -45,7 +45,7 @@ npm start --- -- #### Using Docker +- #### Using Docker ![docker](public/assets/docker.png) @@ -92,6 +92,22 @@ Lets the `user2 join` the room and initiate a `call` to the `user1` --- +## Fast Integration + +![iframe](public/assets/iframe.png) + +Easily integrate `Call-Me` into your website or application with a [simple iframe](https://codepen.io/Miroslav-Pejic/pen/qEWBaKP). Just add the following code to your project: + +```html + +``` + +--- + ## API Get all connected users diff --git a/app/server.js b/app/server.js index cf55835..a6f770a 100755 --- a/app/server.js +++ b/app/server.js @@ -7,6 +7,7 @@ const fs = require('fs'); const http = require('http'); const https = require('https'); const socketIO = require('socket.io'); +const axios = require('axios'); const path = require('path'); const yaml = require('js-yaml'); const swaggerUi = require('swagger-ui-express'); @@ -31,6 +32,7 @@ const config = { turnServerUsername: process.env.TURN_SERVER_USERNAME, turnServerCredential: process.env.TURN_SERVER_CREDENTIAL, apiKeySecret: process.env.API_KEY_SECRET, + randomImageUrl: process.env.RANDOM_IMAGE_URL || '', apiBasePath: '/api/v1', swaggerDocument: yaml.load(fs.readFileSync(path.join(__dirname, '/api/swagger.yaml'), 'utf8')), }; @@ -117,6 +119,19 @@ app.get('/', (req, res) => { res.sendFile(HOME); }); +// Get Random Background Images +app.get('/randomImage', async (req, res) => { + if (config.randomImageUrl === '') return; // Keep client default bg image + + try { + const response = await axios.get(config.randomImageUrl); + const data = response.data; + res.send(data); + } catch (error) { + console.error('Error fetching image', error.message); + } +}); + // Direct Join room app.get('/join/', (req, res) => { if (Object.keys(req.query).length > 0) { diff --git a/doc/self-hosting.md b/doc/self-hosting.md index d46efa8..2cce202 100644 --- a/doc/self-hosting.md +++ b/doc/self-hosting.md @@ -4,13 +4,13 @@ ## Requirements -- Server Selection: - - [Hetzner](https://www.hetzner.com/cloud) (CX11) - Use [this link](https://hetzner.cloud/?ref=XdRifCzCK3bn) to receive `€⁠20 in cloud credits` - - [Contabo](https://www.dpbolvw.net/click-101027391-14462707) (VPS-1) -- OS: Ubuntu 22.04 LTS. -- [Node.js](https://nodejs.org/en/) (LTS) and npm -- Domain or Subdomain Name (e.g., `YOUR.DOMAIN.NAME`) with a DNS A record pointing to your server's IPv4 address. -- `Recommend` utilizing a [Turn Server](https://docs.mirotalk.com/coturn/stun-turn/) the installation documentation accessible [here](https://docs.mirotalk.com/coturn/installation/). +- Server Selection: + - [Hetzner](https://www.hetzner.com/cloud) (CX11) - Use [this link](https://hetzner.cloud/?ref=XdRifCzCK3bn) to receive `€⁠20 in cloud credits` + - [Contabo](https://www.dpbolvw.net/click-101027391-14462707) (VPS-1) +- OS: Ubuntu 22.04 LTS. +- [Node.js](https://nodejs.org/en/) (LTS) and npm +- Domain or Subdomain Name (e.g., `YOUR.DOMAIN.NAME`) with a DNS A record pointing to your server's IPv4 address. +- `Recommend` utilizing a [Turn Server](https://docs.mirotalk.com/coturn/stun-turn/) the installation documentation accessible [here](https://docs.mirotalk.com/coturn/installation/). --- diff --git a/package.json b/package.json index 7bc7137..22e5864 100755 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "call-me", - "version": "1.0.18", + "version": "1.0.19", "description": "Your Go-To for Instant Video Calls", "author": "Miroslav Pejic - miroslav.pejic.85@gmail.com", "license": "AGPLv3", @@ -19,6 +19,7 @@ "lint": "npx prettier --write ." }, "dependencies": { + "axios": "^1.7.8", "dotenv": "^16.4.5", "express": "^4.21.1", "js-yaml": "4.1.0", @@ -27,6 +28,6 @@ }, "devDependencies": { "nodemon": "^3.1.7", - "prettier": "3.3.3" + "prettier": "3.4.1" } } diff --git a/public/assets/iframe.png b/public/assets/iframe.png new file mode 100644 index 0000000..2729de1 Binary files /dev/null and b/public/assets/iframe.png differ diff --git a/public/client.js b/public/client.js index 117b23f..c15c21a 100755 --- a/public/client.js +++ b/public/client.js @@ -10,6 +10,7 @@ const socket = io(); const config = { iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] }; // DOM elements +const randomImage = document.querySelector('#randomImage'); const sessionTime = document.querySelector('#sessionTime'); const githubDiv = document.querySelector('#githubDiv'); const signInPage = document.querySelector('#signInPage'); @@ -32,12 +33,24 @@ let thisConnection; let stream; // On html page loaded... -document.addEventListener('DOMContentLoaded', function () { +document.addEventListener('DOMContentLoaded', async function () { + await fetchRandomImage(); handleToolTip(); handleLocalStorage(); handleDirectJoin(); }); +// Get Random Images +async function fetchRandomImage() { + try { + const response = await axios.get('/randomImage'); + const data = response.data; + randomImage.src = data.urls.regular; + } catch (error) { + console.error('Error fetching image', error.message); + } +} + // Initialize tooltips function handleToolTip() { const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-toggle="tooltip"]')); diff --git a/public/index.html b/public/index.html index 73a121d..bc3c8ab 100755 --- a/public/index.html +++ b/public/index.html @@ -39,6 +39,9 @@ + + +
+ + + diff --git a/public/style.css b/public/style.css index 0e173d5..806b6ad 100644 --- a/public/style.css +++ b/public/style.css @@ -20,14 +20,24 @@ body { right: 0; margin: 0; padding: 0; - width: 100%; - height: 100%; + width: 100vw; + height: 100vh; overflow: auto; } body { - background: url('background.jpg') center center/cover no-repeat; + display: flex; + justify-content: center; + align-items: center; background-attachment: fixed; /* Keeps the background in place during scroll */ + background: url('background.jpg') center center/cover no-repeat; +} + +/* Random image */ +img { + width: 100%; + height: 100%; + object-fit: cover; } /* Session Time */