[Разработка веб-сайтов, JavaScript, Программирование, Node.JS] Создание видеочата с помощью Node.js + Socket.io + WebRTC (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Сегодня, специально к старту нового потока по веб-разработке, поделимся с вами туториалом, из которого вы узнаете, как создать видеочат с помощью JavaScript и NodeJS. Также вы научитесь использовать PeerJS, WebRTC и Socket.io.Здесь вы можете увидеть живой пример приложения, которое вы будете создавать.Подготовка к проектуВот что вам понадобится:
- NodeJS: посетите официальный веб-сайт Node.js, чтобы загрузить и установить Node;
- NPM: программа NPM устанавливается на ваш компьютер при установке Node.js.
Настройка проектаВесь код этого проекта можно найти в репозитории GitHub.
- Создайте пустой каталог с именем video-chat-app.
- Откройте консоль, перейдите в наш новый каталог и запустите npm init.
- Заполните необходимую информацию для инициализации нашего проекта.
- Запустите npm install express ejs socket.io uuid peer. Команда установит все зависимости, необходимые для создания этого приложения.
- А также в качестве dev-зависимости установите Nodemon. Нужно выполнить npm install-dev nodemon. Это установит nodemon как dev-зависимость.
- Создайте файл server.js — в этом файле будет храниться вся ваша серверная логика.
Теперь, когда у вас настроен наш проект, вы можете приступить к созданию приложения!Создание сервера (с Express JS)Первое, что вам нужно сделать, — это запустить ваш сервер. Мы собираемся использовать для этого Express. Express — это минималистичный веб-фреймворк для Node.js. Express позволяет очень легко создавать и запускать веб-сервер с помощью Node.Давайте создадим шаблонный файл начального приложения Express.
// server.js
const express = require(“express”);
const app = express();
const server = require(“http”).Server(app);
app.get(“/”, (req, res) => {
res.status(200).send(“Hello World”);
});
server.listen(3030);
Теперь ваш сервер запущен, вы можете протестировать его, запустив:
> nodemon server.js
Теперь откройте свой браузер и перейдите по адресу: localhost:3000, вы должны увидеть Hello World.
Создание первой страницыВместо того чтобы выводить текст, когда кто-то посещает ваш корневой маршрут, вы хотели бы присылать HTML. Для этого нужно использовать EJS (встроенный JavaScript). EJS — это язык шаблонов.Чтобы использовать EJS в Express, вам нужно настроить ваш шаблонизатор. Для настройки добавьте эту строку кода в файл server.js.
app.set(‘view engine’, ‘ejs’)
Доступ к EJS по умолчанию осуществляется в каталоге views. Теперь создайте новую папку views в каталоге. В этой папке добавьте файл с именем room.ejs. Пока что думайте о нашем файле room.ejs как о HTML-файле.Вот как выглядит ваша файловая структура:
|-- video-chat-app
|-- views
|-- room.ejs
|-- package.json
|-- server.js
Теперь добавьте HTML-код в файл room.ejs.Извините, данный ресурс не поддреживается. :( Как только вы скопируете приведённый выше код, нужно немного поменять app.js:
app.get(‘/’, function (req, res) {
// OLD CODE
res.status(200).send("Hello World");
})
Выше приведён старый код, в котором вы отправляете клиенту текст «Hello World!». Вместо этого вы хотите отправить файл room.ejs:
app.get(‘/’, function (req, res) {
// NEW CODE
res.render(‘room’);
})
Теперь откройте браузер и перейдите по адресу: localhost:3030, и вы увидите, что отображается файл room.ejs!
Добавление CSSВыглядит не очень хорошо, правда? Это потому, что в вашем проекте нет стилей. Итак, добавьте немного CSS.Нам нужно будет добавить новую папку в проект под названием public. В этой папке создайте файлы style.css и script.js. Вот ваша новая файловая структура:
|-- weather-app
|-- views
|-- index.ejs
|-- public
|-- style.css
|-- script.js
|-- package.json
|-- server.js
Express не даёт доступа к этому файлу по умолчанию, поэтому вам нужно открыть его с помощью следующей строки кода:
app.use(express.static(‘public’));
Этот код позволяет вам получить доступ ко всем статическим файлам в папке “public”. Наконец, вам нужен CSS. Поскольку это не курс по CSS, я не буду вдаваться в подробности, но если вы хотите использовать мои стили, вы можете скопировать их отсюда.После того как вы добавили CSS, вы можете посетить: localhost:3030. Вы заметите, что приложение выглядит немного лучше.Настройка комнатК настоящему моменту ваш файл server.js должен выглядеть так:Извините, данный ресурс не поддреживается. :( У вас есть один GET-роут и запуск сервера. Однако, чтобы ваше приложение работало, нужно всякий раз, когда новый пользователь посещает ваш роут по умолчанию, перенаправлять его на уникальный URL-адрес. Следует использовать библиотеку uuid для создания случайного уникального URL-адреса для каждой комнаты.UUID — это библиотека javascript, которая позволяет вам создавать уникальные идентификаторы. В вашем приложении вы будете использовать uuid версии 4 для создания уникального URL. Но сначала импортируйте uuid в server.js.
const { v4: uuidv4 } = require("uuid");
Теперь нужно использовать uuid для создания случайного уникального идентификатора для каждой комнаты и перенаправлять пользователя в эту комнату.
app.get(“/”, (req, res) => {
res.redirect(`/${uuidv4()}`);
});
И, прежде чем вы протестируете это, я также хотел добавить страницу для каждой уникальной комнаты, и вы передадите текущий URL этой странице.
app.get(“/:room”, (req, res) => {
res.render(“room”, { roomId: req.param.room });
});
Вы передали roomId в room.ejs на этом закончили настройку ваших комнат. А теперь, если вы посетите localhost:3030, вы будете перенаправлены на уникальный URL.
Добавление видео пользователяВы будете работать с файлом script.js, который вы создали ранее. script.js будет содержать весь клиентский код приложения.Итак, вот что необходимо сделать: нужно получить видеопоток, а затем добавить этот поток в элемент видео.
let myVideoStream;
const videoGrid = document.getElementById("video-grid");
const myVideo = document.createElement("video");
myVideo.muted = true;
navigator.mediaDevices.getUserMedia({
audio: true,
video: true,
})
.then((stream) => {
myVideoStream = stream;
addVideoStream(myVideo, stream);
});
Теперь создайтем функцию addVideoStream, которая добавит поток к видеоэлементу.
const addVideoStream = (video, stream) => {
video.srcObject = stream;
video.addEventListener("loadedmetadata", () => {
video.play();
videoGrid.append(video);
});
};
Этот код добавит пользовательский поток к видеоэлементу. Вы можете проверить это, посетив localhost:3030, и вы увидите всплывающее окно с видео
Добавление возможности разрешить другим пользователям транслировать свои видео в потоковом режиме.Пришло время использовать Socket.io и PeerJS. Для тех, кто не знает, Socket.io позволяет взаимодействовать серверу и клиенту в режиме реального времени. PeerJS позволяют реализовать WebRTC.Сначала импортируйте socket.io и peerjs в server.js и прослушайте событие соединения.
// server.js
const express = require(“express”);
const app = express();
const server = require(“http”).Server(app);
const { v4: uuidv4 } = require(“uuid”);
app.set(“view engine”, “ejs”);
const io = require(“socket.io”)(server);
const { ExpressPeerServer } = require(“peer”);
const peerServer = ExpressPeerServer(server, {
debug: true,
});
app.use(“/peerjs”, peerServer);
app.use(express.static(“public”));
app.get(“/”, (req, res) => {
res.redirect(`/${uuidv4()}`);
});
app.get(“/:room”, (req, res) => {
res.render(“room”, { roomId: req.param.room });
});
io.on(“connection”, (socket) => {
socket.on(“join-room”, (roomId, userId) => {
socket.join(roomId);
socket.to(roomId).broadcast.emit(“user-connected”, userId);
});
});
server.listen(3030);
Теперь ваш сервер прослушивает событие присоединения к комнате. Далее настройте ваш script.js.
// public/script.js
const socket = io(“/”);
const videoGrid = document.getElementById(“video-grid”);
const myVideo = document.createElement(“video”);
myVideo.muted = true;
var peer = new Peer(undefined, {
path: “/peerjs”,
host: “/”,
port: “3030”,
});
let myVideoStream;
navigator.mediaDevices
.getUserMedia({
audio: true,
video: true,
})
.then((stream) => {
myVideoStream = stream;
addVideoStream(myVideo, stream);
peer.on(“call”, (call) => {
call.answer(stream);
const video = document.createElement(“video”);
call.on(“stream”, (userVideoStream) => {
addVideoStream(video, userVideoStream);
});
});
socket.on(“user-connected”, (userId) => {
connectToNewUser(userId, stream);
});
});
const connectToNewUser = (userId, stream) => {
const call = peer.call(userId, stream);
const video = document.createElement(“video”);
call.on(“stream”, (userVideoStream) => {
addVideoStream(video, userVideoStream);
});
};
peer.on(“open”, (id) => {
socket.emit(“join-room”, ROOM_ID, id);
});
const addVideoStream = (video, stream) => {
video.srcObject = stream;
video.addEventListener(“loadedmetadata”, () => {
video.play();
videoGrid.append(video);
});
};
Теперь, если в комнату войдёт новый пользователь, вы увидите его видео.Создание пользовательского интерфейсаС видеочастью закончили. А теперь займитесь стилизацией. Но сначала добавьте контент в файл room.ejs. (Добавьте CDN font-awesome внутри тега head.)
// views/room.ejs
<body>
<div class="header">
<div class="logo">
<h3>Video Chat</h2>
</div>
</div>
<div class="main">
<div class="main__left">
<div class="videos__group">
<div id="video-grid"></div>
</div>
<div class="options">
<div class="options__left">
<div class="options__button">
<i class="fa fa-video-camera" aria-hidden="true"></i>
</div>
<div class="options__button">
<i class="fa fa-microphone" aria-hidden="true"></i>
</div>
</div>
<div class="options__right">
<div class="options__button background__red">
<i class="fa fa-phone" aria-hidden="true"></i>
</div>
</div>
</div>
</div>
<div class="main__right">
<div class="main__chat_window">
<ul class="messages"></ul>
</div>
<div class="main__message_container">
<input id="chat_message" type="text" placeholder="Type message here...">
<div class="options__button">
<i class="fa fa-plus" aria-hidden="true"></i>
</div>
</div>
</div>
</div>
</body>
Затем откройте файл style.css и добавьте немного CSS.
@import url(“https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap");
:root {
— main-darklg: #1d2635;
— main-dark: #161d29;
— primary-color: #2f80ec;
— main-light: #eeeeee;
font-family: “Poppins”, sans-serif;
}
* {
margin: 0;
padding: 0;
}
.header {
display: flex;
justify-content: center;
align-items: center;
height: 8vh;
width: 100%;
background-color: var( — main-darklg);
}
.logo > h3 {
color: var( — main-light);
}
.main {
overflow: hidden;
height: 92vh;
display: flex;
}
.main__left {
flex: 0.7;
display: flex;
flex-direction: column;
}
.videos__group {
flex-grow: 1;
display: flex;
justify-content: center;
align-items: center;
padding: 1rem;
background-color: var( — main-dark);
}
video {
height: 300px;
border-radius: 1rem;
margin: 0.5rem;
width: 400px;
object-fit: cover;
transform: rotateY(180deg);
-webkit-transform: rotateY(180deg);
-moz-transform: rotateY(180deg);
}
.options {
padding: 1rem;
display: flex;
background-color: var( — main-darklg);
}
.options__left {
display: flex;
}
.options__right {
margin-left: auto;
}
.options__button {
display: flex;
justify-content: center;
align-items: center;
background-color: var( — primary-color);
height: 50px;
border-radius: 5px;
color: var( — main-light);
font-size: 1.2rem;
width: 50px;
margin: 0 0.5rem;
}
.background__red {
background-color: #f6484a;
}
.main__right {
flex: 0.3;
background-color: #242f41;
}
.main__chat_window {
flex-grow: 1;
}
.main__message_container {
padding: 1rem;
display: flex;
align-items: center;
justify-content: center;
}
.main__message_container > input {
height: 50px;
flex: 1;
border-radius: 5px;
padding-left: 20px;
border: none;
}
#video-grid {
display: flex;
justify-content: center;
flex-wrap: wrap;
}
Вот и всё! Поздравляем, вы успешно создали видеочат! Теперь вы можете развернуть его на Heroku и показать его всему миру. Демо и исходный код. Это лишь небольшой пример того, какие вещи может делать веб-разработчик, причем в одиночку. Сделать just for fun экспорт музыки в Spotify и получить известность, пока огромная компания долго думает над решением задачи — без проблем. За один вечер набросать и выкатить расширение для браузера, которое упростит жизнь миллионам пользователей — тоже по силам. На что еще способна веб-разработка — зависит только от фантазии программиста. Приходите учиться, чтобы освоить дзюцу веб-разработки и стать настоящим самураем интернета.
Узнайте, как прокачаться в других специальностях или освоить их с нуля:
- Профессия Fullstack-разработчик на Python
- Профессия C++ разработчик
- Профессия Java-разработчик
- Курс "Python для веб-разработки"
Другие профессии и курсыПРОФЕССИИ
- Профессия Data Scientist
- Профессия Data Analyst
- Профессия QA-инженер на JAVA
- Профессия Frontend-разработчик
- Профессия Этичный хакер
- Профессия C++ разработчик
- Профессия Разработчик игр на Unity
- Профессия Веб-разработчик
- Профессия iOS-разработчик с нуля
- Профессия Android-разработчик с нуля
КУРСЫ
- Курс по Data Engineering
- Курс по Machine Learning
- Курс "Machine Learning и Deep Learning"
- Курс "Математика для Data Science"
- Курс "Математика и Machine Learning для Data Science"
- Курс "Python для веб-разработки"
- Курс "Алгоритмы и структуры данных"
- Курс по аналитике данных
- Курс по DevOps
===========
Источник:
habr.com
===========
===========
Автор оригинала: Taran Arora
===========Похожие новости:
- [Ненормальное программирование, JavaScript] $mol_strict: Как же меня [object Object] этот ваш undefined NaN‼
- [Программирование, 1С] Законы робототехники сегодня
- [Программирование, Java] Java: передача параметров по значению или по ссылке (перевод)
- [Децентрализованные сети, Программирование микроконтроллеров, Умный дом, DIY или Сделай сам] Hello NXP Zigbee World
- [Программирование, Usability, Управление разработкой, Научно-популярное] Хорошие времена рождают слабаков (перевод)
- [Разработка веб-сайтов, Open source, Управление разработкой, Софт] Бесплатные сервисы для разработчиков — огромный список
- [Python, Программирование, Data Mining, Big Data, R] R vs Python в продуктивном контуре
- [Программирование, Промышленное программирование, Управление разработкой, Распределённые системы] Предварительная оптимизация — корень всех зол?
- [Читальный зал, Научно-популярное, Космонавтика] Знакомьтесь, первая вертушка на Марсе. Что же делает её такой… изобретательной (перевод)
- [Разработка веб-сайтов, .NET, ASP, C#, Микросервисы] Учим ASP.NET Core новым трюкам на примере Json Rpc 2.0
Теги для поиска: #_razrabotka_vebsajtov (Разработка веб-сайтов), #_javascript, #_programmirovanie (Программирование), #_node.js, #_skillfactory, #_node.js, #_socket.io, #_webrtc, #_javascript, #_css, #_html, #_express.js, #_programmirovanie (программирование), #_veb_razrabotka (веб разработка), #_blog_kompanii_skillfactory (
Блог компании SkillFactory
), #_razrabotka_vebsajtov (
Разработка веб-сайтов
), #_javascript, #_programmirovanie (
Программирование
), #_node.js
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 00:05
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Сегодня, специально к старту нового потока по веб-разработке, поделимся с вами туториалом, из которого вы узнаете, как создать видеочат с помощью JavaScript и NodeJS. Также вы научитесь использовать PeerJS, WebRTC и Socket.io.Здесь вы можете увидеть живой пример приложения, которое вы будете создавать.Подготовка к проектуВот что вам понадобится:
// server.js
const express = require(“express”); const app = express(); const server = require(“http”).Server(app); app.get(“/”, (req, res) => { res.status(200).send(“Hello World”); }); server.listen(3030); > nodemon server.js
Создание первой страницыВместо того чтобы выводить текст, когда кто-то посещает ваш корневой маршрут, вы хотели бы присылать HTML. Для этого нужно использовать EJS (встроенный JavaScript). EJS — это язык шаблонов.Чтобы использовать EJS в Express, вам нужно настроить ваш шаблонизатор. Для настройки добавьте эту строку кода в файл server.js. app.set(‘view engine’, ‘ejs’)
|-- video-chat-app
|-- views |-- room.ejs |-- package.json |-- server.js app.get(‘/’, function (req, res) {
// OLD CODE res.status(200).send("Hello World"); }) app.get(‘/’, function (req, res) {
// NEW CODE res.render(‘room’); }) Добавление CSSВыглядит не очень хорошо, правда? Это потому, что в вашем проекте нет стилей. Итак, добавьте немного CSS.Нам нужно будет добавить новую папку в проект под названием public. В этой папке создайте файлы style.css и script.js. Вот ваша новая файловая структура: |-- weather-app
|-- views |-- index.ejs |-- public |-- style.css |-- script.js |-- package.json |-- server.js app.use(express.static(‘public’));
const { v4: uuidv4 } = require("uuid");
app.get(“/”, (req, res) => {
res.redirect(`/${uuidv4()}`); }); app.get(“/:room”, (req, res) => {
res.render(“room”, { roomId: req.param.room }); }); Добавление видео пользователяВы будете работать с файлом script.js, который вы создали ранее. script.js будет содержать весь клиентский код приложения.Итак, вот что необходимо сделать: нужно получить видеопоток, а затем добавить этот поток в элемент видео. let myVideoStream;
const videoGrid = document.getElementById("video-grid"); const myVideo = document.createElement("video"); myVideo.muted = true; navigator.mediaDevices.getUserMedia({ audio: true, video: true, }) .then((stream) => { myVideoStream = stream; addVideoStream(myVideo, stream); }); const addVideoStream = (video, stream) => {
video.srcObject = stream; video.addEventListener("loadedmetadata", () => { video.play(); videoGrid.append(video); }); }; Добавление возможности разрешить другим пользователям транслировать свои видео в потоковом режиме.Пришло время использовать Socket.io и PeerJS. Для тех, кто не знает, Socket.io позволяет взаимодействовать серверу и клиенту в режиме реального времени. PeerJS позволяют реализовать WebRTC.Сначала импортируйте socket.io и peerjs в server.js и прослушайте событие соединения. // server.js
const express = require(“express”); const app = express(); const server = require(“http”).Server(app); const { v4: uuidv4 } = require(“uuid”); app.set(“view engine”, “ejs”); const io = require(“socket.io”)(server); const { ExpressPeerServer } = require(“peer”); const peerServer = ExpressPeerServer(server, { debug: true, }); app.use(“/peerjs”, peerServer); app.use(express.static(“public”)); app.get(“/”, (req, res) => { res.redirect(`/${uuidv4()}`); }); app.get(“/:room”, (req, res) => { res.render(“room”, { roomId: req.param.room }); }); io.on(“connection”, (socket) => { socket.on(“join-room”, (roomId, userId) => { socket.join(roomId); socket.to(roomId).broadcast.emit(“user-connected”, userId); }); }); server.listen(3030); // public/script.js
const socket = io(“/”); const videoGrid = document.getElementById(“video-grid”); const myVideo = document.createElement(“video”); myVideo.muted = true; var peer = new Peer(undefined, { path: “/peerjs”, host: “/”, port: “3030”, }); let myVideoStream; navigator.mediaDevices .getUserMedia({ audio: true, video: true, }) .then((stream) => { myVideoStream = stream; addVideoStream(myVideo, stream); peer.on(“call”, (call) => { call.answer(stream); const video = document.createElement(“video”); call.on(“stream”, (userVideoStream) => { addVideoStream(video, userVideoStream); }); }); socket.on(“user-connected”, (userId) => { connectToNewUser(userId, stream); }); }); const connectToNewUser = (userId, stream) => { const call = peer.call(userId, stream); const video = document.createElement(“video”); call.on(“stream”, (userVideoStream) => { addVideoStream(video, userVideoStream); }); }; peer.on(“open”, (id) => { socket.emit(“join-room”, ROOM_ID, id); }); const addVideoStream = (video, stream) => { video.srcObject = stream; video.addEventListener(“loadedmetadata”, () => { video.play(); videoGrid.append(video); }); }; // views/room.ejs
<body> <div class="header"> <div class="logo"> <h3>Video Chat</h2> </div> </div> <div class="main"> <div class="main__left"> <div class="videos__group"> <div id="video-grid"></div> </div> <div class="options"> <div class="options__left"> <div class="options__button"> <i class="fa fa-video-camera" aria-hidden="true"></i> </div> <div class="options__button"> <i class="fa fa-microphone" aria-hidden="true"></i> </div> </div> <div class="options__right"> <div class="options__button background__red"> <i class="fa fa-phone" aria-hidden="true"></i> </div> </div> </div> </div> <div class="main__right"> <div class="main__chat_window"> <ul class="messages"></ul> </div> <div class="main__message_container"> <input id="chat_message" type="text" placeholder="Type message here..."> <div class="options__button"> <i class="fa fa-plus" aria-hidden="true"></i> </div> </div> </div> </div> </body> @import url(“https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap");
:root { — main-darklg: #1d2635; — main-dark: #161d29; — primary-color: #2f80ec; — main-light: #eeeeee; font-family: “Poppins”, sans-serif; } * { margin: 0; padding: 0; } .header { display: flex; justify-content: center; align-items: center; height: 8vh; width: 100%; background-color: var( — main-darklg); } .logo > h3 { color: var( — main-light); } .main { overflow: hidden; height: 92vh; display: flex; } .main__left { flex: 0.7; display: flex; flex-direction: column; } .videos__group { flex-grow: 1; display: flex; justify-content: center; align-items: center; padding: 1rem; background-color: var( — main-dark); } video { height: 300px; border-radius: 1rem; margin: 0.5rem; width: 400px; object-fit: cover; transform: rotateY(180deg); -webkit-transform: rotateY(180deg); -moz-transform: rotateY(180deg); } .options { padding: 1rem; display: flex; background-color: var( — main-darklg); } .options__left { display: flex; } .options__right { margin-left: auto; } .options__button { display: flex; justify-content: center; align-items: center; background-color: var( — primary-color); height: 50px; border-radius: 5px; color: var( — main-light); font-size: 1.2rem; width: 50px; margin: 0 0.5rem; } .background__red { background-color: #f6484a; } .main__right { flex: 0.3; background-color: #242f41; } .main__chat_window { flex-grow: 1; } .main__message_container { padding: 1rem; display: flex; align-items: center; justify-content: center; } .main__message_container > input { height: 50px; flex: 1; border-radius: 5px; padding-left: 20px; border: none; } #video-grid { display: flex; justify-content: center; flex-wrap: wrap; } Узнайте, как прокачаться в других специальностях или освоить их с нуля:
=========== Источник: habr.com =========== =========== Автор оригинала: Taran Arora ===========Похожие новости:
Блог компании SkillFactory ), #_razrabotka_vebsajtov ( Разработка веб-сайтов ), #_javascript, #_programmirovanie ( Программирование ), #_node.js |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 00:05
Часовой пояс: UTC + 5