Signaling client error
Co2Link opened this issue · 3 comments
Co2Link commented
I'm getting error like this as viewer using Chrome on iphone.
[2021-09-27T07:05:15.095Z] [INFO] [VIEWER] Starting viewer connection
[2021-09-27T07:05:15.355Z] [INFO] [VIEWER] Connected to signaling service
[2021-09-27T07:05:15.356Z] [INFO] [VIEWER] Creating SDP offer
[2021-09-27T07:05:15.362Z] [INFO] [VIEWER] Sending SDP offer
[2021-09-27T07:05:15.363Z] [INFO] [VIEWER] Generating ICE candidates
[2021-09-27T07:09:04.113Z] [ERROR] [VIEWER] Signaling client error: {
"isTrusted": true
}
[2021-09-27T07:09:04.117Z] [INFO] [VIEWER] Disconnected from signaling channel
As described in #102 , it suggested that it could be a permission issue.
But i can view the stream normally without error at the same page using Chrome or Edge on my Windows PC.
I'm using
"amazon-kinesis-video-streams-webrtc": "^1.0.8",
"aws-sdk": "^2.989.0",
Thank you in advance.
Co2Link commented
Here is the code for startViewer()
Only receive video stream from master.
var AWS = require("aws-sdk");
let logConfigured = false;
const SignalingClient = require("amazon-kinesis-video-streams-webrtc")
.SignalingClient;
const region = process.env.VUE_APP_AWS_REGION;
const accessKeyId = process.env.VUE_APP_AWS_ACCESS_KEY;
const secretAccessKey = process.env.VUE_APP_AWS_SECRET_ACCESS_KEY;
function getRandomClientId() {
return Math.random()
.toString(36)
.substring(2)
.toUpperCase();
}
export const startViewer = async (viewer, channelName, remoteView) => {
viewer.remoteView = remoteView;
const kinesisVideoClient = new AWS.KinesisVideo({
region,
accessKeyId,
secretAccessKey,
correctClockSkew: true,
});
const describeSignalingChannelResponse = await kinesisVideoClient
.describeSignalingChannel({
ChannelName: channelName, // channel name
})
.promise();
const channelARN = describeSignalingChannelResponse.ChannelInfo.ChannelARN;
console.log("[VIEWER] Channel ARN: ", channelARN);
// Get signaling channel endpoints
const getSignalingChannelEndpointResponse = await kinesisVideoClient
.getSignalingChannelEndpoint({
ChannelARN: channelARN,
SingleMasterChannelEndpointConfiguration: {
Protocols: ["WSS", "HTTPS"],
Role: "VIEWER",
},
})
.promise();
const endpointsByProtocol = getSignalingChannelEndpointResponse.ResourceEndpointList.reduce(
(endpoints, endpoint) => {
endpoints[endpoint.Protocol] = endpoint.ResourceEndpoint;
return endpoints;
},
{}
);
console.log("[VIEWER] Endpoints: ", endpointsByProtocol);
const kinesisVideoSignalingChannelsClient = new AWS.KinesisVideoSignalingChannels(
{
region: region,
accessKeyId: accessKeyId,
secretAccessKey: secretAccessKey,
endpoint: endpointsByProtocol.HTTPS,
correctClockSkew: true,
}
);
// Get ICE server configuration
const getIceServerConfigResponse = await kinesisVideoSignalingChannelsClient
.getIceServerConfig({
ChannelARN: channelARN,
})
.promise();
const iceServers = [];
iceServers.push({
urls: `stun:stun.kinesisvideo.${region}.amazonaws.com:443`,
});
getIceServerConfigResponse.IceServerList.forEach((iceServer) =>
iceServers.push({
urls: iceServer.Uris,
username: iceServer.Username,
credential: iceServer.Password,
})
);
console.log("[VIEWER] ICE servers: ", iceServers);
// Create Signaling Client
viewer.signalingClient = new SignalingClient({
channelARN,
channelEndpoint: endpointsByProtocol.WSS,
clientId: getRandomClientId(),
role: "VIEWER",
region: region,
credentials: {
// TODO
// region: region,
accessKeyId: accessKeyId,
secretAccessKey: secretAccessKey,
},
systemClockOffset: kinesisVideoClient.config.systemClockOffset,
});
// eslint-disable-next-line no-debugger
// debugger;
const configuration = {
iceServers,
iceTransportPolicy: "all",
};
viewer.peerConnection = new RTCPeerConnection(configuration);
viewer.signalingClient.on("sdpAnswer", async (answer) => {
// Add the SDP answer to the peer connection
console.log("[VIEWER] Received SDP answer");
await viewer.peerConnection.setRemoteDescription(answer);
// Indicate if the connection is successful
viewer.SDP_RECEIVED = true;
});
viewer.signalingClient.on("iceCandidate", (candidate) => {
// Add the ICE candidate received from the MASTER to the peer connection
console.log("[VIEWER] Received ICE candidate");
viewer.peerConnection.addIceCandidate(candidate);
});
viewer.signalingClient.on("close", () => {
console.log("[VIEWER] Disconnected from signaling channel");
});
viewer.signalingClient.on("error", (error) => {
console.error("[VIEWER] Signaling client error: ", error);
});
viewer.peerConnection.addEventListener("icecandidate", ({ candidate }) => {
if (candidate) {
console.log("[VIEWER] Generated ICE candidate");
// When trickle ICE is enabled, send the ICE candidates as they are generated.
console.log("[VIEWER] Sending ICE candidate");
viewer.signalingClient.sendIceCandidate(candidate);
} else {
console.log("[VIEWER] All ICE candidates have been generated");
// When trickle ICE is disabled, send the offer now that all the ICE candidates have ben generated.
// console.log("[VIEWER] Sending SDP offer");
// viewer.signalingClient.sendSdpOffer(
// viewer.peerConnection.localDescription
// );
}
});
viewer.peerConnection.addEventListener("track", (event) => {
console.log("[VIEWER] Received remote track");
if (remoteView.srcObject) {
return;
}
viewer.remoteStream = event.streams[0];
remoteView.srcObject = viewer.remoteStream;
});
viewer.signalingClient.on("open", async () => {
console.log("[VIEWER] Connected to signaling service");
// Create an SDP offer to send to the master
console.log("[VIEWER] Creating SDP offer");
const offer = await viewer.peerConnection.createOffer({
offerToReceiveVideo: true,
// offerToReceiveAudio: true,
});
await viewer.peerConnection.setLocalDescription(offer);
//eslint-disable-next-line no-debugger
// debugger;
console.log("offer:", offer);
console.log("[VIEWER] Sending SDP offer 4");
viewer.signalingClient.sendSdpOffer(viewer.peerConnection.localDescription);
console.log("[VIEWER] Generating ICE candidates");
});
console.log("[VIEWER] Starting viewer connection");
viewer.signalingClient.open();
};
export const stopViewer = (viewer) => {
console.log("[VIEWER] Stopping viewer connection");
if (viewer.signalingClient) {
viewer.signalingClient.close();
viewer.signalingClient = null;
}
if (viewer.peerConnection) {
viewer.peerConnection.close();
viewer.peerConnection = null;
}
if (viewer.remoteStream) {
viewer.remoteStream.getTracks().forEach((track) => track.stop());
viewer.remoteStream = null;
}
if (viewer.remoteView) {
viewer.remoteView.srcObject = null;
}
};
export const configureLogging = (logs) => {
function log(level, messages) {
const text = messages
.map((message) => {
if (typeof message === "object") {
return JSON.stringify(message, null, 2);
} else {
return message;
}
})
.join(" ");
logs.push({
time: new Date().toISOString(),
level: level,
text: text,
});
}
if (logConfigured) {
console.error = console._error;
console.warn = console._warn;
console.log = console._log;
}
logConfigured = true;
console._error = console.error;
console.error = function(...rest) {
log("ERROR", Array.prototype.slice.call(rest));
console._error.apply(this, rest);
};
console._warn = console.warn;
console.warn = function(...rest) {
log("WARN", Array.prototype.slice.call(rest));
console._warn.apply(this, rest);
};
console._log = console.log;
console.log = function(...rest) {
log("INFO", Array.prototype.slice.call(rest));
console._log.apply(this, rest);
};
};
Found out that offer do not contain any media if running on mobile chrome
const offer = await viewer.peerConnection.createOffer({
offerToReceiveVideo: true,
// offerToReceiveAudio: true,
});
await viewer.peerConnection.setLocalDescription(offer);
//eslint-disable-next-line no-debugger
// debugger;
console.log("offer:", offer);
[2021-10-05T09:09:01.567Z] [INFO] [VIEWER] Starting viewer connection
[2021-10-05T09:09:02.595Z] [INFO] [VIEWER] Connected to signaling service
[2021-10-05T09:09:02.596Z] [INFO] [VIEWER] Creating SDP offer
[2021-10-05T09:09:02.608Z] [INFO] {
"sdp": "v=0\r\no=- 9007969078791235421 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS\r\n",
"type": "offer"
}
[2021-10-05T09:09:02.609Z] [INFO] [VIEWER] Sending SDP offer 4
[2021-10-05T09:09:02.609Z] [INFO] [VIEWER] Generating ICE candidates
niyatim23 commented
niyatim23 commented
Closing due to inactivity, feel free to reopen it if you have any further questions/issues.