ossrs / srs

SRS is a simple, high-efficiency, real-time media server supporting RTMP, WebRTC, HLS, HTTP-FLV, HTTP-TS, SRT, MPEG-DASH, and GB28181.
https://ossrs.io
MIT License
25.65k stars 5.38k forks source link

The `on_connect` hook is firing more than one time when sending the transcoder output to another vhost. #3548

Closed basemkhirat closed 1 year ago

basemkhirat commented 1 year ago

I am transcoding to 360p and sending the output to another vhost which named by the engine name.

I am using on_connect and but It's firing twice.

One when connecting the origin vhost and the other when SRS connected internally to the quality host.

To authenticate, I send a secret with the stream_key like stream_key?secret=09mY6AsPSeSF and check it using on_connect hook. like what implemented in srs-cloud.

The data sent from SRS to the first on_connect request:

{
  "server_id":"vid-776x7h7",
  "service_id":"j0356409",
  "action":"on_connect",
  "client_id":"2u38x628",
  "ip":"127.0.0.1",
  "vhost":"site.streamer",
  "app":"test-app",
  "stream":"stream_key",
  "param":"?vhost=site.streamer&secret=09mY6AsPSeSF",
  "tcUrl":"rtmp:\/\/127.0.0.1:1935\/test-app",
  "pageUrl":""
}

And the data sent from SRS to the second on_connect request:

{
  "server_id":"vid-776x7h7",
  "service_id":"j0356409",
  "action":"on_connect",
  "client_id":"5z3833fo",
  "ip":"127.0.0.1",
  "vhost":"site.streamer",
  "app":"test-app",
  "stream":"stream_key",
  "param":"?vhost=site.streamer?vhost=site.streamer",
  "tcUrl":"rtmp:\/\/127.0.0.1:1935\/test-app?vhost=site.streamer",
  "pageUrl":""
}

And the last one not having the secret, so it will fail to connect.

SRS Version: 5.0 SRS Config:

listen 1935;
max_connections 1000;
daemon on;

vhost site.streamer {

 transcode {
        enabled     on;
        ffmpeg     /usr/local/bin/ffmpeg;

        engine 360p {
            enabled         on;
            vfilter {
                vf scale=w=640:h=360:force_original_aspect_ratio=decrease;
                loglevel       debug;
            }
            vcodec          libx264;
            vbitrate        1000;
            vfps            30;
            vwidth          0;
            vheight         0;
            vthreads        4;
            vprofile        high;
            vpreset         superfast;
            vparams {
                g       60;
                tune    zerolatency;
                vlevel  3.1;
            }
            acodec          aac;
            abitrate        128;
            achannels       2;
            aparams {
            }
            output          rtmp://127.0.0.1:[port]/[app]?vhost=[engine]/[stream];
        }
    }

    play {
        gop_cache_max_frames 2500;
    }

    http_hooks {
        enabled on;
    on_connect http://localhost:8000/v1/hooks/on_connect;
        on_publish http://localhost:8000/v1/hooks/on_publish;
        on_unpublish http://localhost:8000/v1/hooks/on_unpublish;
    }

}

vhost 360p {            

    security {
    enabled         on;
    allow           publish     127.0.0.1;
    allow           play        all;
    }

    gop_cache       off;
    queue_length    10;
    min_latency     on;
    mr {
        enabled     on;
    }
    mw_latency      100;

    hls {
        enabled         on;
        hls_on_error    disconnect;
        hls_cleanup on;
        hls_window 7200;
        hls_fragment 10;
        hls_path        /Users/basem/www/streamer/public/apps;
        hls_dispose 300;
        hls_m3u8_file   [app]/[stream]/live-[vhost].m3u8;
        hls_ts_file     [app]/[stream]/segment-[vhost]-[seq].ts;
    }

   http_hooks {
        enabled on;
        on_play http://localhost:8000/v1/hooks/on_play;
        on_stop http://localhost:8000/v1/hooks/on_stop;
        on_hls http://localhost:8000/v1/hooks/on_hls;
   }

}       

Is there a method to allow firing on_connect once? or a method to forward the secret to the other vhost to be authenticated also, or recommned another authentication method to do this.

winlinvip commented 1 year ago

This issue is related to the HTTP callback bug.

As a workaround, you can manage the FFmpeg process independently, since the transcoder is essentially an FFmpeg process. By managing FFmpeg yourself, you can bypass this bug.

duiniuluantanqin commented 1 year ago

You can add [param] after the output as follows, and try again.

transcode {
        enabled     on;
        ffmpeg     /usr/local/bin/ffmpeg;

        engine 360p {
            enabled         on;
            ... ...
            output   rtmp://127.0.0.1:[port]/[app]/[stream][param];
        }
}