Security News
Fluent Assertions Faces Backlash After Abandoning Open Source Licensing
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
custom-node-media-server
Advanced tools
npx custom-node-media-server
npm i custom-node-media-server -g
custom-node-media-server
docker run --name nms -d -p 1935:1935 -p 8000:8000 -p 8443:8443 hunglsx/node-media-server
mkdir nms
cd nms
npm install custom-node-media-server
vi app.js
const NodeMediaServer = require('custom-node-media-server');
const config = {
rtmp: {
port: 1935,
chunk_size: 60000,
gop_cache: true,
ping: 30,
ping_timeout: 60
},
http: {
port: 8000,
allow_origin: '*'
}
};
var nms = new NodeMediaServer(config)
nms.run();
node app.js
If you have a video file with H.264 video and AAC audio:
ffmpeg -re -i INPUT_FILE_NAME -c copy -f flv rtmp://localhost/live/STREAM_NAME
Or if you have a video file that is encoded in other audio/video format:
ffmpeg -re -i INPUT_FILE_NAME -c:v libx264 -preset veryfast -tune zerolatency -c:a aac -ar 44100 -f flv rtmp://localhost/live/STREAM_NAME
Settings -> Stream
Stream Type : Custom Streaming Server
URL : rtmp://localhost/live
Stream key : STREAM_NAME?sign=expires-HashValue (sign parameter required only if publish auth is enabled)
rtmp://localhost/live/STREAM_NAME
http://localhost:8000/live/STREAM_NAME.flv
ws://localhost:8000/live/STREAM_NAME.flv
http://localhost:8000/live/STREAM_NAME/index.m3u8
http://localhost:8000/live/STREAM_NAME/index.mpd
<script src="https://cdn.bootcss.com/flv.js/1.5.0/flv.min.js"></script>
<video id="videoElement"></video>
<script>
if (flvjs.isSupported()) {
var videoElement = document.getElementById('videoElement');
var flvPlayer = flvjs.createPlayer({
type: 'flv',
url: 'http://localhost:8000/live/STREAM_NAME.flv'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
</script>
<script src="https://cdn.bootcss.com/flv.js/1.5.0/flv.min.js"></script>
<video id="videoElement"></video>
<script>
if (flvjs.isSupported()) {
var videoElement = document.getElementById('videoElement');
var flvPlayer = flvjs.createPlayer({
type: 'flv',
url: 'ws://localhost:8000/live/STREAM_NAME.flv'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
</script>
It is now possible to modify the logging type which determines which console outputs are shown.
There are a total of 4 possible options:
Modifying the logging type is easy - just add a new value logType
in the config and set it to a value between 0 and 4.
By default, this is set to show errors and generic info internally (setting 2).
const NodeMediaServer = require('node-media-server');
const config = {
logType: 3,
rtmp: {
port: 1935,
chunk_size: 60000,
gop_cache: true,
ping: 30,
ping_timeout: 60
},
http: {
port: 8000,
allow_origin: '*'
}
};
var nms = new NodeMediaServer(config)
nms.run();
rtmp://hostname:port/appname/stream?sign=expires-HashValue
http://hostname:port/appname/stream.flv?sign=expires-HashValue
ws://hostname:port/appname/stream.flv?sign=expires-HashValue
1.Publish or play address:
rtmp://192.168.0.10/live/stream
2.Config set auth->secret: 'nodemedia2017privatekey'
const config = {
rtmp: {
port: 1935,
chunk_size: 60000,
gop_cache: true,
ping: 30,
ping_timeout: 60
},
http: {
port: 8000,
allow_origin: '*'
},
auth: {
play: true,
publish: true,
secret: 'nodemedia2017privatekey'
}
}
3.expiration time: 2017/8/23 11:25:21 ,The calculated expiration timestamp is
1503458721
4.The combination HashValue is:
HashValue = md5("/live/stream-1503458721-nodemedia2017privatekey”)
HashValue = 80c1d1ad2e0c2ab63eebb50eed64201a
5.Final request address
rtmp://192.168.0.10/live/stream?sign=1503458721-80c1d1ad2e0c2ab63eebb50eed64201a
The 'sign' keyword can not be modified
......
nms.run();
nms.on('preConnect', (id, args) => {
console.log('[NodeEvent on preConnect]', `id=${id} args=${JSON.stringify(args)}`);
// let session = nms.getSession(id);
// session.reject();
});
nms.on('postConnect', (id, args) => {
console.log('[NodeEvent on postConnect]', `id=${id} args=${JSON.stringify(args)}`);
});
nms.on('doneConnect', (id, args) => {
console.log('[NodeEvent on doneConnect]', `id=${id} args=${JSON.stringify(args)}`);
});
nms.on('prePublish', (id, StreamPath, args) => {
console.log('[NodeEvent on prePublish]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
// let session = nms.getSession(id);
// session.reject();
});
nms.on('postPublish', (id, StreamPath, args) => {
console.log('[NodeEvent on postPublish]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
});
nms.on('donePublish', (id, StreamPath, args) => {
console.log('[NodeEvent on donePublish]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
});
nms.on('prePlay', (id, StreamPath, args) => {
console.log('[NodeEvent on prePlay]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
// let session = nms.getSession(id);
// session.reject();
});
nms.on('postPlay', (id, StreamPath, args) => {
console.log('[NodeEvent on postPlay]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
});
nms.on('donePlay', (id, StreamPath, args) => {
console.log('[NodeEvent on donePlay]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
});
openssl genrsa -out privatekey.pem 1024
openssl req -new -key privatekey.pem -out certrequest.csr
openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem
const NodeMediaServer = require('custom-node-media-server');
const config = {
rtmp: {
port: 1935,
chunk_size: 60000,
gop_cache: true,
ping: 30,
ping_timeout: 60
},
http: {
port: 8000,
allow_origin: '*'
},
https: {
port: 8443,
key:'./privatekey.pem',
cert:'./certificate.pem',
}
};
var nms = new NodeMediaServer(config)
nms.run();
https://localhost:8443/live/STREAM_NAME.flv
wss://localhost:8443/live/STREAM_NAME.flv
In the browser environment, Self-signed certificates need to be added with trust before they can be accessed.
const config = {
.......
auth: {
api : true,
api_user: 'admin',
api_pass: 'nms2018',
},
......
}
Based on the basic auth,Please change your password. The default is not turned on
http://localhost:8000/api/server
{
"os": {
"arch": "x64",
"platform": "darwin",
"release": "16.7.0"
},
"cpu": {
"num": 8,
"load": 12,
"model": "Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz",
"speed": 3592
},
"mem": {
"totle": 8589934592,
"free": 754126848
},
"net": {
"inbytes": 6402345,
"outbytes": 6901489
},
"nodejs": {
"uptime": 109,
"version": "v8.9.0",
"mem": {
"rss": 59998208,
"heapTotal": 23478272,
"heapUsed": 15818096,
"external": 3556366
}
},
"clients": {
"accepted": 207,
"active": 204,
"idle": 0,
"rtmp": 203,
"http": 1,
"ws": 0
}
}
http://localhost:8000/api/streams
{
"live": {
"s": {
"publisher": {
"app": "live",
"stream": "s",
"clientId": "U3UYQ02P",
"connectCreated": "2017-12-21T02:29:13.594Z",
"bytes": 190279524,
"ip": "::1",
"audio": {
"codec": "AAC",
"profile": "LC",
"samplerate": 48000,
"channels": 6
},
"video": {
"codec": "H264",
"width": 1920,
"height": 1080,
"profile": "Main",
"level": 4.1,
"fps": 24
}
},
"subscribers": [
{
"app": "live",
"stream": "s",
"clientId": "H227P4IR",
"connectCreated": "2017-12-21T02:31:35.278Z",
"bytes": 18591846,
"ip": "::ffff:127.0.0.1",
"protocol": "http"
},
{
"app": "live",
"stream": "s",
"clientId": "ZNULPE9K",
"connectCreated": "2017-12-21T02:31:45.394Z",
"bytes": 8744478,
"ip": "::ffff:127.0.0.1",
"protocol": "ws"
},
{
"app": "live",
"stream": "s",
"clientId": "C5G8NJ30",
"connectCreated": "2017-12-21T02:31:51.736Z",
"bytes": 2046073,
"ip": "::ffff:192.168.0.91",
"protocol": "rtmp"
}
]
},
"stream": {
"publisher": null,
"subscribers": [
{
"app": "live",
"stream": "stream",
"clientId": "KBH4PCWB",
"connectCreated": "2017-12-21T02:31:30.245Z",
"bytes": 0,
"ip": "::ffff:127.0.0.1",
"protocol": "http"
}
]
}
}
}
const NodeMediaServer = require('custom-node-media-server');
const config = {
rtmp: {
port: 1935,
chunk_size: 60000,
gop_cache: true,
ping: 30,
ping_timeout: 60
},
http: {
port: 8000,
mediaroot: './media',
allow_origin: '*'
},
trans: {
ffmpeg: '/usr/local/bin/ffmpeg',
tasks: [
{
app: 'live',
hls: true,
hlsFlags: '[hls_time=2:hls_list_size=3:hls_flags=delete_segments]',
hlsKeep: true, // to prevent hls file delete after end the stream
dash: true,
dashFlags: '[f=dash:window_size=3:extra_window_size=5]',
dashKeep: true // to prevent dash file delete after end the stream
}
]
}
};
var nms = new NodeMediaServer(config)
nms.run();
const NodeMediaServer = require('custom-node-media-server');
const config = {
rtmp: {
port: 1935,
chunk_size: 60000,
gop_cache: true,
ping: 30,
ping_timeout: 60
},
http: {
port: 8000,
mediaroot: './media',
allow_origin: '*'
},
trans: {
ffmpeg: '/usr/local/bin/ffmpeg',
tasks: [
{
app: 'live',
vc: "copy",
vcParam: [],
ac: "aac",
acParam: ['-ab', '64k', '-ac', '1', '-ar', '44100'],
rtmp:true,
rtmpApp:'live2',
hls: true,
hlsFlags: '[hls_time=2:hls_list_size=3:hls_flags=delete_segments]',
dash: true,
dashFlags: '[f=dash:window_size=3:extra_window_size=5]'
}
]
}
};
var nms = new NodeMediaServer(config)
nms.run();
Remux to RTMP cannot use the same app name
const NodeMediaServer = require('custom-node-media-server');
const config = {
rtmp: {
port: 1935,
chunk_size: 60000,
gop_cache: true,
ping: 30,
ping_timeout: 60
},
http: {
port: 8000,
mediaroot: './media',
allow_origin: '*'
},
trans: {
ffmpeg: '/usr/local/bin/ffmpeg',
tasks: [
{
app: 'live',
mp4: true,
mp4Flags: '[movflags=frag_keyframe+empty_moov]',
}
]
}
};
var nms = new NodeMediaServer(config)
nms.run();
NodeMediaServer implement RTSP and RTMP relay with ffmpeg.
The static pull mode is executed at service startup and reconnect after failure. It could be a live stream or a file. In theory, it is not limited to RTSP or RTMP protocol.
relay: {
ffmpeg: '/usr/local/bin/ffmpeg',
tasks: [
{
app: 'cctv',
mode: 'static',
edge: 'rtsp://admin:admin888@192.168.0.149:554/ISAPI/streaming/channels/101',
name: '0_149_101',
rtsp_transport : 'tcp' //['udp', 'tcp', 'udp_multicast', 'http']
}, {
app: 'iptv',
mode: 'static',
edge: 'rtmp://live.hkstv.hk.lxdns.com/live/hks',
name: 'hks'
}, {
app: 'mv',
mode: 'static',
edge: '/Volumes/ExtData/Movies/Dancing.Queen-SD.mp4',
name: 'dq'
}
]
}
When the local server receives a play request. If the stream does not exist, pull the stream from the configured edge server to local. When the stream is not played by the client, it automatically disconnects.
relay: {
ffmpeg: '/usr/local/bin/ffmpeg',
tasks: [
{
app: 'live',
mode: 'pull',
edge: 'rtmp://192.168.0.20',
}
]
}
When the local server receives a publish request. Automatically push the stream to the edge server.
relay: {
ffmpeg: '/usr/local/bin/ffmpeg',
tasks: [
{
app: 'live',
mode: 'push',
edge: 'rtmp://192.168.0.10',
}
]
}
Real-time transcoding multi-resolution output
fission: {
ffmpeg: '/usr/local/bin/ffmpeg',
tasks: [
{
rule: "game/*",
model: [
{
ab: "128k",
vb: "1500k",
vs: "1280x720",
vf: "30",
},
{
ab: "96k",
vb: "1000k",
vs: "854x480",
vf: "24",
},
{
ab: "96k",
vb: "600k",
vs: "640x360",
vf: "20",
},
]
},
{
rule: "show/*",
model: [
{
ab: "128k",
vb: "1500k",
vs: "720x1280",
vf: "30",
},
{
ab: "96k",
vb: "1000k",
vs: "480x854",
vf: "24",
},
{
ab: "64k",
vb: "600k",
vs: "360x640",
vf: "20",
},
]
},
]
}
https://play.google.com/store/apps/details?id=cn.nodemedia.qlive
http://www.nodemedia.cn/uploads/qlive-release.apk
https://github.com/NodeMedia/NodeMediaClient-Android
https://github.com/NodeMedia/NodeMediaClient-iOS
https://github.com/NodeMedia/react-native-nodemediaclient
http://www.nodemedia.cn/products/node-media-player
http://www.nodemedia.cn/products/node-media-client/win
Sorng Sothearith, standifer1023, floatflower, Christopher Thomas, strive, jaysonF, 匿名, 李勇, 巴草根, ZQL, 陈勇至, -Y, 高山流水, 老郭, 孙建, 不说本可以, Jacky, 人走茶凉,树根, 疯狂的台灯, 枫叶, lzq, 番茄, smicroz , kasra.shahram, 熊科辉, Ken Lee , Erik Herz, Javier Gomez, trustfarm, leeoxiang, Aaron Turner, Anonymous
Thank you for your support.
FAQs
A Node.js implementation of RTMP Server
The npm package custom-node-media-server receives a total of 1 weekly downloads. As such, custom-node-media-server popularity was classified as not popular.
We found that custom-node-media-server demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Fluent Assertions is facing backlash after dropping the Apache license for a commercial model, leaving users blindsided and questioning contributor rights.
Research
Security News
Socket researchers uncover the risks of a malicious Python package targeting Discord developers.
Security News
The UK is proposing a bold ban on ransomware payments by public entities to disrupt cybercrime, protect critical services, and lead global cybersecurity efforts.