
如果你使用 DeepSeek、元宝 AI、Copilot、ChatGPT 等 AI 工具,协助配置轩辕镜像、编写 docker pull 命令、修改 Docker Compose 镜像地址、配置镜像加速、排查镜像拉取失败、分析报错日志等问题,请先让 AI 阅读并遵守轩辕镜像的规则文档。
只需在 AI 对话中先发送下面这段话即可:
请先阅读并遵守:https://xuanyuan.cloud/agents.md
未读文档前不要生成 pull 命令或排错方案。查看 agents.md 用法指南与完整示范。国内用户首推 元宝 AI、DeepSeek 的深度思考模式,不推荐豆包 AI;Cursor 等编辑器可在对话 @ 该链接,或加入 User Rules。 若 AI 无法访问外链,可 打开说明文档 复制全文粘贴。文档会随站点更新,复制内容可能过期,建议定期检查。
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
If you like this project you can support me.
https://github.com/NodeMedia/NodeMediaServer
https://github.com/illuspas/Node-Media-Server-Admin
[***]
bashnpx node-media-server
bashnpm i node-media-server -g node-media-server
bashdocker run --name nms -d -p 1935:1935 -p 8000:8000 -p 8443:8443 illuspas/node-media-server
bashmkdir nms cd nms npm install node-media-server vi app.js
jsconst 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();
bashnode app.js
If you have a video file with H.264 video and AAC audio:
bashffmpeg -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:
bashffmpeg -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
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
html<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>
html<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).
jsconst 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
[***]
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'
jsconst 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
4.The combination HashValue is:
HashValue = md5("/live/stream-***-nodemedia2017privatekey”)
HashValue = 80c1d1ad2e0c2ab63eebb50eed64201a
5.Final request address
rtmp://192.168.0.10/live/stream?sign=***-80c1d1ad2e0c2ab63eebb50eed64201a
The 'sign' keyword can not be modified
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
Play:NodeMediaClient-Android and NodeMediaClient-iOS
Pure JavaScrip live stream player: https://github.com/illuspas/NodePlayer.js
js...... 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)}`); });
bashopenssl 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
jsconst 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();
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
json{ "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
json{ "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" } ] } } }
jsconst 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]', dash: true, dashFlags: '[f=dash:window_size=3:extra_window_size=5]' } ] } }; var nms = new NodeMediaServer(config) nms.run();
jsconst 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
JSconst 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();
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
[***]
https://github.com/NodeMedia/NodeMediaClient-Android
https://github.com/NodeMedia/NodeMediaClient-iOS
https://github.com/NodeMedia/react-native-nodemediaclient
[***]
[***]
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.
您可以使用以下命令拉取该镜像。请将 <标签> 替换为具体的标签版本。如需查看所有可用标签版本,请访问 标签列表页面。
来自真实用户的反馈,见证轩辕镜像的优质服务