0

I am in a process of making a substitution for Twitch for coders, so they can freely pick/create a category they want to stream in and avoid people who are growing "grass" on Twitch in the "Science & Technology" category.

I've started with nginx-rtmp-module, and build my frontend with this module in mind, however, the problems and limitations i've encountered during the development, or actually, testing phase had me thinking about switching to another product. Specifically, there is no easy (or even possible) way to hide the private stream key from users (those who are going to watch the stream), but this is not the only one.

I've tried Nimble Streamer, however, their "proprietary" approach to this software, which is free to use, however requires you to use their panel to manage streams, which is paid, and to be honest counter intuitive feared me away.

I've tried the Ant Media Server, but yet again, most simple features like authentication is included only with Enterprise version of the software.

Don't get me wrong, I know that later in the "production" stage I will have to think about moving to something more "enterprise" oriented, however, right now, I am just looking for a product, which:

  1. Supports events (stream started, stream ended, stream updated) - nginx-rtmp-module does this already, but as I've already said, it comes with some limitations
  2. Supports REST (or at least presents the data in some way to the reader, which is a script to pull information)
  3. Best, if it is open source or free for development stage

And what this Media Server should be able to do:

  1. Accept RTMP/RTMPS as a source
  2. Produce valid DASH/HLS manifests (nginx-rtmp-module in some cases fails to do so)
  3. Great, but not needed right now, support for adaptive streaming

What I've already tested:

  1. nginx-rtmp-server (and its forks)
  2. Nimble Streamer
  3. Ant Media Server
  4. OSSRS/srs - had problem to even configure it properly, so many warnings on newer types of OSes

Update

I have the following config:

    application live {
        deny play all;      

        live on;
        dash on;

        on_publish http://app.local/api/stream/start;
        on_publish_done http://app.local/api/stream/stop;
        on_update http://app.local/api/stream/update;

        dash_repetition on;
        dash_fragment 5s;
        dash_playlist_length 60s;
        dash_cleanup on;
        dash_nested on;
        dash_clock_compensation http_head;
        dash_clock_helper_uri http://live.local/time;
        dash_path /tmp/dash/stream-dash;
    }

The thing is, stream issued by the /stats page is actually the new public key, however, information about the fragments and manifest is still written in the folder of the private key.

Why stats page shows stream with public key but data is still written in the folder with private key name?

Screenshot from 2019-03-27 17-21-51

Untitled

P.S. And here is the logic of new public key generation written in PHP

Screenshot from 2019-03-27 17-27-54

  1. Extract application and name from the request
  2. Check if request actually has these values (expecting to get two, so counting them)
  3. Plucking $key (name) and $app (application) from resulting array
  4. Caching channel information (here we are checking if channel with this streaming key exists and if it is, caching it in Redis)
  5. Checking if model is null, if it is, then incorrect stream key is provided
  6. Fetching User associated with the Channel
  7. Checking if User is banned from streaming
  8. Creating new Stream entry (with all data associated with RTMP stream and Live status)
  9. Generating cache key form the model (to eliminate further requests to database)
  10. Updating stream cache with default information (everything set to null)
  11. Sending out event to browser that stream has started
  12. Returning 301 response and setting Location to SHA-512 hash of the Stream UUID

The key resulted from step 12 is actually new public key, and as you can see, stats page actually returns this exact key, however, data is still written to the folder with the key name obtained from Step 3

UPDATE #2. Simplified version of key generation algorithm

/**
     * Start stream
     * @return Response
     */
    public function start() : Response
    {
        $requiredStreamKey = 'live_1_B562zv8D6agoozRcXHiiYlvJ1EVVqkF7Q2GBYVE6XkqCsUCH';
        $request = array_values(request()->only(['name', 'app']));
        if (\count($request) < 2) {
            return $this->sendError(Response::HTTP_BAD_REQUEST);
        }
        [$key, $app] = $request;

        if ($requiredStreamKey !== $key) {
                return response('', Response::HTTP_NOT_FOUND);
        }

        $exampleUUID = 'fcefd01c-f379-414c-95f8-c4e6e2b0ffc7';
        $hash = hash('sha512', $exampleUUID);
        return response('Generic Response', Response::HTTP_MOVED_PERMANENTLY)->withHeaders([
            'Location' => sprintf('%s', $hash)
        ]);
    }
halfer
  • 19,824
  • 17
  • 99
  • 186
Ivan Zhivolupov
  • 1,107
  • 2
  • 20
  • 39
  • Recommending software is off topic for stackoverflow. Try serverfault.com. That said, the limitations you mention for nginx are not true. Stream keys do not need to be leaked, and there is no reason ffmpeg will fail to produce a HLS stream unless something else is wrong. – szatmary Mar 29 '19 at 23:54
  • @szatmary Thank you for your reply, i would really like to see an example on how to prevent stream key from leaking. – Ivan Zhivolupov Mar 30 '19 at 17:51
  • I would like to see n example on how you are leaking it :) – szatmary Mar 30 '19 at 17:52
  • @szatmary Sure, just give me 5 minutes to update this post with the information – Ivan Zhivolupov Mar 30 '19 at 18:41
  • @szatmary updated the original question with the information about public key generation and issue with nginx-rtmp-module – Ivan Zhivolupov Mar 30 '19 at 18:54
  • Please not post pictures of text. I can't test it without retyping it, and it's not searchable. – szatmary Mar 30 '19 at 19:50
  • @szatmary I will update post with 'simplified' version of key generation algorithm, just give me 2 minutes – Ivan Zhivolupov Mar 30 '19 at 19:57
  • @szatmary do you have any idea on how to prevent private key leak with the given configuration? – Ivan Zhivolupov Mar 31 '19 at 18:25

1 Answers1

0

SRS is a simple, high efficiency and realtime video server, supports RTMP, WebRTC, HLS, HTTP-FLV, SRT and GB28181.

It accepts a variety of input streams:

  • RTMP: FFmpeg or OBS, also used in many video platforms, like YouTube or Twitch.
  • SRT: is an open source transport technology that optimizes streaming performance across unpredictable networks, such as the Internet.
  • WebRTC: Use H5 to publish stream to SRS, then transmux to RTMP or HLS.

SRS delivers by a set of protocols:

  • RTMP: For other platform or tools, like FFmpeg to transcode.
  • HLS: For mobile H5 player, iOS or Android.
  • HTTP-FLV: For low latency (1~3s) PC H5 player.
  • WebRTC: For realtime streaming (0.5~1s) PC H5 player, or meeting.
  • HDS: Which is deprecated, however it's possible to use it.
  • DASH: Which is experimental feature right now, 2021.12.

Note: For detail about players, please read here.

Also, SRS supports all Linux, ARM, MIPS, Windows(Experimental) and Loonarch, etc.

Apart of protocols, other features is also very improtant, like DVR, Cluster, Transcoding, Snapshot, HTTP API, HTTP Callback, etc.

Ultimately, it's driven by a living open-source community.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
Winlin
  • 1,136
  • 6
  • 25