Last active
May 1, 2024 12:29
-
-
Save moeiscool/e7b0d6a1d3f78d058336f6b56da8dc34 to your computer and use it in GitHub Desktop.
FLV Live Stream to Web Page with flv.js, FFMPEG, and Express Web Server (Node.js)
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 FLV over HTTP Test | |
// How to Use | |
// 1. Navigate to directory where this file is. | |
// 2. Run `npm install express` | |
// 3. Start with `node ffmpegToWeb.js` | |
// 4. Get the IP address of the computer where you did step 1. Example : 127.0.0.1 | |
// 5. Open `http://127.0.0.1:8001/` in your browser. | |
var child = require('child_process'); | |
var events = require('events'); | |
var express = require('express') | |
var app = express(); | |
var server = require('http').Server(app); | |
var spawn = child.spawn; | |
var exec = child.exec; | |
var Emitters = {} | |
var firstChunks = {} | |
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] | |
} | |
//hold first chunk of FLV video | |
var initFirstChunk = function(feed,firstBuffer){ | |
if(!firstChunks[feed]){ | |
firstChunks[feed] = firstBuffer | |
} | |
return firstChunks[feed] | |
} | |
console.log('Starting Express Web Server on Port '+config.port) | |
//start webserver | |
server.listen(config.port); | |
//make libraries static | |
app.use('/libs',express.static(__dirname + '/../../web/libs')); | |
app.use('/',express.static(__dirname + '/')); | |
//homepage with video element. | |
//static file send of index.html | |
app.get('/', function (req, res) { | |
res.sendFile(__dirname + '/index.html'); | |
}) | |
//// FLV over HTTP, this URL goes in the flv.js javascript player | |
// see ./index.html | |
app.get(['/flv','/flv/:feed/s.flv'], function (req, res) { | |
//default to first feed | |
if(!req.params.feed){req.params.feed='1'} | |
//get emitter | |
req.Emitter = initEmitter(req.params.feed) | |
//variable name of contentWriter | |
var contentWriter | |
//set headers | |
res.setHeader('Content-Type', 'video/x-flv'); | |
res.setHeader('Access-Control-Allow-Origin','*'); | |
//write first frame on stream | |
res.write(initFirstChunk(1)) | |
//write new frames as they happen | |
req.Emitter.on('data',contentWriter=function(buffer){ | |
res.write(buffer) | |
}) | |
//remove contentWriter when client leaves | |
res.on('close', function () { | |
req.Emitter.removeListener('data',contentWriter) | |
}) | |
}); | |
//ffmpeg | |
console.log('Starting FFMPEG') | |
var ffmpegString = '-i '+config.url+' -c:v copy -an -f flv pipe:1' | |
//var ffmpegString = '-i '+config.url+' -c:v libx264 -preset superfast -tune zerolatency -c:a aac -ar 44100 -f flv pipe:4' | |
//ffmpegString += ' -f mpegts -c:v mpeg1video -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(' '),{stdio:['pipe','pipe','pipe','pipe','pipe']}); | |
ffmpeg.on('close', function (buffer) { | |
console.log('ffmpeg died') | |
}) | |
//// FFMPEG Error Logs | |
//ffmpeg.stderr.on('data', function (buffer) { | |
// console.log(buffer.toString()) | |
//}); | |
//data from pipe:1 output of ffmpeg | |
ffmpeg.stdio[1].on('data', function (buffer) { | |
initFirstChunk(1,buffer) | |
initEmitter(1).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
<!doctype html> | |
<!--www.shinobi.video--> | |
<html lang="en-US"> | |
<head> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta charset="UTF-8"> | |
<title>FLV to Web Test by Shinobi Systems</title> | |
<!--FLV Live Player--> | |
<script src="http://cdn.shinobi.video/js/flv.min.js"></script> | |
</head> | |
<body> | |
<video id="videoElement"></video> | |
<script> | |
if (flvjs.isSupported()) { | |
var videoElement = document.getElementById('videoElement'); | |
var flvPlayer = flvjs.createPlayer({ | |
type: 'flv', | |
isLive: true, | |
url: '/flv/1/s.flv' | |
}); | |
flvPlayer.attachMediaElement(videoElement); | |
flvPlayer.on('error',function(err){ | |
console.log(err) | |
}); | |
flvPlayer.load(); | |
flvPlayer.play(); | |
} | |
</script> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment