WEBRTC remote video stops streaming after 2 seconds - javascript
I am facing a very weird behavior with this WEBRTC peer to peer app. the app would stream audio form one peer to the other, but when it comes to stream video, it actually stream video but just for the first 2 seconds, then it would stop streaming video, but the audio continues to stream. Here is some of the code that handles the remote video:
var webrtc_capable = true;
var rtc_peer_connection = null;
var rtc_session_description = null;
var get_user_media = null;
var connect_stream_to_src = null;
var stun_server = null;
if (navigator.getUserMedia) {
rtc_peer_connection = RTCPeerConnection;
rtc_session_description = RTCSessionDescription;
get_user_media = navigator.getUserMedia.bind(navigator);
connect_stream_to_src = function(media_stream, media_element) {
media_element.srcObject = window.URL.createObjectURL(media_stream);
media_element.play();
};
} else if (navigator.mozGetUserMedia) {
rtc_peer_connection = mozRTCPeerConnection;
rtc_session_description = mozRTCSessionDescription;
get_user_media = navigator.mozGetUserMedia.bind(navigator);
connect_stream_to_src = function(media_stream, media_element) {
media_element.srcObject = window.URL.createObjectURL(media_stream);
media_element.play();
};
stun_server = null;
} else if (navigator.webkitGetUserMedia) {
rtc_peer_connection = webkitRTCPeerConnection;
rtc_session_description = RTCSessionDescription;
get_user_media = navigator.webkitGetUserMedia.bind(navigator);
connect_stream_to_src = function(media_stream, media_element) {
media_element.src = webkitURL.createObjectURL(media_stream);
};
} else {
alert("This browser does not support WebRTC - visit WebRTC.org for more info");
webrtc_capable = false;
}
</script>
<script>
var call_token;
var signaling_server;
var peer_connection;
function start() {
// create the WebRTC peer connection object
peer_connection = new rtc_peer_connection({
"iceServers": [ // information about ice servers
{ "url": "stun:"+stun_server },
]
});
// generic handler that sends any ice candidates to the other peer
peer_connection.onicecandidate = function (ice_event) {
console.log(ice_event.candidate);
if (ice_event.candidate){
console.log("true");
}
if (ice_event.candidate) {
signaling_server.send(
JSON.stringify({
token:call_token,
type: "new_ice_candidate",
candidate: ice_event.candidate ,
})
);
}
};
peer_connection.onaddstream = function (event) {
var video = document.querySelector("#remote_video");
video.src = webkitURL.createObjectURL(event.stream);
document.getElementById("loading_state").style.display = "none";
document.getElementById("open_call_state").style.display = "block";
};
setup_video();
signaling_server = new WebSocket("ws://localhost:1234");
if (document.location.hash === "" || document.location.hash === undefined) {
var token = Date.now()+"-"+Math.round(Math.random()*10000);
call_token = "#"+token;
document.location.hash = token;
signaling_server.onopen = function() {
signaling_server.onmessage = caller_signal_handler;
signaling_server.send(
JSON.stringify({
token:call_token,
type:"join",
})
);
}
document.title = "You are the Caller";
document.getElementById("loading_state").innerHTML = "Ready for a call...ask your friend to visit:<br/><br/>"+document.location;
} else { // you have a hash fragment so you must be the Callee
// get the unique token for this call from location.hash
call_token = document.location.hash;
signaling_server.onopen = function() {
// setup caller signal handler
signaling_server.onmessage = callee_signal_handler;
// tell the signaling server you have joined the call
signaling_server.send(
JSON.stringify({
token:call_token,
type:"join",
})
);
// let the caller know you have arrived so they can start the call
signaling_server.send(
JSON.stringify({
token:call_token,
type:"callee_arrived",
})
);
}
document.title = "You are the Callee";
document.getElementById("loading_state").innerHTML = "One moment please...connecting your call...";
}
// setup message bar handlers
document.getElementById("message_input").onkeydown = send_chat_message;
document.getElementById("message_input").onfocus = function() { this.value = ""; }
}
// handler to process new descriptions
function new_description_created(description) {
peer_connection.setLocalDescription(
description,
function () {
signaling_server.send(
JSON.stringify({
token:call_token,
type:"new_description",
sdp:description
})
);
},
log_error
);
}
// handle signals as a caller
function caller_signal_handler(event) {
var signal = JSON.parse(event.data);
if (signal.type === "callee_arrived") {
peer_connection.createOffer(
new_description_created,
log_error
);
} else if (signal.type === "new_ice_candidate") {
peer_connection.addIceCandidate(new RTCIceCandidate(signal.candidate));
} else if (signal.type === "new_description") {
peer_connection.setRemoteDescription(
new rtc_session_description(signal.sdp),
function () {
if (peer_connection.remoteDescription.type == "answer") {
peer_connection.createOffer(new_description_created, log_error);
}
},
log_error
);
} else if (signal.type === "new_chat_message") {
add_chat_message(signal);
} else {
// extend with your own signal types here
}
}
// handle signals as a callee
function callee_signal_handler(event) {
var signal = JSON.parse(event.data);
if (signal.type === "new_ice_candidate") {
peer_connection.addIceCandidate(
new RTCIceCandidate(signal.candidate)
);
} else if (signal.type === "new_description") {
peer_connection.setRemoteDescription(
new rtc_session_description(signal.sdp),
function () {
if (peer_connection.remoteDescription.type == "offer") {
peer_connection.createAnswer(new_description_created, log_error);
}
},
log_error
);
} else if (signal.type === "new_chat_message") {
add_chat_message(signal);
} else {
// extend with your own signal types here
}
}
// add new chat message to messages list
function add_chat_message(signal) {
var messages = document.getElementById("messages");
var user = signal.user || "them";
messages.innerHTML = user+": "+signal.message+"<br/>\n"+messages.innerHTML;
}
// send new chat message to the other browser
function send_chat_message(e) {
if (e.keyCode == 13) {
var new_message = this.value;
this.value = "";
signaling_server.send(
JSON.stringify({
token:call_token,
type: "new_chat_message",
message: new_message
})
);
add_chat_message({ user: "you", message: new_message });
}
}
// setup stream from the local camera
function setup_video() {
get_user_media(
{
"audio": true, // request access to local microphone
"video": true // request access to local camera
},
function (local_stream) {
<video> MediaElement
connect_stream_to_src(local_stream, document.getElementById("local_video"));
peer_connection.addStream(local_stream);
},
log_error
);
}
function log_error(error) {
console.log(error);
}
</script>
Additional Info:
Windows 8 x64
opera version is 27.0.1689.76
Localvideo plays fine
This call is between two peers on the same network(no nat traversal)
Related
Unhandled error Error: Data cannot be encoded in JSON error at firebase serverless functions
I'm trying to deploy an api for my application. Using these codes raises Unhandled error "Error: Data cannot be encoded in JSON. const functions = require("firebase-functions"); const axios = require("axios"); exports.getDatas = functions.https.onCall(async (d)=>{ functions.logger.log(d["name"]); cname = d["name"]; ts1=d["ts1"]; ts2=d["ts2"]; const data = await axios.get( "https://api.coingecko.com/api/v3/coins/" + cname + "/market_chart/range?vs_currency=usd&from=" + ts1 + "&to=" + ts2, ); functions.logger.log(data); return {data: data}; }); The error log is Unhandled error Error: Data cannot be encoded in JSON: function httpAdapter(config) { return new Promise(function dispatchHttpRequest(resolvePromise, rejectPromise) { var onCanceled; function done() { if (config.cancelToken) { config.cancelToken.unsubscribe(onCanceled); } if (config.signal) { config.signal.removeEventListener('abort', onCanceled); } } var resolve = function resolve(value) { done(); resolvePromise(value); }; var rejected = false; var reject = function reject(value) { done(); rejected = true; rejectPromise(value); }; var data = config.data; var headers = config.headers; var headerNames = {}; Object.keys(headers).forEach(function storeLowerName(name) { headerNames[name.toLowerCase()] = name; }); // Set User-Agent (required by some servers) // See https://github.com/axios/axios/issues/69 if ('user-agent' in headerNames) { // User-Agent is specified; handle case where no UA header is desired if (!headers[headerNames['user-agent']]) { delete headers[headerNames['user-agent']]; } // Otherwise, use specified value } else { // Only set header if it hasn't been set in config headers['User-Agent'] = 'axios/' + VERSION; } if (data && !utils.isStream(data)) { if (Buffer.isBuffer(data)) { // Nothing to do... } else if (utils.isArrayBuffer(data)) { data = Buffer.from(new Uint8Array(data)); } else if (utils.isString(data)) { data = Buffer.from(data, 'utf-8'); } else { return reject(createError( 'Data after transformation must be a string, an ArrayBuffer, a Buffer, or a Stream', config )); } if (config.maxBodyLength > -1 && data.length > config.maxBodyLength) { return reject(createError('Request body larger than maxBodyLength limit', config)); } // Add Content-Length header if data exists if (!headerNames['content-length']) { headers['Content-Length'] = data.length; } } // HTTP basic authentication var auth = undefined; if (config.auth) { var username = config.auth.username || ''; var password = config.auth.password || ''; auth = username + ':' + password; } // Parse url var fullPath = buildFullPath(config.baseURL, config.url); var parsed = url.parse(fullPath); var protocol = parsed.protocol || 'http:'; if (!auth && parsed.auth) { var urlAuth = parsed.auth.split(':'); var urlUsername = urlAuth[0] || ''; var urlPassword = urlAuth[1] || ''; auth = urlUsername + ':' + urlPassword; } if (auth && headerNames.authorization) { delete headers[headerNames.authorization]; } var isHttpsRequest = isHttps.test(protocol); var agent = isHttpsRequest ? config.httpsAgent : config.httpAgent; var options = { path: buildURL(parsed.path, config.params, config.paramsSerializer).replace(/^\?/, ''), method: config.method.toUpperCase(), headers: headers, agent: agent, agents: { http: config.httpAgent, https: config.httpsAgent }, auth: auth }; if (config.socketPath) { options.socketPath = config.socketPath; } else { options.hostname = parsed.hostname; options.port = parsed.port; } var proxy = config.proxy; if (!proxy && proxy !== false) { var proxyEnv = protocol.slice(0, -1) + '_proxy'; var proxyUrl = process.env[proxyEnv] || process.env[proxyEnv.toUpperCase()]; if (proxyUrl) { var parsedProxyUrl = url.parse(proxyUrl); var noProxyEnv = process.env.no_proxy || process.env.NO_PROXY; var shouldProxy = true; if (noProxyEnv) { var noProxy = noProxyEnv.split(',').map(function trim(s) { return s.trim(); }); shouldProxy = !noProxy.some(function proxyMatch(proxyElement) { if (!proxyElement) { return false; } if (proxyElement === '*') { return true; } if (proxyElement[0] === '.' && parsed.hostname.substr(parsed.hostname.length - proxyElement.length) === proxyElement) { return true; } return parsed.hostname === proxyElement; }); } if (shouldProxy) { proxy = { host: parsedProxyUrl.hostname, port: parsedProxyUrl.port, protocol: parsedProxyUrl.protocol }; if (parsedProxyUrl.auth) { var proxyUrlAuth = parsedProxyUrl.auth.split(':'); proxy.auth = { username: proxyUrlAuth[0], password: proxyUrlAuth[1] }; } } } } if (proxy) { options.headers.host = parsed.hostname + (parsed.port ? ':' + parsed.port : ''); setProxy(options, proxy, protocol + '//' + parsed.hostname + (parsed.port ? ':' + parsed.port : '') + options.path); } var transport; var isHttpsProxy = isHttpsRequest && (proxy ? isHttps.test(proxy.protocol) : true); if (config.transport) { transport = config.transport; } else if (config.maxRedirects === 0) { transport = isHttpsProxy ? https : http; } else { if (config.maxRedirects) { options.maxRedirects = config.maxRedirects; } transport = isHttpsProxy ? httpsFollow : httpFollow; } if (config.maxBodyLength > -1) { options.maxBodyLength = config.maxBodyLength; } if (config.insecureHTTPParser) { options.insecureHTTPParser = config.insecureHTTPParser; } // Create the request var req = transport.request(options, function handleResponse(res) { if (req.aborted) return; // uncompress the response body transparently if required var stream = res; // return the last request in case of redirects var lastRequest = res.req || req; // if no content, is HEAD request or decompress disabled we should not decompress if (res.statusCode !== 204 && lastRequest.method !== 'HEAD' && config.decompress !== false) { switch (res.headers['content-encoding']) { /*eslint default-case:0*/ case 'gzip': case 'compress': case 'deflate': // add the unzipper to the body stream processing pipeline stream = stream.pipe(zlib.createUnzip()); // remove the content-encoding in order to not confuse downstream operations delete res.headers['content-encoding']; break; } } var response = { status: res.statusCode, statusText: res.statusMessage, headers: res.headers, config: config, request: lastRequest }; if (config.responseType === 'stream') { response.data = stream; settle(resolve, reject, response); } else { var responseBuffer = []; var totalResponseBytes = 0; stream.on('data', function handleStreamData(chunk) { responseBuffer.push(chunk); totalResponseBytes += chunk.length; // make sure the content length is not over the maxContentLength if specified if (config.maxContentLength > -1 && totalResponseBytes > config.maxContentLength) { // stream.destoy() emit aborted event before calling reject() on Node.js v16 rejected = true; stream.destroy(); reject(createError('maxContentLength size of ' + config.maxContentLength + ' exceeded', config, null, lastRequest)); } }); stream.on('aborted', function handlerStreamAborted() { if (rejected) { return; } stream.destroy(); reject(createError('error request aborted', config, 'ERR_REQUEST_ABORTED', lastRequest)); }); stream.on('error', function handleStreamError(err) { if (req.aborted) return; reject(enhanceError(err, config, null, lastRequest)); }); stream.on('end', function handleStreamEnd() { try { var responseData = responseBuffer.length === 1 ? responseBuffer[0] : Buffer.concat(responseBuffer); if (config.responseType !== 'arraybuffer') { responseData = responseData.toString(config.responseEncoding); if (!config.responseEncoding || config.responseEncoding === 'utf8') { responseData = utils.stripBOM(responseData); } } response.data = responseData; } catch (err) { reject(enhanceError(err, config, err.code, response.request, response)); } settle(resolve, reject, response); }); } }); // Handle errors req.on('error', function handleRequestError(err) { if (req.aborted && err.code !== 'ERR_FR_TOO_MANY_REDIRECTS') return; reject(enhanceError(err, config, null, req)); }); // set tcp keep alive to prevent drop connection by peer req.on('socket', function handleRequestSocket(socket) { // default interval of sending ack packet is 1 minute socket.setKeepAlive(true, 1000 * 60); }); // Handle request timeout if (config.timeout) { // This is forcing a int timeout to avoid problems if the `req` interface doesn't handle other types. var timeout = parseInt(config.timeout, 10); if (isNaN(timeout)) { reject(createError( 'error trying to parse `config.timeout` to int', config, 'ERR_PARSE_TIMEOUT', req )); return; } // Sometime, the response will be very slow, and does not respond, the connect event will be block by event loop system. // And timer callback will be fired, and abort() will be invoked before connection, then get "socket hang up" and code ECONNRESET. // At this time, if we have a large number of request, nodejs will hang up some socket on background. and the number will up and up. // And then these socket which be hang up will devoring CPU little by little. // ClientRequest.setTimeout will be fired on the specify milliseconds, and can make sure that abort() will be fired after connect. req.setTimeout(timeout, function handleRequestTimeout() { req.abort(); var transitional = config.transitional || defaults.transitional; reject(createError( 'timeout of ' + timeout + 'ms exceeded', config, transitional.clarifyTimeoutError ? 'ETIMEDOUT' : 'ECONNABORTED', req )); }); } if (config.cancelToken || config.signal) { // Handle cancellation // eslint-disable-next-line func-names onCanceled = function(cancel) { if (req.aborted) return; req.abort(); reject(!cancel || (cancel && cancel.type) ? new Cancel('canceled') : cancel); }; config.cancelToken && config.cancelToken.subscribe(onCanceled); if (config.signal) { config.signal.aborted ? onCanceled() : config.signal.addEventListener('abort', onCanceled); } } // Send the request if (utils.isStream(data)) { data.on('error', function handleStreamError(err) { reject(enhanceError(err, config, null, req)); }).pipe(req); } else { req.end(data); } }); } at encode (/workspace/node_modules/firebase-functions/lib/common/providers/https.js:162:11) at encode (/workspace/node_modules/firebase-functions/lib/common/providers/https.js:156:22) at encode (/workspace/node_modules/firebase-functions/lib/common/providers/https.js:156:22) at encode (/workspace/node_modules/firebase-functions/lib/common/providers/https.js:156:22) at /workspace/node_modules/firebase-functions/lib/common/providers/https.js:334:22 at processTicksAndRejections (internal/process/task_queues.js:97:5) First logger logs the parameter i gave correctly and the logger that logs data is in this format: ...["api.coingecko.com:443::::::::::::::::::"]},"keepAliveMsecs":1000,"maxFreeSockets":256,"scheduling":"fifo","keepAlive":false,"maxSockets":null},"_removedConnection":false,"writable":true},"status":200,"data":{"prices":[[1615345414698,37.27069164629981],[1615349310788,36.95627388647297],[1615352802175,37.48630338203377],[1615356202751,37.46442850999597],[1615360079361,37.642735963063906],[1615363905145,38.29435586902702],[1615367492353,38.313292928237594],[1615370461299,38.75503558097479],[1615374138056,38.24406575020552],[1615377815960,38.237026584388175],[1615381321332,38.93964664468625],[1615384813000,39.262646397955635],[1615388739874,39.15882057568881],[1615392094129,38.94488140309047],[1615395966875,38.79820936257378],[1615399312625,38.51637055616189],[1615403055037,38.59237008394828],[1615406529740,38.44087305010874],[1615410281814,37.71855645797291],[1615414278815,38.374824600586976],[1615417716420,38.4538669693684],[1615421045728,37.62772478442999],[1615425672990,36.8826465121472],[1615429587089,37.41958697414903],[1615432278494,37.34865694722488],[1615435254265,37.16289143388951],[1615439122292,37.14731463575248],[1615442523394,36.801517989796814],[1615446290102,37.02248224990424],[1615450361470,36.164787531097126],[1615453299572,36.46191265162147],[1615457172317,36.174755169666334],[1615460886498,37.05778010952229],[1615464298322,37.336909500902365],[1615469586325,37.56497212211488],[1615472126260,37.83046394206218],[1615474882979,37.252561357731096],[1615478498201,36.56190097084664],[1615482336185,36.83824760787625],[1615485957910,36.89351702770813],[1615489642151,37.589229946501746],[1615493390438,37.33184737771527],[1615496666244,37.29234576242379],[1615500577712,37.284260441548426],[1616866645601,1137195941.0307472],[1616870299925,1089416195.9864128],[1616873841648,1074341877.495249],[1616877368137,1061555457.3375872],[1616880970910,1077775411.1216433],[1616884693948,1064594490.6022671],[1616887998472,1087481667.611567],[1616891397951,1068140794.5197278],[1616894759953,1078753362.1719048],[1616898371565,1053546315.1245787],[1616902002474,1052498816.7223371],[1616905584364,1026915395.5541993],[1616909101481,1022271206.3215427],[1616912730390,997185793.1210617],[1616916434482,972130048.6316774],[1616919928611,988711196.2721183],[1616923534317,987299160.6191593],[1616926264719,975360472.6011684],[1616930074136,958327264.7346151],[1616933292776,935085970.8922312],[1616936940791,896217168.3654604],[1616940936847,878876312.6707534],[1616944090304,890504985.5476977],[1616948321869,896715385.5657766],[1616952007508,870767231.0865391],[1616955544207,880601758.4610194],[1616958381375,896794852.1077055],[1616962022167,929362788.5783823],[1616966479654,927502494.4691795],[1616969648773,880385481.5284289],[1616973545649,862329007.9935848],[1616977463095,840138544.6360805],[1616980359587,849727926.595521],[1616984356096,820616225.3306137],[1616987602367,898085663.0760688],[1616990444958,890215727.4112909],[1616995470635,914823340.6343507],[1616999032159,890922230.685704],[1617002651977,937214914.0703756],[1617005329558,976030203.3879734],[1617009370471,1061898884.4388478],[1617012348377,1111994349.2592206],[1617015705482,1175310227.1595278],[1617019895549,1217044915.3900926],[1617022941451,1204239369.9336267],[1617027118715,1225123359.1178432],[1617031210170,1191418570.9198012],[1617033728601,1257085051.9742537],[1617037882992,1261291734.3667347],[1617041858553,1265805909.4506621],[1617044547418,1261869965.5784621],[1617049418534,1225924891.220988],[1617052450394,1200646247.466799],[1617055896172,1209247034.0807025],[1617059684123,1249662106.3996315],[1617062561979,837849935.5380555],[1617066155823,1261094295.2039979],[1617070572708,1244044711.3556864],[1617074210159,1178503497.252399],[1617077106612,1184744920.254339],[1617080571662,1219164970.9205332],[1617084836477,1174744890.1399443],[1617087739776,1236332180.5454476],[1617092763739,1121685108.4046226],[1617096303391,1074005978.1362224],[1617100013739,1075898891.906641],[1617102136947,1041120230.0169744],[1617106411165,1021062028.7444541],[1617110588848,1004207600.6385714],[1617114148509,983098685.435342],[1617117449987,983878432.6976557],[1617120868725,943893192.0239582],[1617123806180,948379973.8680001],[1617128347360,948328240.0510467],[1617131244094,923477307.6495335],[1617134866719,918321070.6284192],[1617138697011,960178009.2986945],[1617142067857,974105207.7725881],[1617146083923,973959760.0729104],[1617149999086,959500047.5209063],[1617153094367,1007753562.6156206],[1617156698445,1021534121.1115336],[1617160175611,1028067427.0339341],[1617163928330,1007755251.8882328],[1617166924538,1023240773.0466446],[1617171886674,1037535813.1806505],[1617175133694,1101375379.7094195],[1617178435173,1136688478.90344],[1617182857658,1208366620.2561867],[1617185353773,1208823054.3509212],[1617188828477,1234197192.568771],[1617193393471,1707076315.380663],[1617196301983,1845668637.7358408],[1617199516026,1901877634.1385415],[1617203681947,2015292037.1305778],[1617207515426,2141098631.115179],[1617210224998,2343473154.2871637],[1617214323265,2329074198.4966955],[1617217968405,2461828129.1798186],[1617221653017,2493042958.539376],[1617224582971,2532015555.7692595],[1617228589364,2508661361.110037],[1617232204720,2590057969.924583],[1617235260464,2749780924.550207],[1617239367664,2791689438.967896],[1617243152558,2778422749.5901804],[1617246573894,2802892972.2612605],[1617250114952,2795446026.902383],[1617253276300,2837092221.188881],[1617257741390,2957061611.281718],[1617261111556,3025594776.954216],[1617264301698,3140730366.12618],[1617267704421,3230797741.627739],[1617272276500,3247001347.7404704],[1617275862720,3182990384.8873067],[1617279129292,2889317168.9977646],[1617283053665,2753527702.506779],[1617287046529,2700392654.8781624],[1617290204012,2616296684.424929],[1617293298853,2494255828.9768047],[1617296557242,2383424694.8900166],[1617301325511,2288268623.177356],[1617303766777,2297155897.636895],[1617307669347,2314935325.319679],[1617311721980,2259716784.056617],[1617314946823,2267889595.9127536],[1617319572007,2174169254.528509],[1617323182318,2097690604.8152165],[1617326033792,2110975746.1916978],[1617329489226,2126100629.800452],[1617332409284,2193182655.044224],[1617337211709,2199847063.5248647],[1617340611316,2167549077.601362],[1617344146863,2110348803.8388174],[1617347361962,2023115590.5637138],[1617351380142,1864316761.5098753],[1617354151186,1788973202.0040677],[1617359277447,1731207666.0376515],[1617361312976,1418566500.3106787],[1617366169158,1693859181.5518322],[1617369860769,1656689094.290342],[1617372306072,1660176536.7450612],[1617376754676,1722154482.4234965],[1617379285817,1915067128.493045],[1617383311995,1982773491.2907202],[1617387963188,1985155493.939231],[1617391564495,1827213471.6221747],[1617395202777,1932891922.7380657],[1617398214973,1937931474.560893],[1617401809690,1961473630.4188676],[1617405699909,1952347409.661483],[1617409553080,2172811188.054834],[1617412963837,2431917537.219363],[1617416445822,2666886575.1140027],[1617420431122,2769520722.4907126],[1617422613890,2797409323.779513],[1617427393260,2895546310.6951184],[1617431058021,2894169435.883223],[1617433696700,2651591430.614699],[1617437513773,3448548871.8910036],[1617441138039,3537764498.5278754],[1617444820385,3662623380.0181885],[1617448128419,3729999481.3895626],[1617452094944,3741683833.307362],[1617457034540,3761774670.321721],[1617460631688,3809173022.555833],[1617464335978,3711591162.8519845],[1617467879738,3759143118.4621553],[1617471447610,3693936894.7524076],[1617474960418,3833857114.2069917],[1617478639837,3888109113.59996],[1617482233320,3857034438.9984646],[1617485821346,3898924734.2645984],[1617489477282,3952661186.2182713],[1617493109729,4002501827.9437523],[1617495709286,3872814933.0218143],[1617499443431,3939579930.8108554],[1617503699037,3663106636.5813146],[1617507443725,3808705623.491391],[1617510706891,3786240536.055139],[1617512446242,3717882675.3539762],[1617516040645,3722966733.2957063],[1617519813304,3482249884.952562],[1617523351916,3345586253.508183],[1617526909722,3327000473.8244348],[1617530664916,3181835266.2617188],[1617534176048,3094776290.1306324],[1617537924632,3064167829.684326],[1617541493704,3112790145.252149],[1617545018360,2989449570.670528],[1617548594506,3016965749.017692],[1617552471191,2973530338.557288],[1617555933696,2759208177.1915674],[1617559387440,2662906186.1813793],[1617563034515,2521716547.9565806],[1617566483711,2454800946.788864],[1617570325792,2412175803.4922743],[1617573668989,2381142461.766321],[1617577282876,2228904400.2017546],[1617580896737,2203439508.717633],[1617584514686,2083961834.3200803],[1617588367701,1922511436.832222],[1617591869391,1816453643.1859522],[1617595346098,1783362433.1356776],[1617599069131,1767878927.408502],[1617602711113,1782121869.0062866],[1617606278078,1784322317.8294444],[1617609891135,1785304724.1970084],[1617613319383,1792007217.4012969],[1617617302304,1808002080.6732872],[1617620901014,1821923720.87615],[1617624265084,1769426364.6123836],[1617629555312,1731155926.337212],[1617631504259,1735378701.9021676],[1617635133537,1942437073.2385755],[1617638780500,1938122743.6976163],[1617642119732,1932182393.8447528],[1617645707597,1918416705.3436842],[1617649325384,1925855235.7182896],[1617653252063,1944708214.0244768],[1617656889033,1932665022.73478],[1617660329160,1943687775.1192245],[1617663683699,1971924479.2343264],[1617667435208,2101421530.2666874],[1617672769205,2175322213.812557],[1617674524812,2168578229.7784457],[1617678186353,2149217571.1759067],[1617681915267,2132725563.885806],[1617685469475,1907950838.2268875],[1617689189705,2026223167.4473426],[1617692670953,1991840998.8517568],[1617696101989,1958389716.0448081],[1617699877898,2027665770.2623076],[1617703590445,2045913908.1590445],[1617707076556,2057724347.183567],[1617710622851,1722203248.9530182],[1617714225215,2160140597.446546],[1617717905528,2192080372.5552874],[1617721488585,2199844279.449877],[1617724918808,2244159138.5689125],[1617728548093,2263548854.897557],[1617732187891,2106855536.9938018],[1617735969816,2268365061.664965],[1617739538518,1863113060.588111],[1617742875565,2296819840.9881096],[1617746516853,2308037223.56185],[1617750327052,2297405821.9954567],[1617754017835,2215648462.217197],[1617758617023,2112353884.9607923],[1617761085616,2094123582.0260437],[1617764518134,2101292245.7045105],[1617768287923,2104106865.0792534],[1617771810289,2127056476.4717],[1617775566730,2152196953.3590703],[1617778865860,2160666464.579131],[1617782881414,2201171213.1865735],[1617786249160,2203934869.139618],[1617789807394,2329117281.806726],[1617793383957,2333039138.899913],[1617796986959,2491205752.3653517],[1617800521125,2652604590.3673797],[1617804331429,2692817000.168284],[1617807822435,2121796914.212729],[1617811418506,2538097921.330415],[1617815037057,2572049083.87979],[1617818698211,2550478468.4248347],[1617822347031,2541491737.3311806],[1617825969097,2609118564.630648],[1617829326876,2651351577.1099257],[1617833305171,2429954572.560337],[1617837011298,2435043578.3313527],[1617840572965,2394428204.082167],[1617843841041,2446826032.07983],[1617848315742,2395082349.188743],[1617850339793,2376349751.741466],[1617852591890,2385498650.2366877],[1617855126472,2380054416.699361],[1617858732962,2424505564.216302],[1617862619633,2434391633.272485],[1617865876330,2410962812.9744062],[1617869233838,2516114320.406959],[1617872539799,2437748581.3302546],[1617876293610,2247205079.171164],[1617880005259,2149347865.150653],[1617883394235,1893777066.5168178],[1617886836203,1757412804.559377],[1617892197847,1668727963.8671286],[1617894162445,1631584545.4824028],[1617897737215,1596293896.725426],[1617901282046,1525523967.3370435],[1617905003853,1370316987.26801],[1617908631874,1358993841.079183],[1617912335250,1404691449.9164236],[1617915995319,1379405950.1047523],[1617919567600,1366246502.7408085],[1617923270275,1289254721.1461022],[1617926622919,1386402238.6371279],[1617930228859,1384851642.1789908],[1617933705891,1365548610.2907162],[1617937372258,1357266138.9978309],[1617941122560,1335764096.6047564],[1617944870896,1322495289.1105938],[1617948462328,1283751933.8339043],[1617951863802,1272489837.990008],[1617955666499,1259096045.8789752],[1617958890026,1247182948.0102005],[1617962609987,1220448763.9536679],[1617966256703,1222538618.147044],[1617969964555,1148194206.4734476],[1617973333279,1199996169.7479842],[1617977646106,1154935691.529977],[1617980504476,1144564005.003322],[1617984273306,1132822242.6037295],[1617987925282,1136733019.0246003],[1617991396077,1139090847.1565342],[1617994822351,1133169530.4839995],[1617998615234,1113274570.5832539],[1618002141094,1094805189.6349592],[1618005876460,1035579604.067034],[1618009282025,1090335224.3969038],[1618013035782,1063984405.5106469],[1618016519119,1058097513.8615906],[1618020114108,1065381128.0365001]]}} When this code invoked it logs data correctly but i can not return it at last. Anyone can help?
The problem appears to be that you're trying to return the entire Axios response. This cannot be serialised as JSON due to circular references. Simply return the response data instead. You can also make your URL construction simpler (and safer) using the params option exports.getDatas = functions.https.onCall(async ({ name, ts1, ts2 }) => { functions.logger.log(name); // 👇 note the destructure here const { data } = await axios.get( `https://api.coingecko.com/api/v3/coins/${encodeURIComponent(name)}/market_chart/range`, { params: { vs_currency: "usd", from: ts1, to: ts2, } } ); functions.logger.log(data); return { data }; });
How to send web push notification for all active users
here I have used the button to send web push notifications. using this button only on the same browser notification came. but I want to send the same push notification to all active users. below is my code. let applicationServerPublicKey = 'myKey'; var pushButton = document.querySelector('.js-push-btn'); var pushNotiButton = document.querySelector('.push-btn'); let isSubscribed = false; let swRegistration = null; function urlB64ToUint8Array(base64String) { const padding = '='.repeat((4 - base64String.length % 4) % 4); const base64 = (base64String + padding) .replace(/\-/g, '+') .replace(/_/g, '/'); const rawData = window.atob(base64); const outputArray = new Uint8Array(rawData.length); for (let i = 0; i < rawData.length; ++i) { outputArray[i] = rawData.charCodeAt(i); } return outputArray; } function updateBtn() { if (isSubscribed) { pushButton.textContent = 'Disable Push Messaging'; } else { pushButton.textContent = 'Enable Push Messaging'; } pushButton.disabled = false; } function updateSubscriptionOnServer(subscription) { // TODO: Send subscription to application server console.log('subscription'+JSON.stringify(subscription)) const subscriptionJson = document.querySelector('.js-subscription-json'); const subscriptionDetails = document.querySelector('.js-subscription-details'); if (subscription) { //subscriptionJson.textContent = JSON.stringify(subscription); //subscriptionDetails.classList.remove('is-invisible'); } else { //subscriptionDetails.classList.add('is-invisible'); } } function subscribeUser() { const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey); swRegistration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: applicationServerKey }) .then(function(subscription) { console.log('User is subscribed'); updateSubscriptionOnServer(subscription); isSubscribed = true; updateBtn(); }) .catch(function(err) { console.log('Failed to subscribe the user: ', err); updateBtn(); }); } function initializeUI() { //pushButton.addEventListener('click', function() { pushButton.disabled = true; if (isSubscribed) { // TODO: Unsubscribe user } else { subscribeUser(); } //}); // Set the initial subscription value swRegistration.pushManager.getSubscription() .then(function(subscription) { isSubscribed = !(subscription === null); updateSubscriptionOnServer(subscription); if (isSubscribed) { console.log('User IS subscribed.'); } else { console.log('User is NOT subscribed.'); } updateBtn(); }); } if ('serviceWorker' in navigator && 'PushManager' in window) { window.addEventListener('load', function() { navigator.serviceWorker.register('{% url 'sw.js' %}').then(function(registration) { // Registration was successful console.log('ServiceWorker registration successful with scope: ', registration.scope); swRegistration = registration; initializeUI(); }, function(err) { // registration failed :( console.log('ServiceWorker registration failed: ', err); }); }); }else { console.warn('Push messaging is not supported'); pushButton.textContent = 'Push Not Supported'; } $(".push-btn").click(function(event) { console.log('[Service Worker] Push Received.'); //console.log('[Service Worker] Push had this data: '); const title = 'Push Codelab'; const options = { body: 'Yay it works.', //icon: 'images/icon.png', //badge: 'images/badge.png' }; navigator.serviceWorker.getRegistration().then(reg => { reg.showNotification(title, options); }); //event.waitUntil(ServiceWorkerRegistration.registration.showNotification(title, options)); }); let deferredPrompt; let addBtn = document.querySelector('#add-home-screen-btn'); let homeScreenBlock = document.querySelector("#home-screen-btn-block") homeScreenBlock.style.display = 'none'; window.addEventListener('beforeinstallprompt',(e)=>{ e.preventDefault(); deferredPrompt = e; homeScreenBlock.style.display = 'block'; addBtn.addEventListener('click',(e)=>{ homeScreenBlock.style.display='none'; deferredPrompt.prompt(); deferredPrompt.userChoice .then((choiceResult)=>{ if(choiceResult.outcome === 'accepted'){ console.log('Accepted A2SH') }else { console.log('user declined') } deferredPrompt = null; }) }) });
Web RTC between two different web clients not working
As per our web RTC requirements, there are two different client Player (Players the screen shared by capture client) Capture (Share Screen) The two web clients communicate and exchange offers and ICE candidates using WebSocket. In Chrome [Version 84.0.4147.105 (Official Build) (64-bit)] There is no error in the Player and Capture javascript console in chrome. But if we check chrome://webrtc-internals/ we can see the following event and transmission graph: Player Capture Here the I can see the video streaming is transmission but not playing in payer end and an ICE Candidate error in showing up int he events log. Is that is the problem the video stream is not working in the payer end? Firefox (v79.0) Showing errors in the console: DOMException: No remoteDescription. In player.js line no: 33. Any Idea why two different browsers have different errors? Player.js (function(){ var localVideo, remoteVideo, localConnection, remoteConnection; const MESSAGE_TYPE = { SDP: 'SDP', CANDIDATE_LOCAL: 'LOCAL_CANDIDATE', CANDIDATE_REMOTE: 'REMOTE_CANDIDATE' }; const signaling = new WebSocket('ws://127.0.0.1:1337'); var configuration = { offerToReceiveAudio: true, offerToReceiveVideo: true } remoteConnection = new RTCPeerConnection({configuration: configuration, iceServers: [{ urls: 'stun:aalimoshaver.com:3478' }]}); remoteConnection.onicecandidate = function(e) { !e.candidate || signaling.send(JSON.stringify({message_type:MESSAGE_TYPE.CANDIDATE_REMOTE, content: e.candidate.toJSON()})); } remoteConnection.ontrack = function (e) { const remoteVideo = document.getElementById('remote-view'); if (!remoteVideo.srcObject) { remoteVideo.srcObject = e.streams[0]; } }; signaling.onmessage = function (message){ const data = JSON.parse(message.data); const message_type = data.message_type; const content = data.content; try { if (message_type === MESSAGE_TYPE.CANDIDATE_LOCAL && content) { remoteConnection.addIceCandidate(content) .catch(function (e) { console.error(e) }); }else if (message_type === MESSAGE_TYPE.SDP && content) { if (content.type === 'offer') { remoteConnection.setRemoteDescription(content); remoteConnection.createAnswer() .then(function(answer){ remoteConnection.setLocalDescription(answer); signaling.send(JSON.stringify({ message_type: MESSAGE_TYPE.SDP, content: answer })); }); } else { console.log('Unsupported SDP type.'); } } } catch (err) { console.error(err); } }; })() Capture.js /** * Created by Sowvik Roy on 30-07-2020. */ (function () { var localVideo, remoteVideo, localConnection, remoteConnection; const MESSAGE_TYPE = { SDP_LOCAL: 'SDP', CANDIDATE_LOCAL: 'LOCAL_CANDIDATE', CANDIDATE_REMOTE: 'REMOTE_CANDIDATE' }; var configuration = { offerToReceiveAudio: true, offerToReceiveVideo: true }; const signaling = new WebSocket('ws://127.0.0.1:1337'); signaling.onmessage = function (message){ const data = JSON.parse(message.data); const message_type = data.message_type; const content = data.content; try { if (message_type === MESSAGE_TYPE.CANDIDATE_REMOTE && content) { localConnection.addIceCandidate(content) .catch(function (e) { console.error(e) }); } else if (message_type === MESSAGE_TYPE.SDP_LOCAL) { if (content.type === 'answer') { localConnection.setRemoteDescription(content); } else { console.log('Unsupported SDP type.'); } } } catch (err) { console.error(err); } }; document.addEventListener('click', function (event) { if (event.target.id === 'start') { startChat(); localVideo = document.getElementById('self-view'); remoteVideo = document.getElementById('remote-view'); } }); function startConnection(){ localConnection = new RTCPeerConnection({configuration: configuration, iceServers: [{ urls: 'stun:aalimoshaver.com:3478' }]}); localConnection.onicecandidate = function (e) { !e.candidate || signaling.send(JSON.stringify({message_type:MESSAGE_TYPE.CANDIDATE_LOCAL, content: e.candidate.toJSON()})); }; localConnection.createOffer() .then(function (offer) { if(offer){ localConnection.setLocalDescription(offer); signaling.send(JSON.stringify({message_type:MESSAGE_TYPE.SDP_LOCAL, content: localConnection.localDescription})); if (navigator.getDisplayMedia) { navigator.getDisplayMedia({video: true}).then(onCaptureSuccess); } else if (navigator.mediaDevices.getDisplayMedia) { navigator.mediaDevices.getDisplayMedia({video: true}).then(onCaptureSuccess); } else { navigator.mediaDevices.getUserMedia({video: {mediaSource: 'screen'}}).then(onCaptureSuccess); } } else{ console.error("RTC offer is null"); } }) .catch(function (e) { console.error(e) }); } function onCaptureSuccess(stream){ localVideo.srcObject = stream; stream.getTracks().forEach( function (track) { localConnection.addTrack( track, stream ); } ); } function startChat() { if (navigator.getDisplayMedia) { navigator.getDisplayMedia({video: true}).then(onMediaSuccess); } else if (navigator.mediaDevices.getDisplayMedia) { navigator.mediaDevices.getDisplayMedia({video: true}).then(onMediaSuccess); } else { navigator.mediaDevices.getUserMedia({video: {mediaSource: 'screen'}}).then(onMediaSuccess); } } function onMediaSuccess(stream) { localVideo.srcObject = stream; // Set up the ICE candidates for the two peers localConnection = new RTCPeerConnection({configuration: configuration, iceServers: [{ urls: 'stun:stun.xten.com:19302' }]}); localConnection.onicecandidate = function (e) { !e.candidate || signaling.send(JSON.stringify({message_type:MESSAGE_TYPE.CANDIDATE_LOCAL, content: e.candidate.toJSON()})); }; stream.getTracks().forEach( function (track) { localConnection.addTrack( track, stream ); } ); localConnection.createOffer() .then(function (offer) { if(offer){ localConnection.setLocalDescription(offer); signaling.send(JSON.stringify({message_type:MESSAGE_TYPE.SDP_LOCAL, content: localConnection.localDescription})); } else{ console.error("RTC offer is null"); } }) .catch(function (e) { console.error(e) }); } })(); Can anybody explain or identify a loophole in the code? Please let me know if you need additional info.
TypeError: Cannot read property 'charCodeAt' of undefined - Button sometimes does not work
I'm updating a Facebook ChatBot to DialogFlow Version 2. I have a problem with buttons, they don't work the first time, but if the user sends a text message, and then try again, the buttons start working. I'm working whit Heroku and Node.js, these are the results of heroku log This is my function sendToDialogFlow async function sendToDialogFlow(sender, textString, params) { try { const sessionPath = sessionClient.sessionPath( config.GOOGLE_PROJECT_ID, sessionIds.get(sender) ); const request = { session: sessionPath, queryInput: { text: { text: textString, languageCode: config.DF_LANGUAGE_CODE, }, }, queryParams: { payload: { data: params } } }; const responses = await sessionClient.detectIntent(request); const result = responses[0].queryResult; handleDialogFlowResponse(sender, result); } catch (e) { console.log('error'); console.log(e); } } And here it is handleDialogFlowResponse function function handleDialogFlowResponse(sender, response) { let responseText = response.fulfillmentMessages.fulfillmentText; let messages = response.fulfillmentMessages; let action = response.action; let contexts = response.outputContexts; let parameters = response.parameters; var delay = 4000; if (isDefined(action)) { sendTypingOn(sender); setTimeout(function(){ sendTypingOff(sender); handleDialogFlowAction(sender, action, messages, contexts, parameters); },delay); } else if (isDefined(messages) && (messages.length == 1 && messages[0].type != 0 || messages.length > 1) ) { sendTypingOn(sender); setTimeout(function(){ sendTypingOff(sender); handleMessages(messages, sender); },delay); } else if (responseText == '' && !isDefined(action)) { } else if (isDefined(responseText)) { sendTypingOn(sender); setTimeout(function(){ sendTypingOff(sender); sendTextMessage(sender, responseText); },delay); } } Thank you
Recorded video can't be forwarded/backwarded, Using MediaRecorder API chrome extension
I am implementing a chrome extension which records the screen with microphone and after recording it generates the recorded video perfectly but the problem is that the recorded video can not be forwarded/ backwarded or start video from any point first time. When it plays the first time after that it works perfectly but when I download this video then the problem is same. I take help from muaz khan plugin. I am using this code for start recording: function gotStream(stream) { if (cameraStream && cameraStream.getAudioTracks().length) { cameraStream.getAudioTracks().forEach(function(track) { // cameraStream.removeTrack(track); stream.addTrack(track); }); } if (typeof MediaRecorder.isTypeSupported == 'function') { /* MediaRecorder.isTypeSupported is a function announced in https://developers.google.com/web/updates/2016/01/mediarecorder and later introduced in the MediaRecorder API spec http://www.w3.org/TR/mediastream-recording/ */ if (MediaRecorder.isTypeSupported('video/mp4;codecs=h264')) { var options = { type: 'video', mimeType: 'video/mp4;codecs=h264' }; } else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) { var options = { type: 'video', mimeType: 'video/webm;codecs=vp9' }; } else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) { var options = { mimeType: 'video/webm;codecs=vp8' }; } console.log('Using ' + options.mimeType); recorder = new RecordRTC(stream, options); } else { console.log('Using default codecs for browser'); recorder = new MediaRecorder(stream); } recorder.streams = [stream]; recorder.start(10); recorder.ondataavailable = function(e) { chunks.push(e.data); }; recorder.onerror = function(e) { console.log('Error: ', e); }; recorder.onstart = function() { isRecording = true; onRecording(); console.log('Started & state = ' + recorder.state); }; recorder.onpause = function() { console.log('Paused & state = ' + recorder.state); } recorder.onresume = function() { console.log('Resumed & state = ' + recorder.state); } recorder.onwarning = function(e) { console.log('Warning: ' + e); }; recorder.onstop = function() { stopScreenRecording(); } stream.onended = function() { if (stream) { stream.onended = null; } recorder.stop(); }; if (stream.getVideoTracks().length) { stream.getVideoTracks().forEach(function(track) { track.onended = function() { if (!recorder) return; if (!stream || typeof stream.onended !== 'function') return; stream.onended(); }; }); } } and this for stop recording: function stopScreenRecording(blob) { isRecording = false; var blob = new Blob(chunks, { type: "video/mp4" }); chunks = []; var file = new File([blob ? blob : ''], getFileName(fileExtension), { type: mimeType }); DiskStorage.Store({ key: 'latest-file', value: file }, function(success) { if (success) { chrome.browserAction.setPopup({ popup: "popup.html" }); chrome.tabs.create({ url: 'preview.html' }); } }); setTimeout(function() { setDefaults(); // chrome.runtime.reload(); }, 1000); try { videoPlayers.forEach(function(player) { player.src = null; }); videoPlayers = []; } catch (e) {} // for dropdown.js chrome.storage.sync.set({ isRecording: 'false' // FALSE }); if (timer) { clearTimeout(timer); } setBadgeText(''); } I saw another screen recorder whose video blob is like: filesystem:chrome-extension://mmeijimgabbpbgpdklnllpncmdofkcpn/persistent/e6ad7ba1-6afe-4d45-y6f5-47e08a87e036.webm and our video blob is like: blob:chrome-extension://hgpenkfjeddjngnojmcmgbclkoakihhg/af3dcfa6-b990-464b-9726-e8b6022762a2 How can I get this type of blob?