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.33k stars 5.33k forks source link

Question: HLS delivery #2274

Closed ifamirhasan closed 3 years ago

ifamirhasan commented 3 years ago

Hello I want to use RTMP to publish stream and HLS for delivery but I could not figure it out. I tried transcoding rtmp with ffmpeg but I could not play it for example on an iphone. Can someone help me to publish by rtmp and deliver with HLS?

akeresztesgh commented 3 years ago

Definitely need more information. What's your configuration file look like? Also, are you able to play it from a browser? (this would use video.js or maybe hls.js) What endpoint are you trying to connect to?

Baa14453 commented 3 years ago

Hello I want to use RTMP to publish stream and HLS for delivery but I could not figure it out. I tried transcoding rtmp with ffmpeg but I could not play it for example on an iphone. Can someone help me to publish by rtmp and deliver with HLS?

Hi, see my config below, I use this to recieve an RTMP stream from OBS, transcode into three qualities and then play over HLS in a browser:

listen              1935;
max_connections     1000;
daemon              off;
srs_log_tank        console;

vhost SecretPasswordVhost {
    gop_cache       off;
    queue_length    10;
    mr {
        enabled     off;
    }
    mw_latency      100;
    transcode {
        enabled     on;
        ffmpeg     ffmpeg;
        engine ff {
            enabled         on;
            vfilter {
                vf scale=w=1920:h=1080:force_original_aspect_ratio=decrease;
                loglevel       debug;
            }
            vcodec          libx264;
            vbitrate        4500;
            vfps            60;
            vwidth          0;
            vheight         0;
            vthreads        4;
            vprofile        high;
            vpreset         superfast;
            vparams {
                g       120;
                tune    zerolatency;
                vlevel  4;
            }
            acodec          aac;
            abitrate        256;
            achannels       2;
            aparams {
            }
            output          rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]-HLS/[stream]_1080-60fps;
        }

        engine ff {
            enabled         on;
            vfilter {
                vf scale=w=1280:h=720:force_original_aspect_ratio=decrease;
                loglevel       quiet;
            }
            vcodec          libx264;
            vbitrate        4000;
            vfps            30;
            vwidth          0;
            vheight         0;
            vthreads        4;
            vprofile        high;
            vpreset         superfast;
            vparams {
                g       60;
                tune    zerolatency;
                vlevel  3.1;
            }
            acodec          aac;
            abitrate        256;
            achannels       2;
            aparams {
            }
            output          rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]-HLS/[stream]_720;
        }

        engine ff {
            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=[vhost]-HLS/[stream]_360;
        }
    }
}

vhost SecretPasswordVhost-HLS {
    gop_cache       off;
    queue_length    10;
    min_latency     on;
    mr {
        enabled     on;
    }
    mw_latency      100;
    hls {
        enabled         on;
        hls_on_error    disconnect;
        hls_fragment    4;
        hls_window      32;
        hls_path        /var/www/video;
        hls_dispose 300;
        hls_m3u8_file   [app]/[stream].m3u8;
        hls_ts_file     [app]/[stream]-[seq].ts;
    }
}

This config produces HLS playlists (.m3u8) and video fragments (.ts) inside /var/www/video/[app]/ Three playlists are made, each one uses different transcoding parameters of above, mainly the resolutions change from 1080, to 720, to 360.

You would stream over RTMP using the below settings: Server: rtmp://<domain name>/ingress?vhost=SecretPasswordVhost Stream Key: StreamKey

ingress fills the space of [app] in the above config StreamKey fills the space of [stream] in the above config. SecretPasswordVhost fills the space of [vhost] in the above config. This part is for security, the StreamKey is not secure because it can be inferred from the URL the user sees, the 'vhost' parameter is normally inferred from the actual domain name that you stream to, but in this case I've defined it manually and used it as a form of security, it's probably not very good but it prevents random people from streaming to your server without whitelisting IPs.

Your web server should serve the directory /var/www/videos/ to https://<domain name>/videos and then your website should load the playlists:

You can load these playlists using a video player that supports HLS. In iOS the <video> tag does this natively, for everyone else you can load an external player like Video.JS, I suggest Oven Player.

HLS also supports a Master Playlist which points to the other three playlists and will auto-select one based on pre-determined bandwidth. SRS can't generate this Master Playlist currently but you can serve one statically, this is what it would look like:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:PROGRAM-ID=1,CLOSED-CAPTIONS=NONE,BANDWIDTH=16000000,RESOLUTION=1920x1080,FRAME-RATE=60.000
/videos/ingress/StreamKey_1080-60fps.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,CLOSED-CAPTIONS=NONE,BANDWIDTH=6400000,RESOLUTION=1280x720,FRAME-RATE=30.000
/videos/ingress/StreamKey_720.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,CLOSED-CAPTIONS=NONE,BANDWIDTH=1600000,RESOLUTION=640x360,FRAME-RATE=30.000
/videos/ingress/StreamKey_360.m3u8
scar63 commented 3 years ago

Hi, thanks for your example @Baa14453 it works really well :)

I would like to inject a custom master playlist into OvenPlayer but I don't understand how I can do it.

Like SRS can't generate this master playlist with the bandwidth info, how can I bypass it and inject my custom master playlist like in your example?

Baa14453 commented 3 years ago

Hi, thanks for your example @Baa14453 it works really well :)

I would like to inject a custom master playlist into OvenPlayer but I don't understand how I can do it.

Like SRS can't generate this master playlist with the bandwidth info, how can I bypass it and inject my custom master playlist like in your example?

Assuming your streamkey or app name never changes (.e.g you always use the same URL when you stream), then you can just create a static master playlist and serve it from a web-server, then tell OvenPlayer to load the Master Playlist as a source e.g.

Create MasterPlaylist.m3u8 and place it in your web directory e.g. /var/www/videos/ Inside it place the URLs for the three HLS playlists you are generating:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:PROGRAM-ID=1,CLOSED-CAPTIONS=NONE,BANDWIDTH=16000000,RESOLUTION=1920x1080,FRAME-RATE=60.000
/videos/ingress/StreamKey_1080-60fps.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,CLOSED-CAPTIONS=NONE,BANDWIDTH=6400000,RESOLUTION=1280x720,FRAME-RATE=30.000
/videos/ingress/StreamKey_720.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,CLOSED-CAPTIONS=NONE,BANDWIDTH=1600000,RESOLUTION=640x360,FRAME-RATE=30.000
/videos/ingress/StreamKey_360.m3u8

In OvenPlayer, point the source to your master playlist: https://<domain name>/videos/MasterPlaylist.m3u8 When using a master playlist, OvenPlayer will automatically load the resolution based on your internet speed.

scar63 commented 3 years ago

Wow that's great, it works perfectly :)

Thank you for this quick response and the detailed explanations

winlinvip commented 3 years ago

👍 @Baa14453 Thanks.