...
Code Block |
---|
|
const createDefaultMeetingModel = function (meetingView, participantFactory, displayOptions, abrFactory) {
return {
...
setMeetingName: function (id) {
this.meetingName = id;
meetingView.setMeetingName(id);
}
}
} |
5. Создание объекта для отображения потоков в комнате
createDefaultMeetingView() code
Code Block |
---|
|
const createDefaultMeetingView = function (entryPoint) {
...
} |
5.1. Инициализация HTML5 элементов
createDefaultMeetingView() code
Code Block |
---|
|
const createDefaultMeetingView = function (entryPoint) {
const rootDiv = document.createElement("div");
rootDiv.setAttribute("class", "grid-item");
entryPoint.appendChild(rootDiv);
const title = document.createElement("label");
title.setAttribute("style", "display:block; border: solid; border-width: 1px");
rootDiv.appendChild(title);
return {
...
}
} |
5.2. Инициализация списка элементов для отображения участников
participantViews() code
Code Block |
---|
|
const createDefaultMeetingView = function (entryPoint) {
...
return {
participantViews: new Map(),
...
}
} |
5.3. Отображение имени комнаты
setMeetingName() code
Code Block |
---|
|
const createDefaultMeetingView = function (entryPoint) {
...
return {
...
setMeetingName: function (id) {
title.innerText = "Meeting: " + id;
},
...
}
} |
5.4. Добавление элементов для отображения участника
addParticipant() code
Code Block |
---|
|
const createDefaultMeetingView = function (entryPoint) {
...
return {
...
addParticipant: function (userId, participantName, cell) {
const participantDiv = createContainer(rootDiv);
participantDiv.appendChild(cell);
this.participantViews.set(userId, participantDiv);
},
...
}
} |
5.5. Удаление элементов участника
removeParticipant() code
Code Block |
---|
|
const createDefaultMeetingView = function (entryPoint) {
...
return {
...
removeParticipant: function (userId) {
const cell = this.participantViews.get(userId);
if (cell) {
this.participantViews.delete(userId);
cell.remove();
}
},
...
}
} |
5.5. Удаление корневого элемента отображения
end() code
Code Block |
---|
|
const createDefaultMeetingView = function (entryPoint) {
...
return {
...
end: function () {
rootDiv.remove();
}
}
} |
6. Создание фабрики объектов участников
createParticipantFactory() code
Здесь содаются объекты модели, управления и отображения участника комнаты
Code Block |
---|
|
const createParticipantFactory = function (remoteTrackFactory, createParticipantView, createParticipantModel) {
return {
displayOptions: null,
abrFactory: null,
createParticipant: function (userId, nickname) {
const view = createParticipantView();
const model = createParticipantModel(userId, nickname, view, remoteTrackFactory, this.abrFactory, this.displayOptions);
const controller = createParticipantController(model);
return [model, view, controller];
}
}
} |
7. Создание объекта управления участником
createParticipantController() code
Объект вызывает соответствующие методы модели участника
Code Block |
---|
|
const createParticipantController = function (model) {
return {
addVideoTrack: function (track) {
model.addVideoTrack(track);
},
removeVideoTrack: function (track) {
model.removeVideoTrack(track);
},
addAudioTrack: function (track) {
model.addAudioTrack(track);
},
removeAudioTrack: function (track) {
model.removeAudioTrack(track);
},
updateQualityInfo: function (qualityInfo) {
model.updateQualityInfo(qualityInfo);
},
setNickname: function (nickname) {
model.setNickname(nickname);
},
dispose: function () {
model.dispose();
}
}
} |
8. Создание объекта модели участника в комнате с двумя участниками
createOneToOneParticipantModel() code
Code Block |
---|
|
const createOneToOneParticipantModel = function (userId, nickname, participantView, remoteTrackFactory, abrFactory, displayOptions) {
const instance = {
userId: userId,
nickname: nickname,
remoteVideoTracks: new Map(),
remoteAudioTracks: new Map(),
audioTracks: new Map(),
videoTracks: new Map(),
abrManagers: new Map(),
disposed: false,
dispose: async function () {
...
},
addVideoTrack: function (track) {
...
},
removeVideoTrack: function (track) {
...
},
addAudioTrack: function (track) {
...
},
removeAudioTrack: function (track) {
...
},
setUserId: function (userId) {
...
},
setNickname: function (nickname) {
...
},
updateQualityInfo: function (remoteTracks) {
...
},
requestVideoTrack: async function (track, remoteTrack) {
...
},
pickQuality: async function (track, qualityName) {
...
},
muteVideo: async function (track) {
...
},
unmuteVideo: async function (track) {
...
}
};
instance.setUserId(userId);
instance.setNickname(nickname);
return instance;
} |
8.1. Добавление видео дорожки для отображения
addVideoTrack() code
Code Block |
---|
|
const createOneToOneParticipantModel = function (userId, nickname, participantView, remoteTrackFactory, abrFactory, displayOptions) {
const instance = {
...
addVideoTrack: function (track) {
this.videoTracks.set(track.mid, track);
if (!track.quality) {
track.quality = [];
}
participantView.addVideoTrack(track);
const self = this;
remoteTrackFactory.getVideoTrack().then((remoteTrack) => {
if (remoteTrack) {
if (self.disposed || !self.videoTracks.get(track.mid)) {
remoteTrack.dispose();
return;
}
participantView.addVideoSource(remoteTrack.track, track, () => {
const abrManager = self.abrManagers.get(track.id);
if (!abrManager) {
return;
}
if (abrManager.isAuto()) {
abrManager.resume();
}
}, (mute) => {
if (mute) {
return self.muteVideo(track);
} else {
return self.unmuteVideo(track);
}
});
self.requestVideoTrack(track, remoteTrack).then(() => {
participantView.showVideoTrack(track);
}, (ex) => {
participantView.removeVideoSource(track);
remoteTrack.dispose();
});
}
}, (ex) => {
console.log("Failed to get remote track " + ex);
});
},
...
};
...
return instance;
} |
8.2. Удаление отображаемой видео дорожки
removeVideoTrack() code
Code Block |
---|
|
const createOneToOneParticipantModel = function (userId, nickname, participantView, remoteTrackFactory, abrFactory, displayOptions) {
const instance = {
...
removeVideoTrack: function (track) {
if (this.videoTracks.delete(track.mid)) {
const remoteTrack = this.remoteVideoTracks.get(track.mid);
if (remoteTrack) {
this.remoteVideoTracks.delete(track.mid);
remoteTrack.dispose();
}
participantView.removeVideoTrack(track);
const abrManager = this.abrManagers.get(track.id);
if (abrManager) {
this.abrManagers.delete(track.id);
abrManager.clearQualityState();
abrManager.stop();
}
}
},
...
};
...
return instance;
} |
8.3. Добавление аудио дорожки для отображения
addAudioTrack() code
Code Block |
---|
|
const createOneToOneParticipantModel = function (userId, nickname, participantView, remoteTrackFactory, abrFactory, displayOptions) {
const instance = {
...
addAudioTrack: function (track) {
this.audioTracks.set(track.mid, track);
const self = this;
remoteTrackFactory.getAudioTrack().then((remoteTrack) => {
if (remoteTrack) {
if (self.disposed || !self.audioTracks.get(track.mid)) {
remoteTrack.dispose();
return;
}
this.remoteAudioTracks.set(track.mid, remoteTrack);
remoteTrack.demandTrack(track.id).then(() => {
if (!self.audioTracks.get(track.mid)) {
remoteTrack.dispose();
self.remoteAudioTracks.delete(track.mid);
return;
}
participantView.addAudioTrack(track, remoteTrack.track, displayOptions.showAudio);
}, (ex) => {
console.log("Failed demand track " + ex);
remoteTrack.dispose();
self.remoteAudioTracks.delete(track.mid);
});
}
}, (ex) => {
console.log("Failed to get audio track " + ex);
});
},
...
};
...
return instance;
} |