• Stars
    star
    5,956
  • Rank 6,784 (Top 0.2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 10 years ago
  • Updated 3 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A Node.js implementation of RTMP/HTTP-FLV/WS-FLV/HLS/DASH/MP4 Media Server

Node-Media-Server

npm npm npm npm Join the chat at https://gitter.im/Illuspas/Node-Media-Server

A Node.js implementation of RTMP/HTTP-FLV/WS-FLV/HLS/DASH Media Server
中文介绍

NodeMediaServer V3

https://www.nodemedia.cn/product/node-media-server/

Web Admin Panel Source

https://github.com/illuspas/Node-Media-Server-Admin

Web Admin Panel Screenshot

http://server_ip:8000/admin

admin preview

Features

  • Cross platform support Windows/Linux/Unix
  • Support H.264/AAC/MP3/SPEEX/NELLYMOSER/G.711
  • Extension support H.265(flv_id=12)/OPUS(flv_id=13)
  • Support GOP cache
  • Support remux to LIVE-HTTP/WS-FLV, Support NodePlayer.js playback
  • Support remux to HLS/DASH/MP4
  • Support xycdn style authentication
  • Support event callback
  • Support https/wss
  • Support Server Monitor
  • Support Rtsp/Rtmp relay
  • Support api control relay
  • Support real-time multi-resolution transcoding
  • Support Enhancing RTMP, FLV (HEVC/AV1 encoding using OBS)

Usage

npx

npx node-media-server

install as a global program

npm i node-media-server -g
node-media-server

docker version

docker run --name nms -d -p 1935:1935 -p 8000:8000 -p 8443:8443 illuspas/node-media-server

npm version (recommended)

mkdir nms
cd nms
npm install node-media-server
vi app.js
const NodeMediaServer = require('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

Publishing live streams

From FFmpeg

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

From OBS

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)

Accessing the live stream

RTMP

rtmp://localhost/live/STREAM_NAME

http-flv

http://localhost:8000/live/STREAM_NAME.flv

websocket-flv

ws://localhost:8000/live/STREAM_NAME.flv

HLS

http://localhost:8000/live/STREAM_NAME/index.m3u8

DASH

http://localhost:8000/live/STREAM_NAME/index.mpd

via flv.js over http-flv

<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>

via flv.js over websocket-flv

<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>

Logging

Modify the logging type

It is now possible to modify the logging type which determines which console outputs are shown.

There are a total of 4 possible options:

  • 0 - Don't log anything
  • 1 - Log errors
  • 2 - Log errors and generic info
  • 3 - Log everything (debug)

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();

Authentication

Encryption URL consists of:

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

H.265 over RTMP

AV1 over RTMP

  • OBS 29.1+

Event callback

......
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)}`);
});

Https/Wss

Generate certificate

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

Config https

const NodeMediaServer = require('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();

Accessing

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.

API

Protected API

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

Server stats

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
  }
}

Streams stats

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"
        }
      ]
    }
  }
}

Remux to HLS/DASH live stream

const NodeMediaServer = require('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();

Remux to RTMP/HLS/DASH live stream with audio transcode

const NodeMediaServer = require('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

Record to MP4

const NodeMediaServer = require('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();

Rtsp/Rtmp Relay

NodeMediaServer implement RTSP and RTMP relay with ffmpeg.

Static pull

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:[email protected]: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'
      }
  ]
}

Dynamic pull

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',
    }
  ]
}

Dynamic push

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',
    }
  ]
}

Fission

Real-time transcoding multi-resolution output fission

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",
        },
      ]
    },
  ]
}

Publisher and Player App/SDK

Android Livestream App

https://play.google.com/store/apps/details?id=cn.nodemedia.qlive
http://www.nodemedia.cn/uploads/qlive-release.apk

Android SDK

https://github.com/NodeMedia/NodeMediaClient-Android

iOS SDK

https://github.com/NodeMedia/NodeMediaClient-iOS

React-Native SDK

https://github.com/NodeMedia/react-native-nodemediaclient

NodePlayer.js HTML5 live player

  • Implemented with asm.js / wasm
  • http-flv/ws-flv
  • H.264/H.265 + AAC/Nellymoser/G.711 decoder
  • Ultra low latency
  • All modern browsers are supported

https://www.nodemedia.cn/product/nodeplayer-js/

More Repositories

1

nginx-rtmp-win32

Nginx-rtmp-module Windows builds.
XSLT
982
star
2

libyuv-android

Build Google libyuv with NDK for Android
C++
234
star
3

NodePlayer.js

Pure JavaScrip HTML5 live stream player
197
star
4

Node-Media-Server-Admin

JavaScript
111
star
5

SayHi

Native audio recording/playing (OpenSL ES) and speex encoding/decoding,transport by rtmp.
C
76
star
6

NodeMediaDevClient

Flex开发的RTMP视频推流播放测试工具
HTML
53
star
7

SayHey

iOS rtmp speex
C
48
star
8

VoAACEncoder

Android aac encoder using voaac
C
32
star
9

NodeMediaClient-Web

NodeMedia RTMP Publisher/Player for web (OpenSource)
JavaScript
18
star
10

libaec-android

echo cancellation module port from webrtc
C
16
star
11

libsrs_rtmp-android

Build libsrs_rtmp for android
C++
15
star
12

libyuv-iOS

Build Google libyuv with xcodebuild for iOS
C++
15
star
13

pro-fiv.js

Professional HTML5 FLV Player
JavaScript
13
star
14

tsdebugger

12
star
15

NodeMediaDevice

C
8
star
16

libspeex-Android

Build libspeex with Android NDK
C
6
star
17

xcgo

CGO Cross Compiler
Dockerfile
6
star
18

icedemo-android

icedemo for Android
C
5
star
19

librtmp-android

C
5
star
20

Red5-Publisher

Red5 RTMP 发布播放工具,更新为Flex4.6 SDK,支持了H.264视频编码,Speex音频编码
ActionScript
4
star
21

node-ffmpeg-pro

Nodejs ffmpeg process caller
JavaScript
4
star
22

webrtc-audio-processing

C
3
star
23

nodeplayer-uniapp

uni-app 集成NodePlayer.js 开发直播app的Demo
Vue
3
star
24

LiveVideoGameLaya

JavaScript
2
star
25

rtmp-bench

JavaScript
2
star
26

rtmploader

2
star
27

state-threads-win32

WIN32 API state threads
C
2
star
28

libilbc-Android

Build libilbc with Android NDK
C
1
star
29

bitop.js

bit operation for nodejs
JavaScript
1
star
30

nginx-rtmp-embedded-linux

nginx-rtmp-module embedded linux builds
1
star
31

LiveVideoGame

使用白鹭引擎集成NodePlayer.js-wasm版开发视频直播游戏Demo
JavaScript
1
star