aws – SRS v6 Docker Cluster – WebRTC Fails Whereas FLV/HLS Work

0
1
aws – SRS v6 Docker Cluster – WebRTC Fails Whereas FLV/HLS Work


I’m organising an SRS origin-edge cluster utilizing Docker. I need to publish a single RTMP stream to the origin and play it again on the proxy utilizing HTTP-FLV, HLS, and WebRTC. My motivation is that once I stream a number of cameras with WebRTC via my AWS server, the second digicam experiences latency. From my understanding, SRS works on a single thread which may create points. Thus, I made a decision to make use of multi-containers system (Please let me know if there are higher methods to do!). For now, I’m simply attempting two containers:

  1. origin that receives the stream
  2. proxy that pulls the stream from origin and stream on an html web page

I used to be capable of:

  • Setup a single-container setup works completely for all protocols (FLV, HLS, and WebRTC).
  • Create a multi-container setup, HTTP-FLV and HLS playback works accurately, which proves the stream is being pulled from the origin to the proxy.

My drawback:

WebRTC playback is the one factor that fails. The browser makes a profitable connection to the proxy (logs present connection established), however no video ever seems. The proxy log exhibits it connects to the origin to tug the stream, however the connection then instances out or fails with a video parsing error (avc demux annexb : not annexb).

My docker-compose.yml:

model: '3.8'
networks:
  srs-net:
    driver: bridge
companies:
  srs-origin:
    picture: ossrs/srs:6
    container_name: srs-origin
    networks: [srs-net]
    ports: ["1936:1935"]
    expose:
      - "1935"
    volumes: ["./origin.conf:/usr/local/srs/conf/srs.conf:ro"]
    command: ["./objs/srs", "-c", "conf/srs.conf"]
    restart: unless-stopped      
  srs-proxy:
    picture: ossrs/srs:6
    container_name: srs-proxy
    networks: ["srs-net"]
    ports:
      - "1935:1935"
      - "1985:1985"
      - "8000:8000/udp"
      - "8080:8080"
    depends_on:
      - srs-origin
    volumes: 
      - "./proxy.conf:/usr/native/srs/conf/srs.conf:ro"
      - "./html:/usr/native/srs/html"
    command: ["./objs/srs", "-c", "conf/srs.conf"]
    restart: unless-stopped

origin.conf:

hear 1935;
daemon off;
srs_log_tank console;
srs_log_level hint;

vhost __defaultVhost__ {
}

proxy.conf:

hear              1935;
max_connections     1000;
daemon              off;
srs_log_tank        console;
srs_log_level       hint;

http_server {
    enabled         on;
    hear          8080;
    dir             ./html;
    crossdomain     on;
}

http_api {
    enabled         on;
    hear          1985;
    crossdomain     on;
}

rtc_server {
    enabled         on;
    hear          8000;
    candidate      xxx.xxx.xxx.xxx; # IP tackle
}

vhost __defaultVhost__ {
    enabled         on;

    # Allow cluster mode to tug from the origin server
    cluster {
        mode            distant;
        origin          srs-origin:1935;
    }

    # Low latency settings
    play {
        gop_cache       off;
        queue_length    1;
        mw_latency      50;
    }

    # WebRTC configuration (Not working)
    rtc {
        enabled         on;
        rtmp_to_rtc     on;
        rtc_to_rtmp     off;
        
        # Essential for SRS v6
        bframe          discard;
        keep_bframe     off;
    }

    # HTTP-FLV (working)
    http_remux {
        enabled     on;
        mount       /[app]/[stream].flv;
    }
    
    # HLS (working)
    hls {
        enabled         on;
        hls_path        ./html;
        hls_fragment    3;
        hls_window      9;
    }
}

The ffmpeg pipe I exploit in my python code from my host machine to push video frames to my AWS server:

IP_ADDRESS      = ip_address
        RTMP_SERVER_URL = f"rtmp://{IP_ADDRESS}:1936/reside/Camera_0"
        BITRATE_KBPS    = bitrate # Goal bitrate for the output stream (2 Mbps)
        # Threading and queue for body processing
        ffmpeg_cmd = [
            'ffmpeg',
            '-y',
            '-f', 'rawvideo',
            '-vcodec', 'rawvideo',
            '-pix_fmt', 'bgr24',
            '-s', f'{self.frame_width}x{self.frame_height}',
            '-r', str(self.camera_fps),
            '-i', '-',

            # Add audio source (silent audio if no mic)
            '-f', 'lavfi',
            '-i', 'anullsrc=channel_layout=stereo:sample_rate=44100',

            # Video encoding
            '-c:v', 'libx264',
            '-preset', 'ultrafast',
            '-tune', 'zerolatency',
            '-pix_fmt', 'yuv420p',
            # Keyframe interval: 1 second. Consider 0.5s if still high, but increases bitrate.
            '-g', str(2*self.camera_fps), 
            # Force no B-frames (zerolatency should handle this, but explicit is sometimes better)
            '-bf', '0', 
            '-profile:v', 'baseline',   # Necessary for apple devices 

            # Specific libx264 options for latency (often implied by zerolatency, but can be explicit)
            # Add options to explicitly disable features not in Baseline profile,
            # ensuring maximum compatibility and avoiding implicit enabling by preset.
            '-x264-params', 'cabac=0:ref=1:nal-hrd=cbr:force-cfr=1:no-mbtree=1:slice-max-size=1500', 
            # Force keyframes only if input allows (might not be practical for camera input)
            '-keyint_min', str(self.camera_fps), # Ensure minimum distance is also 1 second
            
            # Rate control and buffering for low latency
            '-b:v', f'{BITRATE_KBPS}k',         # Your target bitrate (e.g., 1000k)
            '-maxrate', f'{BITRATE_KBPS * 1.2}k', # Slightly higher maxrate than bitrate
            '-bufsize', f'{BITRATE_KBPS * 1.5}k', # Buffer size related to maxrate
            
            '-f', 'flv',
            RTMP_SERVER_URL
        ]

self.ffmpeg_process = subprocess.Popen(ffmpeg_cmd, stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, bufsize=10**5)

LEAVE A REPLY

Please enter your comment!
Please enter your name here