diff --git a/README.md b/README.md
index 59751225..1614a2a2 100644
--- a/README.md
+++ b/README.md
@@ -1,51 +1,68 @@
# Node-Media-Server
+
[![npm](https://img.shields.io/node/v/node-media-server.svg)](https://nodejs.org/en/)
[![npm](https://img.shields.io/npm/v/node-media-server.svg)](https://npmjs.org/package/node-media-server)
[![npm](https://img.shields.io/npm/dm/node-media-server.svg)](https://npmjs.org/package/node-media-server)
-[![npm](https://img.shields.io/npm/l/node-media-server.svg)](LICENSE)
+[![npm](https://img.shields.io/npm/l/node-media-server.svg)](LICENSE)
[![Join the chat at https://gitter.im/Illuspas/Node-Media-Server](https://badges.gitter.im/Illuspas/Node-Media-Server.svg)](https://gitter.im/Illuspas/Node-Media-Server?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+## Status
+
+[![Codacy Badge](https://app.codacy.com/project/badge/Grade/7d88520caba84fec95830312a4407058)](https://www.codacy.com/gh/illuspas/Node-Media-Server/dashboard?utm_source=github.com&utm_medium=referral&utm_content=illuspas/Node-Media-Server&utm_campaign=Badge_Grade)
+![GitHub repo size](https://img.shields.io/github/repo-size/illuspas/Node-Media-Server?style=flat-square)
+![Lines of code](https://img.shields.io/tokei/lines/github/illuspas/Node-Media-Server?style=flat-square)
+
+![GitHub pull requests](https://img.shields.io/github/issues-pr-raw/illuspas/Node-Media-Server?style=flat-square)
+![GitHub issues](https://img.shields.io/github/issues/illuspas/Node-Media-Server?style=flat-square) ![GitHub forks](https://img.shields.io/github/forks/illuspas/Node-Media-Server?style=flat-square) ![GitHub Repo stars](https://img.shields.io/github/stars/illuspas/Node-Media-Server?style=flat-square) ![GitHub watchers](https://img.shields.io/github/watchers/illuspas/Node-Media-Server?style=flat-square)
+
![logo](https://www.nodemedia.cn/uploads/site_logo.png)
A Node.js implementation of RTMP/HTTP-FLV/WS-FLV/HLS/DASH Media Server
-[中文介绍](https://github.com/illuspas/Node-Media-Server/blob/master/README_CN.md)
+[中文介绍](https://github.com/illuspas/Node-Media-Server/blob/master/README_CN.md)
**If you like this project you can support me.**
# NMSv3
+
https://github.com/NodeMedia/NodeMediaServer
# Web Admin Panel Source
+
[https://github.com/illuspas/Node-Media-Server-Admin](https://github.com/illuspas/Node-Media-Server-Admin)
# Web Admin Panel Screenshot
+
[http://server_ip:8000/admin](http://server_ip:8000/admin)
![admin](https://raw.githubusercontent.com/illuspas/resources/master/img/admin_panel_dashboard.png)
![preview](https://raw.githubusercontent.com/illuspas/resources/master/img/admin_panel_streams_preview.png)
# Features
- - Cross platform support Windows/Linux/Unix
- - Support H.264/H.265/AAC/MP3/SPEEX/NELLYMOSER/G.711
- - Support GOP cache
- - Support remux to LIVE-HTTP/WS-FLV,Support [NodePlayer.js](https://www.nodemedia.cn/product/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
-
-# Usage
+
+- Cross platform support Windows/Linux/Unix
+- Support H.264/H.265/AAC/MP3/SPEEX/NELLYMOSER/G.711
+- Support GOP cache
+- Support remux to LIVE-HTTP/WS-FLV,Support [NodePlayer.js](https://www.nodemedia.cn/product/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
+
+# Usage
+
## docker version
+
```bash
docker run --name nms -d -p 1935:1935 -p 8000:8000 illuspas/node-media-server
```
## git version
+
```bash
mkdir nms
cd nms
@@ -64,7 +81,7 @@ vi app.js
```
```js
-const NodeMediaServer = require('node-media-server');
+const NodeMediaServer = require("node-media-server");
const config = {
rtmp: {
@@ -72,15 +89,15 @@ const config = {
chunk_size: 60000,
gop_cache: true,
ping: 30,
- ping_timeout: 60
+ ping_timeout: 60,
},
http: {
port: 8000,
- allow_origin: '*'
- }
+ allow_origin: "*",
+ },
};
-var nms = new NodeMediaServer(config)
+var nms = new NodeMediaServer(config);
nms.run();
```
@@ -89,19 +106,24 @@ node app.js
```
# Publishing live streams
+
## From FFmpeg
->If you have a video file with H.264 video and AAC audio:
+
+> If you have a video file with H.264 video and AAC audio:
+
```bash
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:
+
```bash
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
+
+> Settings -> Stream
Stream Type : Custom Streaming Server
@@ -110,27 +132,33 @@ URL : rtmp://localhost/live
Stream key : STREAM_NAME
# Accessing the live stream
-## RTMP
+
+## 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
```
@@ -141,16 +169,16 @@ http://localhost:8000/live/STREAM_NAME/index.mpd
```
@@ -160,24 +188,27 @@ http://localhost:8000/live/STREAM_NAME/index.mpd
```
# 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
@@ -187,7 +218,7 @@ Modifying the logging type is easy - just add a new value `logType` in the confi
By default, this is set to show errors and generic info internally (setting 2).
```js
-const NodeMediaServer = require('node-media-server');
+const NodeMediaServer = require("node-media-server");
const config = {
logType: 3,
@@ -197,29 +228,32 @@ const config = {
chunk_size: 60000,
gop_cache: true,
ping: 30,
- ping_timeout: 60
+ ping_timeout: 60,
},
http: {
port: 8000,
- allow_origin: '*'
- }
+ allow_origin: "*",
+ },
};
-var nms = new NodeMediaServer(config)
+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
+> ws://hostname:port/appname/stream.flv?sign=expires-HashValue
1.Publish or play address:
->rtmp://192.168.0.10/live/stream
+
+> rtmp://192.168.0.10/live/stream
2.Config set auth->secret: 'nodemedia2017privatekey'
+
```js
const config = {
rtmp: {
@@ -227,37 +261,43 @@ const config = {
chunk_size: 60000,
gop_cache: true,
ping: 30,
- ping_timeout: 60
+ ping_timeout: 60,
},
http: {
port: 8000,
- allow_origin: '*'
+ allow_origin: "*",
},
auth: {
play: true,
publish: true,
- secret: 'nodemedia2017privatekey'
- }
-}
+ secret: "nodemedia2017privatekey",
+ },
+};
```
+
3.expiration time: 2017/8/23 11:25:21 ,The calculated expiration timestamp is
->1503458721
+
+> 1503458721
4.The combination HashValue is:
->HashValue = md5("/live/stream-1503458721-nodemedia2017privatekey”)
->HashValue = 80c1d1ad2e0c2ab63eebb50eed64201a
+
+> 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
+
H.265 does not appear in Adobe's official specification. Id 12 is the standard for most cloud services in China.
Publish or Transcode: [ffmpeg-hw-win32](#ffmpeg-hw-win32)
Play:[NodeMediaClient-Android](#android) and [NodeMediaClient-iOS](#ios)
Pure JavaScrip live stream player: [NodePlayer.js](https://github.com/illuspas/NodePlayer.js)
# Event callback
+
```js
......
nms.run();
@@ -303,18 +343,21 @@ nms.on('donePlay', (id, StreamPath, args) => {
console.log('[NodeEvent on donePlay]', `id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`);
});
```
+
# Https/Wss
## Generate certificate
+
```bash
openssl genrsa -out privatekey.pem 1024
-openssl req -new -key privatekey.pem -out certrequest.csr
+openssl req -new -key privatekey.pem -out certrequest.csr
openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem
```
## Config https
+
```js
-const NodeMediaServer = require('node-media-server');
+const NodeMediaServer = require("node-media-server");
const config = {
rtmp: {
@@ -322,32 +365,36 @@ const config = {
chunk_size: 60000,
gop_cache: true,
ping: 30,
- ping_timeout: 60
+ ping_timeout: 60,
},
http: {
port: 8000,
- allow_origin: '*'
+ allow_origin: "*",
},
https: {
port: 8443,
- key:'./privatekey.pem',
- cert:'./certificate.pem',
- }
+ key: "./privatekey.pem",
+ cert: "./certificate.pem",
+ },
};
-
-var nms = new NodeMediaServer(config)
+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
+> In the browser environment, Self-signed certificates need to be added with trust before they can be accessed.
+
+# API
+
+## Protected API
+
```
const config = {
.......
@@ -356,14 +403,16 @@ const config = {
api_user: 'admin',
api_pass: 'nms2018',
},
-
+
......
}
```
->Based on the basic auth,Please change your password.
->The default is not turned on
+
+> Based on the basic auth,Please change your password.
+> The default is not turned on
## Server stats
+
http://localhost:8000/api/server
```json
@@ -409,6 +458,7 @@ http://localhost:8000/api/server
```
## Streams stats
+
http://localhost:8000/api/streams
```json
@@ -486,8 +536,9 @@ http://localhost:8000/api/streams
```
# Remux to HLS/DASH live stream
+
```js
-const NodeMediaServer = require('node-media-server');
+const NodeMediaServer = require("node-media-server");
const config = {
rtmp: {
@@ -495,34 +546,35 @@ const config = {
chunk_size: 60000,
gop_cache: true,
ping: 30,
- ping_timeout: 60
+ ping_timeout: 60,
},
http: {
port: 8000,
- mediaroot: './media',
- allow_origin: '*'
+ mediaroot: "./media",
+ allow_origin: "*",
},
trans: {
- ffmpeg: '/usr/local/bin/ffmpeg',
+ ffmpeg: "/usr/local/bin/ffmpeg",
tasks: [
{
- app: 'live',
+ app: "live",
hls: true,
- hlsFlags: '[hls_time=2:hls_list_size=3:hls_flags=delete_segments]',
+ hlsFlags: "[hls_time=2:hls_list_size=3:hls_flags=delete_segments]",
dash: true,
- dashFlags: '[f=dash:window_size=3:extra_window_size=5]'
- }
- ]
- }
+ dashFlags: "[f=dash:window_size=3:extra_window_size=5]",
+ },
+ ],
+ },
};
-var nms = new NodeMediaServer(config)
+var nms = new NodeMediaServer(config);
nms.run();
```
# Remux to RTMP/HLS/DASH live stream with audio transcode
+
```js
-const NodeMediaServer = require('node-media-server');
+const NodeMediaServer = require("node-media-server");
const config = {
rtmp: {
@@ -530,40 +582,41 @@ const config = {
chunk_size: 60000,
gop_cache: true,
ping: 30,
- ping_timeout: 60
+ ping_timeout: 60,
},
http: {
port: 8000,
- mediaroot: './media',
- allow_origin: '*'
+ mediaroot: "./media",
+ allow_origin: "*",
},
trans: {
- ffmpeg: '/usr/local/bin/ffmpeg',
+ ffmpeg: "/usr/local/bin/ffmpeg",
tasks: [
{
- app: 'live',
+ app: "live",
vc: "copy",
vcParam: [],
ac: "aac",
- acParam: ['-ab', '64k', '-ac', '1', '-ar', '44100'],
- rtmp:true,
- rtmpApp:'live2',
+ 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]',
+ hlsFlags: "[hls_time=2:hls_list_size=3:hls_flags=delete_segments]",
dash: true,
- dashFlags: '[f=dash:window_size=3:extra_window_size=5]'
- }
- ]
- }
+ dashFlags: "[f=dash:window_size=3:extra_window_size=5]",
+ },
+ ],
+ },
};
-var nms = new NodeMediaServer(config)
+var nms = new NodeMediaServer(config);
nms.run();
```
->Remux to RTMP cannot use the same app name
+> Remux to RTMP cannot use the same app name
# Record to MP4
+
```JS
const NodeMediaServer = require('node-media-server');
@@ -597,9 +650,11 @@ 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.
@@ -628,7 +683,8 @@ relay: {
}
```
-## Dynamic pull
+## 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.
@@ -647,6 +703,7 @@ relay: {
```
## Dynamic push
+
When the local server receives a publish request.
Automatically push the stream to the edge server.
@@ -664,8 +721,10 @@ relay: {
```
# Fission
+
Real-time transcoding multi-resolution output
![fission](https://raw.githubusercontent.com/illuspas/resources/master/img/admin_panel_fission.png)
+
```
fission: {
ffmpeg: '/usr/local/bin/ffmpeg',
@@ -723,36 +782,43 @@ fission: {
# 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
+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 (Support for iOS safari browser)
+
+- Implemented with asm.js / wasm
+- http-flv/ws-flv
+- H.264/H.265 + AAC/Nellymoser/G.711 decoder
+- Ultra low latency (Support for iOS safari browser)
http://www.nodemedia.cn/products/node-media-player
## Windows browser plugin(ActiveX/NPAPI)
-* H.264/H.265+AAC rtmp publisher
-* Camera/Desktop + Microphone capture
-* Nvidia/AMD/Intel Hardware acceleration Encoder/Decoder
-* Ultra low latency rtmp/rtsp/http live player
-* Only 6MB installation package
+
+- H.264/H.265+AAC rtmp publisher
+- Camera/Desktop + Microphone capture
+- Nvidia/AMD/Intel Hardware acceleration Encoder/Decoder
+- Ultra low latency rtmp/rtsp/http live player
+- Only 6MB installation package
http://www.nodemedia.cn/products/node-media-client/win
# Thanks
-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
+
+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.