Question / Help How to stream to HTML5? (without JWPlayer or VLC)

Tormy

Member
I try to setup OBS + NGINX in order to be able to stream to any HTML 5 tag <videosrc="">, instead to VLC or JWPlayer
But I'm not able to watch the content.
Can you please help me?

I'm under W7 64 bit OBS 22.0.2
Please her below the settings I use

NGINX

NGINX:
worker_processes  1;

error_log  logs/error.log debug;
error_log  logs/error.log  debug;
error_log  logs/error.log  notice;
error_log  logs/error.log  info;
pid        logs/nginx.pid;

events {
    worker_connections  1024;
    # max value 16384, nginx recycling connections+registry optimization =
    #   this.value * 20 = max concurrent connections currently tested with one worker
    #   C1000K should be possible depending there is enough ram/cpu power
    multi_accept on;
}


rtmp {
    server {
        listen 1935;
        chunk_size 8192;
        application live {
            live on;
            meta copy;
            wait_key on;
            wait_video on;
            record off;
            idle_streams off;
            allow publish 127.0.0.1;
            deny publish all;
            hls on;
            hls_path /temp/hls;
        }
    }
}


http {
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    server_tokens off;

    include mime.types;
    default_type application/octet-stream;

    access_log logs/access.log;
    error_log logs/error.log;

    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name _;

        root /;
        index index.html;

        location hls/ {
            root temp;
            add_header Cache-Control no-cache;
        }
    }
}


OBS Settings to stream to NGINX (and it works)
Code:
URL: rtmp://127.0.0.1:1935/live
streamkey: live


here the HTML page I would like to use to watch the streaming

HTML:
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
    <video src="http://127.0.0.1/hls/live"></video>
</body>
</html>

I obtain always lank page
 

Tormy

Member
Ok I think I came up to a solution, reading your link and looking for more info in the internet and also on this forum.
I did cross many many many useless settings and fake stuff in the internet, but at the end I solved and I want to share it, in case somebody else got the same issue, and found no answers (rather than craps.
I report als the links where I found the useful informations.

Settings NGINX
It should be with RTMP module of course. Here my settings into conf/nginx.conf

NGINX:
# https://www.nginx.com/blog/scalable-live-video-streaming-nginx-plus-bitmovin
# https://nwgat.ninja/quick-easy-nginx-with-rtmp-streaming-support/
# https://github.com/video-dev/hls.js HLS
# *******************************************************************
# important notes for OBS studio on RTMP
# OBSstudio url
# rtmp://localhost:1935/live

# OBSstudio StreamKey
# live

# HTTP access
# http://localhost:8080/live/live/index.m3u8
# http://localhost:8080/        Welcome Nginx
# *******************************************************************
# Folders
# C:\nginx\nginx.exe
# C:\nginx\hls\live
# C:\nginx\hls\mobile
# C:\nginx\dash
# C:\nginx\html
# C:\nginx\conf
# C:\nginx\temp
# C:\nginx\logs
# C:\nginx\stats
# C:\nginx\videos
# C:\nginx\stream\dash
# C:\nginx\stream\hls
# *******************************************************************

worker_processes  1;
error_log  logs/error.log debug;
error_log  logs/error.log  notice;
error_log  logs/error.log  info;
pid        logs/nginx.pid;

events {
    worker_connections  1024;
    # max value 16384, nginx recycling connections+registry optimization =
    #   this.value * 20 = max concurrent connections currently tested with one worker
    #   C1000K should be possible depending there is enough ram/cpu power
    multi_accept on;
}

rtmp {
    server {
    listen 1935;
    chunk_size 8192;
    publish_time_fix off;
    allow play all;

        #creates our "live" full-resolution DASH videostream from our incoming encoder stream and tells where to put the DASH video manifest and video fragments
        application dash {
            allow play all;
            live on;
            #record all;
            record off;
            record_path videos;
            record_unique on;
            #allow publish <your_sender_ip_here>;
            allow publish 127.0.0.1;
            deny publish all;
            meta copy;
            wait_key on;
            wait_video on;
            idle_streams off;
          
            # Dash settings and pushing towards repeaters
            dash on;
            dash_nested on;
            dash_path stream/dash;
            dash_fragment 3;
            dash_playlist_length 20;
            dash_cleanup on;

            #dash_clock_compensation http_head;
            #dash_clock_helper_uri https://<your_server_domain_here>/time;

            #dash_variant _low   bandwidth="500000"  width="640"  height="360";
            #dash_variant _med  bandwidth="1500000" width="1280"  height="720";
            #dash_variant _high bandwidth="5000000" width="1920" height="1080" max;
          
            push rtmp://localhost/hls/hls; // it goes to generate a HLS streaming

        }     
      
        application hls {
            # I despise iOS devices!
            live on;
            hls on;
            hls_path stream/hls;
            hls_nested on;

            hls_variant _low   BANDWIDTH=500000;
            hls_variant _med  BANDWIDTH=1500000;
            hls_variant _high BANDWIDTH=5000000;
        }
    }
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        off; 
    #keepalive_timeout  65;

    server {
        listen 8080;
        #server_name home;

        #creates the http-location for HLS stream - "http://localhost:8080/hls/live/index.m3u8"  
        location /hls {
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            #alias HLS/live;
            root "C:/ngingx/stream";
            add_header Cache-Control no-cache;
            add_header Access-Control-Allow-Origin *;
        }
        #creates the http-location for DASH stream - "http://localhost:8080/dash/live/index.mpd"           
        location /dash {
            root "C:/nginx/stream";
            add_header Cache-Control no-cache;
            add_header Access-Control-Allow-Origin *;
        }

        #allows us to host some webpages which can show our videos: "http://localhost:8080/index.html" 
        location / {
            root   c:/nginx/html;
            index  index.html index.htm;
        }
    }
}


Settings on OBS
1546820425757.png



HTML page for DASH
Download dash.min.js from here http://cdn.dashjs.org/latest/jsdoc/index.html

HTML:
<!doctype html>
<html>
<!--
http://reference.dashif.org/dash.js/v2.9.2/samples/dash-if-reference-player/index.html
http://cdn.dashjs.org/latest/jsdoc/index.html
-->
    <head>
        <title>Dash.js Rocks</title>
        <style>
            video {
                width: 1280px;
                height: 720px;
            }
        </style>
    </head>
    <body>
        <div>
            <video data-dashjs-player autoplay src="http://127.0.0.1:8080/dash/live/index.mpd" controls>
            </video>
        </div>
        <script src="dash.all.min.js"></script>
    </body>
</html>

HTML for HLS
HTML:
<!DOCTYPE html>
<html lang="en">
<!-- <script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script> -->
<!-- Or if you want a more recent canary version -->
<script src="https://cdn.jsdelivr.net/npm/hls.js@canary"></script>
<video id="video"></video>
<script>
  var video = document.getElementById('video');
  if(Hls.isSupported()) {
    var hls = new Hls();
    hls.loadSource('http://127.0.0.1:8080/hls/hls/index.m3u8');
    hls.attachMedia(video);
    hls.on(Hls.Events.MANIFEST_PARSED,function() {
      video.play();
  });
}
// hls.js is not supported on platforms that do not have Media Source Extensions (MSE) enabled.
// When the browser has built-in HLS support (check using `canPlayType`), we can provide an HLS manifest (i.e. .m3u8 URL) directly to the video element throught the `src` property.
// This is using the built-in support of the plain video element, without using hls.js.
// Note: it would be more normal to wait on the 'canplay' event below however on Safari (where you are most likely to find built-in HLS support) the video.src URL must be on the user-driven
// white-list before a 'canplay' event will be emitted; the last video event that can be reliably listened-for when the URL is not on the white-list is 'loadedmetadata'.
  else if (video.canPlayType('application/vnd.apple.mpegurl')) {
    video.src = 'http://127.0.0.1:8080/hls/hls/index.m3u8'';
    video.addEventListener('loadedmetadata',function() {
      video.play();
    });
  }
</script>


[B][COLOR=rgb(250, 197, 28)][SIZE=6]C:\nginx\html\crossdomain.xml[/SIZE][/COLOR][/B]
[CODE=html]<?xml version="1.0"?>
<cross-domain-policy>      
<allow-access-from domain="*" to-ports="80,443" secure="false"/>        
<site-control permitted-cross-domain-policies="master-only" />  
</cross-domain-policy>

</html>[/CODE]

Her and there there is some flaw, but it's working ...
 
Last edited:

Tormy

Member
It' snot fully reliable and not always working fine. But at least I got something ... now ... if somebody is able to solve the stability issues, I will be very grateful

EDIT I updated the HTML for the DASH. Now it's reliable and stable. The HLS needs some work again. However thi is the way to use HTML5 with RTMP to broadcast to your site etc. Example: visual radios that are using OBS etc
 
Last edited:

jf9292

New Member
Thank you for your config. The issue I am having is that the Dash of HLS website will not play the video. I have no issue with VLC playing both links. The Website code will not play either video.
I have pretty much the same conf as what was posted.
 

Tormy

Member
Thank you for your config. The issue I am having is that the Dash of HLS website will not play the video. I have no issue with VLC playing both links. The Website code will not play either video.
I have pretty much the same conf as what was posted.
To me it works with Chrome, FF and IE.Ma be some glitchy, but what's impeding you to use the DASH instead?
 

jf9292

New Member
Sorry I am trying to use dash.

This is my code

<!doctype html>
<html>
<!--
http://reference.dashif.org/dash.js/v2.9.2/samples/dash-if-reference-player/index.html
http://cdn.dashjs.org/latest/jsdoc/index.html
-->
<head>
<title>Dash.js Rocks</title>
<style>
video {
width: 1280px;
height: 720px;
}
</style>
</head>
<body>
<div>
<video data-dashjs-player autoplay src="http://10.85.16.107:8080/dash/live/index.mpd" controls>
</video>
</div>
<script src="https://cdn.dashjs.org/latest/dash.all.min.js"></script>



</body>
</html>


If I remove data-dashjs-player autoplay from the video tag I can get it to play in Edge but won't work in Chrome and FF
 

Tormy

Member
Sorry I am trying to use dash.

This is my code

<!doctype html>
<html>
<!--
http://reference.dashif.org/dash.js/v2.9.2/samples/dash-if-reference-player/index.html
http://cdn.dashjs.org/latest/jsdoc/index.html
-->
<head>
<title>Dash.js Rocks</title>
<style>
video {
width: 1280px;
height: 720px;
}
</style>
</head>
<body>
<div>
<video data-dashjs-player autoplay src="http://10.85.16.107:8080/dash/live/index.mpd" controls>
</video>
</div>
<script src="https://cdn.dashjs.org/latest/dash.all.min.js"></script>



</body>
</html>


If I remove data-dashjs-player autoplay from the video tag I can get it to play in Edge but won't work in Chrome and FF
I don't consider edge any longer since Microsoft is cleared intentioned to dismiss it and do not create any longer a webbrowser.
IE: I used just becuase it's on my PC ... just out of curiosity ...
 
Last edited:

jf9292

New Member
nginx-rtmp-win32
================

* Nginx: 1.13.12
* Nginx-Rtmp-Module: 1.2.1
* openssl-1.0.2o
* pcre-8.42
* zlib-1.2.11

Thanks that helped out. I was using the wrong version. The only I have with Chrome right now it plays for a few seconds then buffers then starts again. Did you run into this issue?
 

dashdash

New Member
This is kind of an old thread. But I'm working on the same project Tormy.

I followed your settup closely. I am using an EC2 server hosted on AWS that has rtmp enabled.

I was able to send a stream to rtmp://ec2-xx-xxx-xxx-xxx.compute-1.amazonaws.com:1935/live

but I fail to send a stream to rtmp://ec2-xx-xx-xxx-xxx.compute-1.amazonaws.com:1935/dash (I get an error when using this url for the server location)


Not sure how to post code correctly. But I created a post on stackoverflow that has the code.

https://stackoverflow.com/questions...s-stream-from-personal-rtmp-server-on-aws-ec2

Any help would be greatly appreciated..
 

Tarumes

Member
Have fun testing around

Code:
worker_processes  auto;
worker_priority -20;
worker_shutdown_timeout 5;

error_log  logs/error.log;

events {
    worker_connections  1024;
}
rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;

rtmp {
    server {
        listen 1935;
       
        application incoming {
            live on;
            deny play all;
            push rtmp://127.0.0.1/view/stream;
            #push rtmp://twitch youtube etc.....
        }
       
        application view {
            live on;
            allow publish 127.0.0.1;
            deny publish all;
            hls on;
            hls_path html/hls;
            hls_fragment 10s;
            hls_playlist_length 60s;
            hls_fragment_naming timestamp;
            hls_fragment_slicing aligned;
            hls_type live;
            hls_cleanup on;
            recorder all {
                record all;
                record_path html/record/stream;
                record_lock on;
                record_unique on;
            }
        }
    }
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        off;
    server_tokens off;
   
    server {
        listen      8080;
       
        location / {
            root html;
        }
       
        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }

        location /stat.xsl {
            root html;
        }
        location /control {
            rtmp_control all;
        }
    }
}

Documentation here
https://github.com/novage/p2p-media-loader

https://cdn.jsdelivr.net/npm/p2p-media-loader-core@latest/build/p2p-media-loader-core.min.js
https://cdn.jsdelivr.net/npm/p2p-media-loader-hlsjs@latest/build/p2p-media-loader-hlsjs.min.js
https://cdn.jsdelivr.net/npm/hls.js@latest

HTML:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta name="description" content="MediaDB">
    <meta name="author" content="Tarumes">
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
   
    <link href="css/style.css" rel="stylesheet" type="text/css"/>
    <link href="css/style_video.css" rel="stylesheet" type="text/css"/>
    <link href="css/bootstrap.css" rel="stylesheet" type="text/css"/>

    <script src="js/jquery-3.4.1.min.js"></script>
    <script src="js/p2p-media-loader-core.min.js"></script>
    <script src="js/p2p-media-loader-hlsjs.min.js"></script>
    <script src="js/hls.js"></script>
    <title></title>
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="h-auto col">
                <video id="video" autoplay=true controls muted style="max-height: 720px;"></video>
            </div>
            <div id="chat_container" class="col-m-2 col-l-2 col-xl-2">
                <div class="container">
                    <div class="row">
                        <div id="chat_main" class="col">Chat Main</div>
                    </div>
                </div>
            </div>
        </div>
    </div>
   
    <script src="js/jquery-3.4.1.min.js"></script>
    <script src="js/popper.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script>
        if (Hls.isSupported() && p2pml.hlsjs.Engine.isSupported()) {
            var engine = new p2pml.hlsjs.Engine();
            var hls = new Hls({
                liveSyncDurationCount: 7, // To have at least 6 segments in queue
                loader: engine.createLoaderClass()
            });
            p2pml.hlsjs.initHlsJsPlayer(hls);
            hls.loadSource("hls/stream.m3u8");
            var video = document.getElementById("video");
            hls.attachMedia(video);
        } else {
            document.write("Not supported :(");
        }
    </script>
</body>
</html>
 

Rosiero

New Member
Hi there, I've been following this guide to try and get a Dash player working for my server. I'm 90% of the way there; I'm able to use OBS to stream to the server, and I can load the index.mpd in VLC and it will play just fine. However, when I try to use dash.js (using the "quickstart for users" code from their website), the stream doesn't load. The Javascript console gives these errors:
Code:
[2486][ScheduleController][video] Start denied to Schedule Controller
[2486][ScheduleController][audio] Start denied to Schedule Controller
I'm also unable to load the stream on the Dash.JS reference player, where it gives an error of "Data update failed" repeatedly.

I've tried multiple versions of nginx, including the 1.13.2 with the 1.2.1 RTMP module mentioned above. I found all these builds premade through Google since I'm not savvy enough to build myself.

Does anyone know what I'm doing wrong?
 
Top