I am trying to implement websocket through uwsgi Gevent. But, in between 2,3 requests I am always getting no PONG received in 3 seconds error.
Server Side code:
#ws.route('/websocket')
def audio(ws):
first_message = True
total_msg = ""
sample_rate = 0
total_data = []
while True:
msg = ws.receive()
# processing message here and sending response back
ws.send("response")
if __name__ == '__main__':
app.run(https='0.0.0.0:443,{},{}'.format(ssl_cert,ssl_key), port = 5002, gevent=1000)
Client side code:
ws = new WebSocket('wss://ec2-54-72-7-110.eu-west-1.compute.amazonaws.com/websocket');
//ws = new WebSocket('wss://ec2-54-72-7-110.eu-west-1.compute.amazonaws.com:5000/websocket');
ws.onopen = function(evt) {
console.log('Connected to websocket.');
alert("Recording started")
navigator.getUserMedia({audio: true, video: false}, initializeRecorder, function(e) {
console.log('No live audio input: ' + e);
});
}
function initializeRecorder(stream){
audio_context = new AudioContext;
sampleRate = audio_context.sampleRate;
ws.send("sample rate:" + sampleRate);
var audioInput = audio_context.createMediaStreamSource(stream);
console.log("Created media stream.");
var bufferSize = 4096;
// record only 1 channel
recorder = audio_context.createScriptProcessor(bufferSize, 1, 1);
// specify the processing function
recorder.onaudioprocess = recorderProcess;
// connect stream to our recorder
audioInput.connect(recorder);
// connect our recorder to the previous destination
recorder.connect(audio_context.destination);
}
function recorderProcess(e) {
var left = e.inputBuffer.getChannelData(0);
if (ws.readyState === WebSocket.OPEN) {
var view = new Int16Array(convertFloat32ToInt16(left))
console.log(view);
ws.send(view);
}
}
function close_WebSocket(){
console.log("done")
ws.send("done")
ws.onmessage = function(evt) {
console.log(evt.data)
ws.close()
}
audio_context.close();
}
I don't know what is wrong with it?
Related
I'm using recordRTC in browser for creating Video Clip, but after stop recording, I'm getting blob file type.
but I want to mp4 file type, for converting I used ffmpeg.js https://archive.org/download/ffmpeg_asm/ffmpeg_asm.js . yes I'm able to covert it now,
but the worry thing is, Now I only can view it on after downloading to my local PC, when I upload it to the server and then retrieve it, It's not visible.
recordRef.current.stopRecording(function (url) {
convertStreams(recordRef.current.getBlob());
});
var workerPath = 'https://archive.org/download/ffmpeg_asm/ffmpeg_asm.js';
function processInWebWorker() {
var blob = URL.createObjectURL(new Blob(['importScripts("' + workerPath + '");var now = Date.now;function print(text) {postMessage({"type" : "stdout","data" : text});};onmessage = function(event) {var message = event.data;if (message.type === "command") {var Module = {print: print,printErr: print,files: message.files || [],arguments: message.arguments || [],TOTAL_MEMORY: message.TOTAL_MEMORY || false};postMessage({"type" : "start","data" : Module.arguments.join(" ")});postMessage({"type" : "stdout","data" : "Received command: " +Module.arguments.join(" ") +((Module.TOTAL_MEMORY) ? ". Processing with " + Module.TOTAL_MEMORY + " bits." : "")});var time = now();var result = ffmpeg_run(Module);var totalTime = now() - time;postMessage({"type" : "stdout","data" : "Finished processing (took " + totalTime + "ms)"});postMessage({"type" : "done","data" : result,"time" : totalTime});}};postMessage({"type" : "ready"});'], {
type: 'application/javascript'
}));
var worker = new Worker(blob);
URL.revokeObjectURL(blob);
return worker;
}
var worker;
function convertStreams(videoBlob) {
setBlob(videoBlob)
setIsRecording(false)
setVideoPreview(true)
var aab;
var buffersReady;
var workerReady;
var posted;
var fileReader = new FileReader();
fileReader.onload = function () {
aab = this.result;
postMessage();
};
fileReader.readAsArrayBuffer(videoBlob);
if (!worker) {
worker = processInWebWorker();
}
worker.onmessage = function (event) {
var message = event.data;
if (message.type == "ready") {
workerReady = true;
if (buffersReady)
postMessage();
} else if (message.type == "stdout") {
} else if (message.type == "start") {
} else if (message.type == "done") {
var result = message.data[0];
var videoFile = new File([result.data], 'test.mp4', {
type: 'video/mpeg4'
});
setVideo_obj(videoFile)
}
};
const postMessage = function () {
posted = true;
worker.postMessage({
type: 'command',
arguments: '-i video.webm -c:v mpeg4 -b:v 6400k -strict experimental output.mp4'.split(' '),
// arguments: 'ffmpeg -i video.webm -movflags faststart -profile:v high -level 4.2 video.mp4',
files: [
{
data: new Uint8Array(aab),
name: 'video.webm'
}
]
});
};
}
}
}
I am using MediaRecorder to record chunks of my live video in webm format from MediaStream and converting these chunks to .ts files on the server using ffmpeg and then updating my playlist.m3u8 file with this code:
function generateM3u8Playlist(fileDataArr, playlistFp, isLive, cb) {
var durations = fileDataArr.map(function(fd) {
return fd.duration;
});
var maxT = maxOfArr(durations);
var meta = [
'#EXTM3U',
'#EXT-X-VERSION:3',
'#EXT-X-MEDIA-SEQUENCE:0',
'#EXT-X-ALLOW-CACHE:YES',
'#EXT-X-TARGETDURATION:' + Math.ceil(maxT),
];
fileDataArr.forEach(function(fd) {
meta.push('#EXTINF:' + fd.duration.toFixed(2) + ',');
meta.push(fd.fileName2);
});
if (!isLive) {
meta.push('#EXT-X-ENDLIST');
}
meta.push('');
meta = meta.join('\n');
fs.writeFile(playlistFp, meta, cb);
}
Here fileDataArr holds information for all the chunks that have been created.
After that i use this code to create a hls server :
var runStreamServer = (function(streamFolder) {
var executed = false;
return function(streamFolder) {
if (!executed) {
executed = true;
var HLSServer = require('hls-server')
var http = require('http')
var server = http.createServer()
var hls = new HLSServer(server, {
path: '/stream', // Base URI to output HLS streams
dir: 'C:\\Users\\Work\\Desktop\\live-stream\\webcam2hls\\videos\\' + streamFolder // Directory that input files are stored
})
console.log("We are going to stream from folder:" + streamFolder);
server.listen(8000);
console.log('Server Listening on Port 8000');
}
};
})();
The problem is that if i stop creating new chunks and then use the hls server link:
http://localhost:8000/stream/playlist.m3u8 then the video plays in VLC but if i try to play during the recording it keeps loading the file but does not play. I want it to play while its creating new chunks and updating playlist.m3u8. The quirk in generateM3u8Playlist function is that it adds '#EXT-X-ENDLIST' to the playlist file after i have stopped recording.
The software is still in production so its a bit messy code. Thank you for any answers.
The client side that generates blobs is as follows:
var mediaConstraints = {
video: true,
audio:true
};
navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError);
function onMediaSuccess(stream) {
console.log('will start capturing and sending ' + (DT / 1000) + 's videos when you press start');
var mediaRecorder = new MediaStreamRecorder(stream);
mediaRecorder.mimeType = 'video/webm';
mediaRecorder.ondataavailable = function(blob) {
var count2 = zeroPad(count, 5);
// here count2 just creates a blob number
console.log('sending chunk ' + name + ' #' + count2 + '...');
send('/chunk/' + name + '/' + count2 + (stopped ? '/finish' : ''), blob);
++count;
};
}
// Here we have the send function which sends our blob to server:
function send(url, blob) {
var xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.responseType = 'text/plain';
xhr.setRequestHeader('Content-Type', 'video/webm');
//xhr.setRequestHeader("Content-Length", blob.length);
xhr.onload = function(e) {
if (this.status === 200) {
console.log(this.response);
}
};
xhr.send(blob);
}
The code that receives the XHR request is as follows:
var parts = u.split('/');
var prefix = parts[2];
var num = parts[3];
var isFirst = false;
var isLast = !!parts[4];
if ((/^0+$/).test(num)) {
var path = require('path');
shell.mkdir(path.join(__dirname, 'videos', prefix));
isFirst = true;
}
var fp = 'videos/' + prefix + '/' + num + '.webm';
var msg = 'got ' + fp;
console.log(msg);
console.log('isFirst:%s, isLast:%s', isFirst, isLast);
var stream = fs.createWriteStream(fp, { encoding: 'binary' });
/*stream.on('end', function() {
respond(res, ['text/plain', msg]);
});*/
//req.setEncoding('binary');
req.pipe(stream);
req.on('end', function() {
respond(res, ['text/plain', msg]);
if (!LIVE) { return; }
var duration = 20;
var fd = {
fileName: num + '.webm',
filePath: fp,
duration: duration
};
var fileDataArr;
if (isFirst) {
fileDataArr = [];
fileDataArrs[prefix] = fileDataArr;
} else {
var fileDataArr = fileDataArrs[prefix];
}
try {
fileDataArr.push(fd);
} catch (err) {
fileDataArr = [];
console.log(err.message);
}
videoUtils.computeStartTimes(fileDataArr);
videoUtils.webm2Mpegts(fd, function(err, mpegtsFp) {
if (err) { return console.error(err); }
console.log('created %s', mpegtsFp);
var playlistFp = 'videos/' + prefix + '/playlist.m3u8';
var fileDataArr2 = (isLast ? fileDataArr : lastN(fileDataArr, PREV_ITEMS_IN_LIVE));
var action = (isFirst ? 'created' : (isLast ? 'finished' : 'updated'));
videoUtils.generateM3u8Playlist(fileDataArr2, playlistFp, !isLast, function(err) {
console.log('playlist %s %s', playlistFp, (err ? err.toString() : action));
});
});
runStreamServer(prefix);
}
You don't show us how you use MediaRecorder to generate your "chunks" of data. Do you you use its ondataavailable event for this purpose?
If so, please keep this in mind: You must concatenate all the chunks handed to you by ondataavailable to get a valid .webm (or .matroska) data stream.
You can't just store an arbitrary chunk of data in a media file and expect it to play. Even ffmpeg needs all your chunks streamed to it to generate valid output. That's because the first couple of chunks contain the mandatory .webm initialization segment, and the other chunks do not.
I need to call a javascript program which will get the ip address (from intranet) and send it to node js server where i have to do some calculation!
below is the JS file ipaddress.js:
var myIP = (function () {
return {
getIP: function () {
var ip_dups = {};
//compatibility for firefox and chrome
var RTCPeerConnection = window.RTCPeerConnection
|| window.mozRTCPeerConnection
|| window.webkitRTCPeerConnection;
var useWebKit = !!window.webkitRTCPeerConnection;
//bypass naive webrtc blocking using an iframe
if (!RTCPeerConnection) {
//NOTE: you need to have an iframe in the page right above the script tag
//
//<iframe id="iframe" sandbox="allow-same-origin" style="display: none"></iframe>
//<script>...getIPs called in here...
//
var win = iframe.contentWindow;
RTCPeerConnection = win.RTCPeerConnection
|| win.mozRTCPeerConnection
|| win.webkitRTCPeerConnection;
useWebKit = !!win.webkitRTCPeerConnection;
}
//minimal requirements for data connection
var mediaConstraints = {
optional: [{ RtpDataChannels: true }]
};
var servers = { iceServers: [{ urls: "stun:stun.services.mozilla.com" }] };
//construct a new RTCPeerConnection
var pc = new RTCPeerConnection(servers, mediaConstraints);
function handleCandidate(candidate) {
//match just the IP address
var ip_regex = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/
var ip_addr = ip_regex.exec(candidate)[1];
//remove duplicates
if (ip_dups[ip_addr] === undefined)
return (ip_addr);
ip_dups[ip_addr] = true;
}
//listen for candidate events
pc.onicecandidate = function (ice) {
//skip non-candidate events
if (ice.candidate)
handleCandidate(ice.candidate.candidate);
};
//create a bogus data channel
pc.createDataChannel("");
//create an offer sdp
pc.createOffer(function (result) {
//trigger the stun server request
pc.setLocalDescription(result, function () { }, function () { });
}, function () { });
//wait for a while to let everything done
setTimeout(function () {
//read candidate info from local description
var lines = pc.localDescription.sdp.split('\n');
lines.forEach(function (line) {
if (line.indexOf('a=candidate:') === 0)
handleCandidate(line);
});
}, 1000);
}
}
})(myIP() || {})
In angular program app.component.ts file:
import 'ipaddress.js'
declare var myIP;
....
ngOnInit(){
ip = myIP();
console.log(ip);
//send this ip to node server and do the validation!
}
I need myIP() function to return ip and program should wait until myIP() doesnot send result and then only further execution starts.
can anyone help me in this?
I have been developing a home automation system
Scenario:
ESP8266 sending keep alive to Rasp pi MQTT server
webpage on Chrome using IBM utility javascript Paho client
ESP sends alive every 10 secs and shows when it receives its own message including received time, this proves the server is sending the messages back on time.
Webpage(also has timer) displays the time messages are received with the message
Messages are received on the webpage in a random manner, by this I mean that no messages arrive for a long time then a glut arrives all at the same time
from the esp I can see that the messages are being received when the are published. there seems to be a problem in the webpage code
I am just wondering if anyone has seen this before and can point me in the right direction, my code is below:
thanks in advance
Dave
/*
Original Copyright (c) 2015 IBM Corp.
Eclipse Paho MQTT-JS Utility
This utility can be used to test MQTT brokers
its been bent by me to fit my needs
*/
// global variables
var MyLib = {}; // space for my bits
MyLib.theMessage = ""; // received message
MyLib.theTopic = ""; // received topic
MyLib.clientId = 'webRunpage2' + (Math.random() * 10);
MyLib.connected = false;
MyLib.ticker = setInterval(function(){MyLib.tickTime ++;}, 1000); // 5secs
MyLib.tickTime = 0;
MyLib.aliveTimer = setInterval(function(){keepMeAlive()}, 90000); // 1.5 mins
//=============================================================
function keepMeAlive() {
var topic='webpage', message='KeepAlive';
publish(topic, 1, message, false); // keeps the conection open
console.info("Alive Time: ", MyLib.tickTime);
}
//=============================================================
function onMessageArrived(message) {
MyLib.theTopic = message.destinationName; MyLib.theMessage = message.payloadString;
var topic = MyLib.theTopic;
var messg = MyLib.theMessage;
var id = messg.substring(0,6);
console.log('Message Recieved: Topic: ', message.destinationName, "Time ", MyLib.tickTime);
}
//=============================================================
function onFail(context) {
console.log("Failed to connect");
MyLib.connected = false;
}
//=============================================================
function connectionToggle(){
if(MyLib.connected){ disconnect();
} else { connect(); }
}
//=============================================================
function onConnect(context) {
// Once a connection has been made
console.log("Client Connected");
document.getElementById("status").value = "Connected";
MyLib.connected = true;
client.subscribe('LIGHTS/#'); // subscribe to all 'LIGHTS' members
}
//=================================================
// called when the client loses its connection
function onConnectionLost() {
console.log("Connection Lost: ");
document.getElementById("status").value = "Connection Lost";
MyLib.connected = false;
connectionToggle();
}
//=============================================================
function connect(){
var hostname = "192.168.1.19";
var port = 1884;
var clientId = MyLib.clientId;
var path = "/ws";
var user = "dave";
var pass = "vineyard01";
var keepAlive = 120; // 2 mins stay alive
var timeout = 3;
var ssl = false;
var cleanSession = true; //*******************
var lastWillTopic = "lastwill";
var lastWillQos = 0;
var lastWillRetain = false;
var lastWillMessage = "its Broken";
if(path.length > 0){
client = new Paho.MQTT.Client(hostname, Number(port), path, clientId);
} else {
client = new Paho.MQTT.Client(hostname, Number(port), clientId);
}
// console.info('Connecting to Server: Hostname: ', hostname, '. Port: ', port, '. Path: ', client.path, '. Client ID: ', clientId);
// set callback handlers
client.onConnectionLost = onConnectionLost;
client.onMessageArrived = onMessageArrived;
var options = {
invocationContext: {host : hostname, port: port, path: client.path, clientId: clientId},
timeout: timeout,
keepAliveInterval:keepAlive,
cleanSession: cleanSession,
useSSL: ssl,
onSuccess: onConnect,
onFailure: onFail
};
if(user.length > 0){ options.userName = user; }
if(pass.length > 0){ options.password = pass; }
if(lastWillTopic.length > 0){
var lastWillMessage = new Paho.MQTT.Message(lastWillMessage);
lastWillMessage.destinationName = lastWillTopic;
lastWillMessage.qos = lastWillQos;
lastWillMessage.retained = lastWillRetain;
options.willMessage = lastWillMessage;
}
// connect the client
client.connect(options);
}
//=============================================================
function disconnect(){
// console.info('Disconnecting from Server');
client.disconnect();
MyLib.connected = false;
}
//=============================================================
function publish(topic, qos, message, retain){
// console.info('Publishing Message: Topic: ', topic, '. QoS: ' + qos + '. Message: ', message, '. Retain: ', retain);
message = new Paho.MQTT.Message(message);
message.destinationName = topic;
message.qos = Number(qos);
message.retained = retain;
client.send(message);
}
//=============================================================
function subscribe(topic){
var qos = 1;
client.subscribe(topic, {qos: Number(qos)});
}
//=============================================================
// left next 4 functions but not used
function unsubscribe(topic){
client.unsubscribe(topic, {
onSuccess: unsubscribeSuccess,
onFailure: unsubscribeFailure,
invocationContext: {topic : topic}
});
}
//=============================================================
function unsubscribeSuccess(context){
// console.info('Successfully unsubscribed from ', context.invocationContext.topic);
}
//=============================================================
function unsubscribeFailure(context){
// console.info('Failed to unsubscribe from ', context.invocationContext.topic);
}
//=============================================================
// Just in case someone sends html
function safe_tags_regex(str) {
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
}
//=============================================================
I am trying to stream MP3 file from a nodeJS server using BinaryJS - http://binaryjs.com/
But, when I am decoding the buffers on the client side they are seems to be overlapping, Meaning that the new chunk of data is being played few milliseconds before the previous one ended, causing the audio to lag.
is there any way to make the client wait until the current buffer is finished before starting the new one?
Server:
var BinaryServer = require('binaryjs').BinaryServer;
var fs = require('fs');
var server = BinaryServer({port: 9000});
server.on('connection', function(client){
var file = fs.createReadStream(__dirname + '/Song.mp3', {
'flags': 'r',
'bufferSize': 4 * 1024
});
});
client.send(file);
});
Client:
var client = new BinaryClient('ws://localhost:9000');
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
client.on('stream', function (stream, meta) {
var parts = [];
var last = 0;
stream.on('data', function (data) {
var source = context.createBufferSource();
context.decodeAudioData(data, function (buf) {
source.buffer = buf;
source.connect(context.destination);
source.loop = false;
source.start(last);
last += buf.duration;
source.onended = function() {
console.log('Your audio has finished playing');
};
},
function (e) {
"Error with decoding audio data" + e.err
});
parts.push(data);
});
stream.on('end', function () {
console.log(parts);
});
});
Not sure about this, but instead of initializing last to 0, you might want to initialize it to context.currentTime.