MistServer Documentation

repository·master·Indexed 19 days ago

https://github.com/ddvtech/mistserver

An open source, public domain streaming media toolkit for OTT and system integration. Includes documentation on installation via pre-compiled binaries or Meson, managing the MistController, and developer libraries for AMF0/AMF3 serialization, DTSC packet parsing, HTTP request/response handling, and configuration management.

Tokens
8.4K
Snippets
23
Records
30
Agent score
67%

What's inside MistServer

  1. Run MistServer and the MistController

    master

    MistServer is initialized by executing the MistController binary.

    How it works:

    • MistController scans its current directory for any other binaries starting with Mist*.
    • It runs these discovered binaries to identify available inputs, outputs, and processes.
    • You can manage available features simply by adding or removing Mist* binaries from the same directory.

    First-time Setup:

    • If running in an interactive terminal, you will be guided through a brief setup process.
    • If no interactive terminal is available, setup can be completed via the web interface.

    Accessing the Server:

    • The controller listens on port 4242 for API connections.
    • You can access the web interface by navigating to http://<your-ip>:4242 in a web browser to perform human-friendly configuration and API commands.
    # Run the controller from the build directory
    ./MistController
  2. Install MistServer via pre-compiled binaries

    master

    MistServer provides pre-compiled binaries for most common operating systems. You can download them from the official download page.

    For an automated setup, the download page provides a "Copy install cmd" button which generates a command to set up MistServer running as root under your system's init daemon (systemd is recommended). Alternatively, you can follow manual installation instructions in the official documentation.

    https://mistserver.org/download
  3. Compile MistServer from source using Meson

    master

    MistServer uses the Meson build system. It utilizes Meson's "wraps" feature to automatically fulfill dependencies, though it will prefer compatible system-wide libraries if available.

    To compile the project:

    1. Initialize the build directory using meson setup build.
    2. Enter the build directory.
    3. Run ninja to compile the binaries.

    To install the compiled binaries system-wide (requires root/sudo privileges), run ninja install from within the build directory.

    # Setup the build directory
    meson setup build
    
    # Compile
    cd build
    ninja
    
    # Optional: Install system-wide
    ninja install
  4. Understand the SDP Media Model

    master

    The SDP namespace provides a hierarchical model for parsing and interacting with Session Description Protocol (SDP) data, primarily used for WebRTC and RTSP. The model consists of three main layers:

    1. SDP::Session: Represents the entire SDP session. It contains session-wide attributes (like iceUFrag and icePwd) and a collection of SDP::Media objects.
    2. SDP::Media: Represents a specific media line (e.g., an m=video or m=audio line). It contains media-specific attributes like SSRC, direction, fingerprint, and a map of SDP::MediaFormat objects.
    3. SDP::MediaFormat: Represents a specific encoding/payload type within a media line (e.g., H264, VP8). It stores codec-specific parameters like payloadType, encodingName, and formatParameters (from a=fmtp).

    This structure allows a single media line to support multiple formats, which is common in WebRTC offers/answers.

  5. Set up listening sockets with Socket::Server

    master

    The Socket::Server class is used to create listening sockets for accepting incoming TCP or Unix connections.

    Usage:

    • TCP Server: Initialize with Server(port, hostname, nonblock).
    • Unix Server: Initialize with Server(address, nonblock).
    • Accepting Connections: Use accept(bool nonblock) to retrieve a Socket::Connection object for a new client.
    • Cleanup: Use close() or drop() to stop the server.
    // Example: Creating a TCP server on port 8080
    Socket::Server server(8080, "0.0.0.0", true);
    Socket::Connection client = server.accept(true);
    if (client.connected()) {
        // Handle client
    }
  6. Use SDP::Answer to generate WebRTC answers

    master

    The SDP::Answer class is a helper for constructing an SDP answer from an incoming offer. It manages the state of the answer being built, including media enablement and ICE credentials.

    Workflow:

    1. Initialize an Answer object.
    2. Call parseOffer(sdp) to ingest the remote offer.
    3. Use enableMedia(type, codecName, localIceUfrag, localIcePwd) to select which media tracks to include in the answer.
    4. Set the direction using setDirection(dir).
    5. Call toString() to generate the final SDP answer string.

    Key Properties:

    • sdpOffer: The parsed SDP::Session from the offer.
    • answerVideoMedia / answerAudioMedia: The SDP::Media objects being prepared for the answer.
    • videoLossPrevention: A value set using SDP_LOSS_PREVENTION_* constants.
    SDP::Answer answer;
    answer.parseOffer(incomingSdpString);
    answer.enableMedia("video", "H264", "local_ufrag", "local_pwd");
    answer.setDirection("sendrecv");
    std::string sdpAnswer = answer.toString();
  7. Handle TCP and Unix connections with Socket::Connection

    master

    The Socket::Connection class manages communication over TCP or Unix domain sockets. It supports both blocking and non-blocking modes and includes optional SSL support (via mbedTLS).

    Key Operations:

    • Initialization: Create connections via open(host, port, nonblock, with_ssl) for TCP or open(address, nonblock) for Unix sockets.
    • I/O:
      • send(data, len) and SendNow(data) for sending data.
      • iwrite(buffer, len) for incremental/non-blocking writes.
      • Received() returns a reference to a Socket::Buffer containing incoming data.
      • spool() updates the internal download buffer.
    • State Management: Use connected() to check status, setBlocking(bool) to toggle mode, and close() or drop() to terminate the connection.
    • Statistics: Track usage via dataUp() (bytes sent) and dataDown() (bytes received).
    // Example: Opening a non-blocking TCP connection with SSL
    Socket::Connection conn("example.com", 443, true, true);
    if (conn.connected()) {
        conn.SendNow("GET / HTTP/1.1\r\n\r\n");
    }
  8. Configure URIReader read bounds and progress callbacks

    master

    You can tune the behavior of URIReader to optimize memory usage and monitoring:

    • onProgress(bool (*progressCallback)(uint8_t)): Sets a callback that is triggered whenever a transfer stalls. The callback should return a boolean.
    • setBounds(size_t minLen, size_t maxLen): Sets the minimum and maximum buffer sizes used when performing read operations that utilize dataCallback. This controls the granularity of the data chunks passed to your callback.
    HTTP::URIReader reader("https://example.com/stream");
    
    // Monitor progress
    reader.onProgress([](uint8_t progress) -> bool {
        // Handle progress update
        return true;
    });
    
    // Set buffer constraints for callbacks
    reader.setBounds(4096, 65536);
  9. Manage data streams with Socket::Buffer

    master

    The Socket::Buffer class is an efficient buffer implementation using std::deque<std::string>. It is designed for high-performance reading and writing of network data.

    Key Features:

    • Appending/Prepending: Use append(data, size) or prepend(data, size) to add data to the stream.
    • Extraction: remove(count) removes and returns a string of a specific size; copy(count) copies data without removing it.
    • Splitting: The splitter member (defaults to \n) allows the buffer to automatically identify message boundaries.
    • Maintenance: compact() can be used to optimize the internal storage structure.
  10. Manipulate AMF3 objects with the AMF::Object3 class

    master

    The AMF::Object3 class is a recursive container for AMF3 data. It provides methods for handling integer and double values specifically for the AMF3 format.

    Key Methods:

    • addContent(...): Adds nested data.
    • getIntValue() / getDblValue(): Retrieves integer or double values.
    • StrValue(): Retrieves the string value.
    • Pack(): Serializes the object to an AMF3 string.
    • toJSON(): Converts the object to a JSON::Value.
    // Example: Creating an AMF3 object
    AMF::Object3 obj3("data", 42, AMF::AMF3_INTEGER);
    std::string amf3Data = obj3.Pack();
  11. Use SDP::MediaFormat to access codec parameters

    master

    The SDP::MediaFormat class stores information specific to an encoding. While you can access members directly, you should use the provided getter functions when available, as they include fallback logic (e.g., determining sample rate from the payload type if not explicitly set).

    Key Methods:

    • getFormatParameterForName(name): Retrieves a parameter from the a=fmtp: line.
    • getAudioSampleRate(): Returns the audio sample rate (falls back to payload type lookup if not set).
    • getAudioNumChannels(): Returns the number of audio channels.
    • getAudioBitSize(): Returns the audio bitsize.
    • getVideoRate(): Returns the video time base/rate.
    • getPayloadType(): Returns the payloadType.
    • getProfileLevelIdForH264(): Specifically for H264, returns the profile-level-id from format parameters.
    • getPacketizationModeForH264(): Specifically for H264, returns the packetization mode.
  12. Manipulate AMF0 objects with the AMF::Object class

    master

    The AMF::Object class is a recursive container for AMF0 data. You can create objects with specific types, add content (nested objects, strings, or numbers), and retrieve values by index or key. It supports serialization to/from AMF and JSON.

    Key Methods:

    • addContent(...): Adds nested data. Can take an index, a string key, or just a value.
    • getContent(string s) / getContentP(string s): Retrieves content by key (returns value or pointer).
    • getContent(unsigned int i) / getContentP(unsigned int i): Retrieves content by index (returns value or pointer).
    • Pack(): Serializes the object to an AMF string.
    • toJSON(): Converts the object to a JSON::Value.
    // Example: Creating a nested AMF0 object
    AMF::Object root(AMF::AMF0_OBJECT);
    root.addContent("user", "admin");
    root.addContent("id", 123.45, AMF::AMF0_NUMBER);
    
    AMF::Object nested(AMF::AMF0_OBJECT);
    nested.addContent("active", true, AMF::AMF0_BOOL);
    root.addContent("settings", nested);
    
    std::string amfData = root.Pack();