...
1. Обертка для кода
createControls() code
Функция-обертка для вызова из основной логики, ограничивает область видимости
...
2. Создание объекта controls
Создание объекта controls, содержащего все HTML элементы для настройки. Здесь же инициализируются таблицы для настройки публикации дорожек.
...
3. Заполнение полей модального окна входа
Заполнение полей модального окна входа в соответствии с текущей конфигурацией
...
4. Добавление новых аудио дорожек в объект controls
addAudioTrackRow() code
Добавление новых аудиодорожек и оповещение основного модуля
Code Block | ||||
---|---|---|---|---|
| ||||
const addAudioTrackRow = async function(track) { const stream = await getMedia([track]).then(function(stream){; let button = '<button id="' + stream.id + '-button" class="btn btn-primary">Delete</button>'; const row = controls.tables.audio.row.add({ source: track.source, channels: track.channels, action: button, stream: stream }).node(); controls.tables.audio.draw(); $('#' + stream.id + "-button").on('click', function(){ //terminate stream console.log("terminate audio stream " + stream.id); let track = stream.getAudioTracks()[0]; track.stop(); track.dispatchEvent(new Event("ended")); }).prop('disabled', true); stream.getTracks()[0].onended = function() { controls.tables.audio.row(row).remove().draw(); } trackCallback({ stream: stream, encodings: track.encodings, source: track.source, }); type: track.type }); } |
Запрос локального медиа через WebRTC API
Code Block | ||||
---|---|---|---|---|
| ||||
getMedia(const stream = await getMedia([track]).then(function(stream){; |
Добавление аудио дорожки в таблицу дорожек
...
Code Block | ||||
---|---|---|---|---|
| ||||
let button = '<button id="' + stream.id + '-button" class="btn btn-primary">Delete</button>'; const row = controls.tables.audio.row.add({ source: track.source, channels: track.channels, action: button, stream: stream }).node(); controls.tables.audio.draw(); |
Подписка на событие "click". По нажатию кнопки "Delete" дорожка останавливается, генерируется событие "ended"
Code Block | ||||
---|---|---|---|---|
| ||||
$('#' + stream.id + "-button").on('click', function(){ //terminate stream console.log("terminate audio stream " + stream.id); let track = stream.getAudioTracks()[0]; track.stop(); track.dispatchEvent(new Event("ended")); });.prop('disabled', true); |
Подписка на событие "ended" и очистка таблицы при получении данного события
...
Code Block | ||||
---|---|---|---|---|
| ||||
trackCallback({ stream: stream, encodings: track.encodings, source: track.source, type: track.type }); |
5. Добавление новых видео дорожек
addVideoTrackRow() code
Добавление новых видео дорожек и оповещение основного модуля, аналогично функции addAudioTrackRow.
Code Block | ||||
---|---|---|---|---|
| ||||
const addVideoTrackRow = const addVideoTrackRow = async function(track) { const stream = await getMedia([track]).then(function(stream){; let button = '<button id="' + stream.id + '-button" class="btn btn-primary">Delete</button>'; const row = controls.tables.video.row.add({ source: track.source, width: track.width, height: track.height, codec: track.codec, action: button, stream: stream, encodings: track.encodings, }).node(); controls.tables.video.draw(); $('#' + stream.id + "-button").on('click', function(){ //terminate stream console.log("terminate video stream " + stream.id); let track = stream.getVideoTracks()[0]; track.stop(); track.dispatchEvent(new Event("ended")); }).prop('disabled', true); stream.getTracks()[0].addEventListener("ended", function() { controls.tables.video.row(row).remove().draw(); }); trackCallback({ stream: stream, encodings: track.encodings, }); source: track.source }); } |
6. Форматирование настроек кодирования видео
format() code
Вспомогательная функция форматирует настройки кодирования видео для их отображения в таблице
Code Block | ||||
---|---|---|---|---|
| ||||
const format = function(d) { if (!d.encodings) { return; } let details = '<table cellpadding="5" cellspacing="0" border="0" style="padding-left:50px;">'; d.encodings.forEach(function(encoding){ details += '<tr>'; for (const [key, value] of Object.entries(encoding)) { details += '<td>'+ key + '</td>'+ '<td>'+ value + '</td>'; } details += '</tr>'; }); details +='</table>'; return details; } |
7.
...
Добавление обработчика для того, чтобы показать или спрятать данные видео дорожки
...
Отображение таблиц аудио и видео дорожек
displayTables() code
Code Block | ||||
---|---|---|---|---|
| ||||
const displayTables = async function() { // Add event listener for opening and closing details $('#videoTracksTableBody').on('click', 'td.details-control', function () { let tr = $(this).closest('tr'); let row = controls.tables.video.row(tr); if (row.child.isShown()) { // This row is already open - close it row.child. row.child.hide(); tr.removeClass('shown'); } else { // Open this row row.child(format(row.data())).show(); tr.addClass('shown'); } }); |
8. Добавление аудио дорожек в таблицу
Добавление всех настроенных аудио дорожек в таблицу
Code Block | ||||
---|---|---|---|---|
| ||||
}); // Add preconfigured audio and video tracks for (const track of config.media.audio.tracks.forEach(function(track){ addAudioTrackRow(track); }) |
9. Добавление видео дорожек в таблицу
Добавление всех настроенных видео дорожек в таблицу
Code Block | ||||
---|---|---|---|---|
| ||||
config.media.video.tracks.forEach(function(track){
addVideoTrackRow(track);
}) |
...
) {
await addAudioTrackRow(track);
}
for (const track of config.media.video.tracks) {
await addVideoTrackRow(track);
}
// Click event listener to add a new video track
document.getElementById("addVideoTrack").addEventListener("click", function(e){
let encodings = [];
controls.tables.encodings.rows().every(function() {
let encoding = this.data();
encodings.push({
rid: encoding.rid,
active: encoding.active,
maxBitrate: encoding.maxBitrate,
scaleResolutionDownBy: encoding.resolutionScale
})
});
let track = {
source: controls.addVideoTrack.source.value,
width: controls.addVideoTrack.width.value,
height: controls.addVideoTrack.height.value,
codec: controls.addVideoTrack.codec.value,
encodings: encodings
}
addVideoTrackRow(track);
});
// Click event listener to remove video quality
$("#videoTrackEncodingsTable").on("click", ".remove", function(){
controls.tables.encodings.row($(this).parents('tr')).remove().draw();
});
// Click event listener to add video quality
document.getElementById("addVideoTrackEncoding").addEventListener("click", function(){
let button = '<button class="btn btn-primary remove">Delete</button>';
controls.tables.encodings.row.add({
rid: controls.addVideoEncoding.rid.value,
active: controls.addVideoEncoding.active.value,
maxBitrate: controls.addVideoEncoding.maxBitrate.value,
resolutionScale: controls.addVideoEncoding.resolutionScale.value,
action: button
}).draw();
});
// Click event listener to add a new audio track
document.getElementById("addAudioTrack").addEventListener("click", function(e){
let encodings = [];
let track = {
source: controls.addAudioTrack.source.value,
channels: controls.addAudioTrack.channels.value,
encodings: encodings
}
addAudioTrackRow(track);
});
}
|
7.1. Добавление обработчика для отображения/скрытия данных дорожки
Добавление обработчика для того, чтобы показать или спрятать данные видео дорожки
Code Block | ||||
---|---|---|---|---|
| ||||
$('#videoTracksTableBody').on('click', 'td.details-control', function () {
let tr = $(this).closest('tr');
let row = controls.tables.video.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
} else {
// Open this row
row.child(format(row.data())).show();
tr.addClass('shown');
}
}); |
7.2. Добавление аудио и видео дорожек из файла конфигурации в таблицу
Добавление всех настроенных аудио дорожек в таблицу
Code Block | ||||
---|---|---|---|---|
| ||||
// Add preconfigured audio and video tracks
for (const track of config.media.audio.tracks) {
await addAudioTrackRow(track);
}
for (const track of config.media.video.tracks) {
await addVideoTrackRow(track);
} |
7.3. Добавление новых видео дорожек в таблицу
Добавление всех настроенных видео дорожек в таблицу
Code Block | ||||
---|---|---|---|---|
| ||||
// Click event listener to add a new video track
document.getElementById("addVideoTrack").addEventListener("click", function(e){
let encodings = [];
controls.tables.encodings.rows().every(function() {
let encoding = this.data();
encodings.push({
rid: encoding.rid,
active: encoding.active,
maxBitrate: encoding.maxBitrate,
scaleResolutionDownBy: encoding.resolutionScale
})
});
let track = {
source: controls.addVideoTrack.source.value,
width: controls.addVideoTrack.width.value,
height: controls.addVideoTrack.height.value,
codec: controls.addVideoTrack.codec.value,
encodings: encodings
}
addVideoTrackRow(track);
}); |
7.4. Добавление новых аудио дорожек в таблицу
Добавление всех настроенных видео дорожек в таблицу
Code Block | ||||
---|---|---|---|---|
| ||||
// Click event listener to add a new audio track
document.getElementById("addAudioTrack").addEventListener("click", function(e){
let encodings = [];
let track = {
source: controls.addAudioTrack.source.value,
channels: controls.addAudioTrack.channels.value,
encodings: encodings
}
addAudioTrackRow(track);
}); |
8. Отключение элементов формы
muteForm() code
Вспомогательная функция, отключающая все элементы указанной формы
Code Block | ||||
---|---|---|---|---|
| ||||
const muteForm = function(form) { for (const [key, value] of Object.entries(form)) { value.disabled = true; } } |
...
9. Включение элементов формы
unmuteForm() code
Вспомогательная функция, включающая все элементы указанной формы
Code Block | ||||
---|---|---|---|---|
| ||||
const unmuteForm = function(form) { for (const [key, value] of Object.entries(form)) { value.disabled = false; } } |
...
10. Отключение полей ввода модального окна входа
muteInput() code
Вспомогательная функция, отключающая поля ввода в модальном окне
Code Block | ||||
---|---|---|---|---|
| ||||
const muteInput = function() { muteForm(controls.entrance); } |
...
11. Создание объекта конфигурации комнаты
roomConfig() code
Функция собирает объект конфигурации комнаты
Code Block | ||||
---|---|---|---|---|
| ||||
const roomConfig = function() { let roomConfig return= { url: controls.entrance.url.value, roomName: controls.entrance.roomName.value, pin: controls.entrance.roomPin.value, nickname: controls.entrance.nickName.value } } |
14. Получение локальных видео дорожек
getVideoStreams() code
Функция возвращает все локальные видео дорожки
Code Block | ||||
---|---|---|---|---|
| ||||
const getVideoStreams = function() {}; let streams = []; controls.tables.video.rows().every(function(rowIdx, tableLoop, rowLoop if (config.room.failedProbesThreshold !== undefined) { let dataroomConfig.failedProbesThreshold = this.data()config.room.failedProbesThreshold; streams.push({} if (config.room.pingInterval !== undefined) stream: data.stream, { roomConfig.pingInterval encodings: data.encodings= config.room.pingInterval; }); return })roomConfig; return streams; } |
...
12. Получение локальных
...
видео дорожек
getAudioStreamsgetVideoStreams() code
Функция возвращает все локальные аудио видео дорожки
Code Block | ||||
---|---|---|---|---|
| ||||
const getAudioStreamsgetVideoStreams = function() { let streams = []; controls.tables.audiovideo.rows().every(function(rowIdx, tableLoop, rowLoop) { rowLoop) { let data = this.data(); streams.push({ let data =stream: this.data();data.stream, streams.push({ encodings: data.encodings, streamsource: data.streamsource, encodingstype: [] data.type }); }); return streams; } |
16. Обработчик для добавления видео дорожки в таблицу
...
13. Получение локальных аудио дорожек
getAudioStreams() code
Функция возвращает все локальные аудио дорожки
Code Block | ||||
---|---|---|---|---|
| ||||
document.getElementById("addVideoTrack").addEventListener("click", function(e){ const let encodingsgetAudioStreams = []; controls.tables.encodings.rows().every(function() { let encodingstreams = this.data(); encodings.push({[]; controls.tables.audio.rows().every(function(rowIdx, tableLoop, rowLoop) { rid: encoding.rid, let data active:= encoding.active,this.data(); maxBitrate: encoding.maxBitrate, streams.push({ scaleResolutionDownBy stream: encodingdata.resolutionScalestream, }) }); let track = { encodings: [], source: controls.addVideoTrack.source.value, widthsource: controls.addVideoTrack.width.value,data.source height: controls.addVideoTrack.height.value, }); codec: controls.addVideoTrack.codec.value, }); encodings: encodings return }streams; addVideoTrackRow(track); }); |
17. Обработчик для удаления параметров кодирования видео из таблицы
...
14. Передача callback функции новым дорожкам
Функция передает указанную callback функцию новым дорожкам
Code Block | ||||
---|---|---|---|---|
| ||||
$("#videoTrackEncodingsTable").on("click", ".remove",const onTrack = function(callback) { controls.tables.encodings.row($(this).parents('tr')).remove().draw()trackCallback = callback; }); |
...
15. Экспорт функций
codeДобавление
параметров кодирования видео в таблицуЭкспорт функций для использования в основном модуле
Code Block | ||||
---|---|---|---|---|
| ||||
document.getElementById("addVideoTrackEncoding").addEventListener("click", function() return { let button = '<button class="btn btn-primary remove">Delete</button>'; controls.tables.encodings.row.add({ muteInput: muteInput, roomConfig: roomConfig, riddisplayTables: controls.addVideoEncoding.rid.valuedisplayTables, activegetAudioStreams: controls.addVideoEncoding.active.valuegetAudioStreams, maxBitrategetVideoStreams: controls.addVideoEncoding.maxBitrate.valuegetVideoStreams, resolutionScaleonTrack: controls.addVideoEncoding.resolutionScale.valueonTrack, actioncleanTables: buttoncleanTables }).draw(); }); |
19. Обработчик для добавления аудио дорожки в таблицу
...
16. Получение медиа потоков из WebRTC API
getMedia() code
Запрос списка локальных медиа потоков от WebRTC API
Code Block | ||||
---|---|---|---|---|
| ||||
document.getElementById("addAudioTrack").addEventListener("click",const getMedia = async function(etracks) { let//convert encodings = [];to constraints let trackscreen = {false; const constraints= {}; source: controls.addAudioTrack.source.value,tracks.forEach(function(track){ channels:if controls.addAudioTrack.channels.value, (track.source === "mic") { encodings: encodings } addAudioTrackRow(track); }); |
20. Передача callback функции новым дорожкам
Функция передает указанную callback функцию новым дорожкам
Code Block | ||||
---|---|---|---|---|
| ||||
const onTrack = function(callback) { //audio trackCallback = callback; } |
21. Экпорт функций
Экспорт функций для использования в основном модуле
Code Block | ||||
---|---|---|---|---|
| ||||
return { constraints.audio = {}; muteInput: muteInput, roomConfig: roomConfig,if (track.constraints) { getAudioStreams: getAudioStreams, getVideoStreams: getVideoStreams, onTrack: onTrack } |
22. Получение медиа потоков из WebRTC API
getMedia() code
Запрос списка локальных медиа потоков от WebRTC API
Code Block | ||||
---|---|---|---|---|
| ||||
const getMedia = async function(tracks) { constraints.audio = track.constraints; //convert to constraints} let screen = false; const constraints.audio.stereo = track.channels !== {};1 tracks.forEach(function(track){ if (track.sourcechannels && track.channels === "mic"2) { //audio constraints.audio.echoCancellation = {}false; constraints.audio.stereogoogEchoCancellation = track.channels !== 1 false; } } else if (track.source === "camera") { constraints.video = {}; if (track.constraints) { width:constraints.video = track.width,constraints; } height: constraints.video.width = track.heightwidth; constraints.video.height = }track.height; } else if (track.source === "screen") { constraints.video = {}; if (track.constraints) { width: constraints.video = track.width, constraints; } height: constraints.video.width = track.heightwidth; }constraints.video.height = track.height; screen = true; } }); //get access to a/v let stream; if (screen) { stream = await navigator.mediaDevices.getDisplayMedia(constraints); } else { stream = await navigator.mediaDevices.getUserMedia(constraints); } return stream; } |
...