Node-Media-Server

repository·main·Indexed 27 days ago

https://github.com/illuspas/node-media-server

A high-performance, low-latency open-source live streaming server built on Node.js. It supports RTMP, RTMPS, HTTP-FLV, and WS-FLV protocols, with support for modern codecs including H.264, H.265/HEVC, VP9, and AV1. Features include a REST API with JWT-based challenge-response authentication, live stream recording to FLV, GOP caching for faster playback, and an event system for monitoring stream lifecycles.

Tokens
6K
Snippets
12
Records
35
Agent score
91%

What's inside node-media-server

  1. Understand the Node-Media-Server Architecture

    main

    Node-Media-Server is a high-performance Node.js real-time media server. Its architecture is organized into five layers:

    1. Application Layer: Handles RTMP publishing/playback, HTTP-FLV playback, and WebSocket-FLV playback.
    2. Protocol Layer: Implements RTMP (handshake/chunking), FLV (tag format), and WebSocket (frame format) protocols.
    3. Session Layer: Manages individual sessions including RtmpSession, FlvSession (HTTP/WS), and API Session (REST API).
    4. Service Layer: Contains the server implementations: NodeRtmpServer (TCP/SSL), NodeHttpServer (HTTP/WS/Static files/API), NodeRecordServer (Recording), and NodeNotifyServer (HTTP callbacks).
    5. Core Layer: Provides global state via Context, the Logger system, and the Event System.
  2. Understand Node-Media-Server error handling and optimization

    main

    Node-Media-Server manages errors through two primary flows: session-level and protocol-level handling.

    Session Error Handling

    When a session exception occurs, the system follows this lifecycle:

    1. Error capture
    2. Logging
    3. Resource cleanup
    4. Session removal
    5. Event notification
    6. State recovery

    Protocol Error Handling

    Protocol errors are classified to determine severity:

    • Fatal Errors: Result in immediate connection closure and session cleanup.
    • Non-fatal Errors: The system attempts recovery and continues processing.

    Performance Optimization Strategies

    The server employs several strategies to maintain low latency and high throughput:

    • Memory Optimization: Limits GOP (Group of Pictures) cache to 4096 frames, implements timely expired session cleanup, and uses a buffer reuse mechanism.
    • Network Optimization: Utilizes zero-copy data transmission, TCP_NODELAY settings, and buffer size optimization.
    • Concurrency Optimization: Built on an event-driven architecture with non-blocking I/O and load balancing distribution.
  3. Authenticate with the REST API using Challenge-Response

    main

    The REST API uses a two-step JWT-based challenge-response authentication to prevent credential replay attacks. This allows secure login even over plain HTTP.

    1. Request a challenge: Send a POST request to /api/v1/login with the username.
    2. Submit response: Compute response = HMAC-SHA256(password, challenge) and send a POST request to /api/v1/login containing the username, the challenge received, and the computed response.

    Each challenge is single-use and expires after 60 seconds.

    # Step 1: Request a challenge
    curl -X POST http://localhost:8000/api/v1/login \
      -H "Content-Type: application/json" \
      -d '{"username":"admin"}'
    
    # Step 2: Submit challenge response
    # (Assuming $CHALLENGE and $RESPONSE are computed)
    curl -X POST http://localhost:8000/api/v1/login \
      -H "Content-Type: application/json" \
      -d "{\"username\":\"admin\",\"challenge\":\"$CHALLENGE\",\"response\":\"$RESPONSE\"}"
  4. Understand the Node-Media-Server startup process

    main

    When starting the server via node bin/app.js, the following sequence occurs:

    1. Configuration & Security: The application loads config.json, generates a random administrator password, and parses SSL certificate paths.
    2. Core Initialization: NodeMediaServer is instantiated, initializing the logging system and a global Context (which manages sessions, broadcasts, and an eventEmitter).
    3. Server Component Creation:
      • RTMP Server: Creates TCP listeners (default port 1935) and TLS listeners (default port 1936).
      • HTTP Server: Sets up Express routes, JWT middleware, and a WebSocket server.
      • Record Server: Initializes recording capabilities.
      • Notify Server: Initializes the notification system.
    4. Activation: Event listeners are registered, and all sub-servers are started.
  5. Understand the RTMP publishing workflow

    main

    When a client publishes an RTMP stream, the server performs these steps:

    1. Session Establishment: A TCP connection is made, a unique RTMP session is created, and it is registered in the global Context.
    2. Handshake & Connection: The client and server perform the RTMP handshake (C0/C1/C2 and S0/S1/S2). The client sends connect and createStream commands, which the server validates.
    3. Publishing: The client sends a publish command. The server:
      • Parses the stream path (e.g., /app/stream).
      • Retrieves or creates a BroadcastServer instance.
      • Registers the stream in the broadcasts Map.
      • Executes postPublish and triggers prePublish and postPublish events for permission validation.
    4. Data Handling: As audio/video packets arrive, the BroadcastServer:
      • Converts packets to AVPacket format.
      • Caches GOP (Group of Pictures) frames.
      • Broadcasts the data to all active subscribers in the required format (FLV/RTMP).
  6. Understand FLV playback via HTTP or WebSocket

    main

    Node-Media-Server supports FLV playback through two primary methods:

    HTTP FLV Playback

    1. The player requests a URL like /app/stream.flv via HTTP.
    2. The HttpServer creates an FlvSession and extracts the app and name from the path.
    3. The BroadcastServer validates permissions and triggers prePlay/postPlay events.
    4. The server responds with HTTP 200 OK and streams the FLV header, metadata, audio/video configurations, and GOP cache, followed by the real-time stream.
    5. When the connection closes, donePlay is executed, removing the subscriber and triggering donePlay events.

    WebSocket-FLV Playback

    1. The player sends an HTTP Upgrade request to establish a WebSocket connection.
    2. The WsServer creates an FlvSession and extracts stream path information.
    3. The BroadcastServer validates permissions.
    4. The server sends the FLV header, metadata, and media configurations as WebSocket messages.
    5. Real-time media packets are delivered as continuous WebSocket messages containing FLV data.
  7. Analyze playback data flows (HTTP-FLV and WebSocket-FLV)

    main

    When a player requests a stream, the server follows these steps:

    1. Connection & Auth: The server creates a session (e.g., FlvSession) and performs authentication.
    2. Header & Metadata: The server sends the FLV header and stream metadata.
    3. GOP Cache: The server iterates through the flvGopCache and sends the cached frames to the player.
    4. Live Stream: The server subscribes the session to the live stream and begins transmitting real-time data.

    Implementation Details:

    • HTTP-FLV: Uses res.write(buffer) to send data via the HTTP response stream.
    • WebSocket-FLV: Uses res.send(buffer) to send data via WebSocket messages, provided the readyState is WebSocket.OPEN.
  8. Analyze metadata processing for publishers

    main

    When a publisher sends metadata (flag 5), the BroadcastServer decodes the AMF0 data. If the command is @setDataFrame, the server extracts stream parameters to update the publisher's session:

    Extracted Parameters:

    • Audio: audioCodec, audioChannels, audioSamplerate.
    • Video: videoCodec, videoWidth, videoHeight, videoFramerate.
  9. Understand the RTMP playback workflow

    main

    When a client plays an RTMP stream, the server follows this sequence:

    1. Session Setup: A TCP connection is established, an RTMP session is created and registered in the Context.
    2. Protocol Handshake: The client performs the RTMP handshake and sends connect, createStream, and play commands.
    3. Authorization: Upon the play command, the BroadcastServer validates playback permissions and triggers prePlay and postPlay events.
    4. Stream Delivery:
      • The server sends the FLV header, metadata, and audio/video configurations.
      • The server sends the cached GOP (keyframe) sequence to allow immediate playback.
      • Real-time media packets are continuously converted to RTMP format and sent to the player.
  10. Understand GOP (Group of Pictures) caching

    main

    Node-Media-Server uses a GOP cache to allow new players to connect and immediately receive keyframes, ensuring faster playback start times.

    Cache Management Logic:

    • When a Keyframe (flag 3) is received: The existing flvGopCache and rtmpGopCache are cleared and re-initialized with the new keyframe.
    • When a Normal Frame (flag 4) is received: The frame is added to the cache if the cache size is below the limit of 4096 frames.