-
-
Save kevinGodell/3ee1ae42bd54f03f6083355da8d74f43 to your computer and use it in GitHub Desktop.
FFMPEG to Web Browser with Express, Socket.IO and JSMPEG
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Shinobi (http://shinobi.video) - FFMPEG H.264 over HTTP Test | |
// How to Use raw H.264 (Simulated RTSP) | |
// 1. Start with `node ffmpegToWeb.js` | |
// 2. Get the IP address of the computer where you did step 1. Example : 127.0.0.1 | |
// 3. Open VLC and "Open Network Stream". | |
// 4. Input the following without quotes : `http://127.0.0.1:8001/h264` and start. | |
var child = require('child_process'); | |
var io = require('socket.io'); | |
var events = require('events'); | |
var express = require('express') | |
var app = express(); | |
var server = require('http').Server(app); | |
var io = require('socket.io')(server); | |
var spawn = child.spawn; | |
var exec = child.exec; | |
var Emitters = {} | |
var config = { | |
port:8001, | |
url:'rtsp://131.95.3.162/axis-media/media.3gp' | |
} | |
var initEmitter = function(feed){ | |
if(!Emitters[feed]){ | |
Emitters[feed] = new events.EventEmitter().setMaxListeners(0) | |
} | |
return Emitters[feed] | |
} | |
//web app | |
console.log('Starting Express Web Server on Port '+config.port) | |
server.listen(config.port); | |
app.get('/', function (req, res) { | |
res.sendFile(__dirname + '/index.html'); | |
}) | |
//ffmpeg pushed stream in here to make a pipe | |
app.all('/streamIn/:feed', function (req, res) { | |
req.Emitter = initEmitter(req.params.feed) | |
//req.params.feed = Feed Number (Pipe Number) | |
res.connection.setTimeout(0); | |
req.on('data', function(buffer){ | |
req.Emitter.emit('data',buffer) | |
io.to('STREAM_'+req.params.feed).emit('h264',{feed:req.params.feed,buffer:buffer}) | |
}); | |
req.on('end',function(){ | |
console.log('close'); | |
}); | |
}) | |
//socket.io client commands | |
io.on('connection', function (cn) { | |
cn.on('f',function (data) { | |
switch(data.function){ | |
case'getStream': | |
console.log(data) | |
cn.join('STREAM_'+data.feed) | |
break; | |
} | |
}) | |
}); | |
//simulate RTSP over HTTP | |
app.get(['/h264','/h264/:feed'], function (req, res) { | |
if(!req.params.feed){req.params.feed='1'} | |
req.Emitter = initEmitter(req.params.feed) | |
var contentWriter | |
var date = new Date(); | |
res.writeHead(200, { | |
'Date': date.toUTCString(), | |
'Connection': 'keep-alive', | |
'Cache-Control': 'no-cache', | |
'Pragma': 'no-cache', | |
'Content-Type': 'video/mp4', | |
'Server': 'Shinobi H.264 Test Stream', | |
}); | |
req.Emitter.on('data',contentWriter=function(buffer){ | |
res.write(buffer) | |
}) | |
res.on('close', function () { | |
req.Emitter.removeListener('data',contentWriter) | |
}) | |
}); | |
//ffmpeg | |
console.log('Starting FFMPEG') | |
var ffmpegString = '-i '+config.url+'' | |
ffmpegString += ' -f mpegts -c:v copy -an http://localhost:'+config.port+'/streamIn/1' | |
ffmpegString += ' -f mpegts -c:v copy -an http://localhost:'+config.port+'/streamIn/2' | |
if(ffmpegString.indexOf('rtsp://')>-1){ | |
ffmpegString='-rtsp_transport tcp '+ffmpegString | |
} | |
console.log('Executing : ffmpeg '+ffmpegString) | |
var ffmpeg = spawn('ffmpeg',ffmpegString.split(' ')); | |
ffmpeg.on('close', function (buffer) { | |
console.log('ffmpeg died') | |
}) | |
//ffmpeg.stderr.on('data', function (buffer) { | |
// console.log(buffer.toString()) | |
//}); | |
//ffmpeg.stdout.on('data', function (buffer) { | |
// Emitter.emit('data',buffer) | |
//}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="http://cdn.shinobi.video/js/socket.io.js"></script> | |
<script src="http://cdn.shinobi.video/js/jquery.min.js"></script> | |
<script src="http://cdn.shinobi.video/js/jsmpeg.pipe.js"></script> | |
<canvas id="canvas" height=500 width=500></canvas> | |
<script> | |
var socket = io(); | |
console.log(socket) | |
socket.on('connect',function(){ | |
socket.emit('f',{function:'getStream',feed:'2'}) | |
}) | |
var player = new JSMpeg.Player('pipe',{ | |
canvas:document.getElementById('canvas') | |
}); | |
socket.on('h264', function (data) { | |
console.log(data) | |
player.write(data.buffer) | |
}); | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "ffmpegtoweb", | |
"version": "1.0.0", | |
"description": "Shinobi Testing Tool for H.264 over HTTP and Socket.IO", | |
"main": "ffmpegToWeb.js", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1" | |
}, | |
"dependencies": { | |
"express": "^4.14.0", | |
"socket.io": "^1.7.1" | |
}, | |
"author": "Moe Alam", | |
"license": "MIT" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment