I permant use this javascript code for webrtc (aiortc) communication:
var port = 8080
var ip_address = "192.168.1.10"
var main_pc = {
"name":"",
"surname":"",
"pc":null,
"dc":null,
"uid":null,
"local_audio":null,
"local_video":null,
"remote_audio":null,
"remote_video":null
};
var peer_connections = [];
var closing = false
var controller = null;
var signal;
var stop_time_out = null;
function start(name,surname) {
$("#control_call_button").addClass("d-none");
$("#stop_call_button").removeClass("d-none");
$("#signal-audio").trigger("play");
main_pc = createPeerConnection(main_pc);
main_pc["name"] = name;
main_pc["surname"] = surname;
main_pc["dc"] = main_pc["pc"].createDataChannel('chat', {"ordered": true});
main_pc["dc"].onmessage = function(evt) {
data = JSON.parse(evt.data);
if(data["type"] == "closing"){
if (main_pc["uid"] == "uid"){
stop_peer_connection();
}else{
//stop_client_peer_connection(data["uid"]);
}
}
if (data["type"] == "uid"){
uid = data["uid"];
main_pc["uid"] = uid;
console.log(main_pc);
}
if (data["type"] == "new-client"){
var uid = data["uid"];
var client_name = data["name"];
var client_surname = data["surname"];
console.log("New client:");
console.log(uid);
console.log(client_name);
console.log(client_surname);
//start_client(uid,client_name,client_surname);
}
};
main_pc["pc"].onconnectionstatechange = (event) => {
let newCS = main_pc["pc"].connectionState;
if (newCS == "disconnected" || newCS == "failed" || newCS == "closed") {
stop_time_out = setTimeout(stop_with_time_out, 7000);
}else{
if (stop_time_out != null){
clearTimeout(stop_time_out);
stop_time_out = null;
}
}
}
main_pc["pc"].onclose = function() {
closing = true;
stop_peer_connection();
// close data channel
if (main_pc["dc"]) {
main_pc["dc"].close();
}
// close local audio / video
main_pc["pc"].getSenders().forEach(function(sender) {
sender.track.stop();
});
// close transceivers
if (main_pc["pc"].getTransceivers) {
main_pc["pc"].getTransceivers().forEach(function(transceiver) {
if (transceiver.stop) {
transceiver.stop();
}
});
}
main_pc["pc"] = null;
$("#control_call_button").removeClass("d-none");
$("#stop_call_button").addClass("d-none");
};
constraints = {audio:true,video:true};
navigator.mediaDevices.getUserMedia(constraints).then(function(stream) {
stream.getTracks().forEach(function(track) {
try {
main_pc["pc"].addTrack(track, stream);
if (track.kind == "video"){
//correct
main_pc["local_video"] = stream;
document.getElementById('client-video-1').srcObject = stream;
}else{
main_pc["local_audio"] = stream;
}
} catch(e){
}
});
return negotiate();
}, function(err) {
alert('Could not acquire media: ' + err);
});
}
function createPeerConnection(pc) {
var config = {
sdpSemantics: 'unified-plan'
};
config.iceServers = [{ urls: ['stun:stun.l.google.com:19302'] }];
pc["pc"] = new RTCPeerConnection(config);
// connect audio
pc["pc"].addEventListener('track', function(evt) {
if (evt.track.kind == 'audio'){
$("#signal-audio").trigger("pause");
$("#signal-audio").currentTime = 0; // Reset time
document.getElementById('server-audio').srcObject = evt.streams[0];
$("#control_call_button").addClass("d-none")
$("#stop_call_button").removeClass("d-none")
pc["remote_audio"] = evt.streams[0];
}else if (evt.track.kind == 'video'){
document.getElementById('server-video').srcObject = evt.streams[0];
pc["remote_video"] = evt.streams[0];
}
});
return pc;
}
function negotiate() {
return main_pc["pc"].createOffer({"offerToReceiveAudio":true,"offerToReceiveVideo":true}).then(function(offer) {
return main_pc["pc"].setLocalDescription(offer);
}).then(function() {
// wait for ICE gathering to complete
return new Promise(function(resolve) {
if (main_pc["pc"].iceGatheringState === 'complete') {
resolve();
} else {
function checkState() {
if (main_pc["pc"].iceGatheringState === 'complete') {
main_pc["pc"].removeEventListener('icegatheringstatechange', checkState);
resolve();
}
}
main_pc["pc"].addEventListener('icegatheringstatechange', checkState);
}
});
}).then(function() {
var offer = main_pc["pc"].localDescription;
controller = new AbortController();
signal = controller.signal;
try{
promise = timeoutPromise(60000, fetch('http://'+ip_address+':'+port+'/offer', {
body: JSON.stringify({
sdp: offer.sdp,
type: offer.type,
"name":name,
"surname":surname
}),
headers: {
'Content-Type': 'application/json'
},
method: 'POST',
signal
}));
return promise;
}catch (error){
console.log(error);
stop_peer_connection();
}
}).then(function(response) {
if (response.ok){
return response.json();
}else{
stop_peer_connection();
}
}).then(function(answer) {
console.log(answer);
if (answer.sdp == "" && answer.type == ""){
stop_peer_connection();
return null;
}else{
return main_pc["pc"].setRemoteDescription(answer);
}
}).catch(function(e) {
console.log(e);
stop_peer_connection();
return null;
});
}
function timeoutPromise(ms, promise) {
return new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => {
reject(new Error("promise timeout"))
}, ms);
promise.then(
(res) => {
clearTimeout(timeoutId);
resolve(res);
},
(err) => {
clearTimeout(timeoutId);
reject(err);
}
);
})
}
function stop_peer_connection(dc_message=true) {
$("#signal-audio").trigger("pause");
$("#signal-audio").currentTime = 0; // Reset time
// send disconnect message because iceconnectionstate slow to go in failed or in closed state
try{
if (main_pc["dc"].readyState == "open"){
if (dc_message){
main_pc["dc"].send(JSON.stringify({"type":"disconnected"}));
}
}
}catch (e){
}
try{
if (main_pc["local_audio"] != null){
main_pc["local_audio"].stop();
main_pc["local_video"].stop();
main_pc["local_audio"] = null;
main_pc["local_video"] = null;
//main_pc["remote_audio"].stop();
//main_pc["remote_video"].stop();
//main_pc["remote_audio"] = null;
//main_pc["remote_video"] = null;
}
}
catch (e){
}
document.getElementById('client-video-1').srcObject = null;
document.getElementById('server-video').srcObject = null;
document.getElementById('server-audio').srcObject = null;
document.getElementById('client-audio-2').srcObject = null;
document.getElementById('client-video-2').srcObject = null;
document.getElementById('client-audio-3').srcObject = null;
document.getElementById('client-video-3').srcObject = null;
try{
if (controller != null){
controller.abort();
}
if (main_pc["dc"].readyState != "open"){
main_pc["pc"].close();
}
}catch (e){
}
$("#control_call_button").removeClass("d-none")
$("#stop_call_button").addClass("d-none")
}
function stop_with_time_out(){
stop_peer_connection(false);
stop_time_out = null;
}
$(document).ready(function(){
$("#control_call_button").on( "click", function() {
name = $("#name").val();
surname = $("#surname").val();
$("#me-name").html(name+" "+surname)
closing = false;
controller = null;
start(name,surname);
});
$("#stop_call_button").on( "click", function() {
closing = true;
stop_peer_connection();
});
})
I just want when the connection is closed the camera led will also close. Is there something i can do about?
You are trying to call the stop()
method on a MediaStream
object like main_pc["local_audio"]
which is no longer how you are supposed to do do it. Instead, you need to stop all tracks of the local stream along the lines of
main_pc["local_audio"].getTracks().forEach(track => track.stop())
Once all local tracks have been stopped the webcam light will go off and you need to call getUserMedia again.