Goal: Stream from PC using OBS , receive stream with Nginx RTMP Module and output to viewers so that they can view the live stream both on PC and mobile. For that to happen, Nginx must output live stream with HLS.
My partner has set up the following Nginx file, but nothing occurs (it was done following this answer from stackoverflow --> answer )
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 8080;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}
location /stat.xsl {
# you can move stat.xsl to a different location
root /usr/build/nginx-rtmp-module;
}
# rtmp control
location /control {
rtmp_control all;
}
# Client (VLC etc.) can access HLS here.
location /hls {
# Serve HLS fragments
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp;
add_header Cache-Control no-cache;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
record off;
}
application directo {
live on;
record off;
}
# You should send x.264/aac RTMP Stream via ffmpeg to this application
application hls {
allow play all;
live on;
hls on;
hls_path /tmp/hls;
}
}
}
And this is a capture of the OBS streaming configuration:
PC can view the stream just fine, but mobile can't.
Appreciate any input anyone may have.
I did test over ubuntu 16.04 LTS and it works with that following instructions:
cd $HOME
git clone https://github.com/arut/nginx-ts-module.git
wget https://nginx.org/download/nginx-1.13.8.tar.gz
git clone https://github.com/sergey-dryabzhinsky/nginx-rtmp-module.git
sudo apt-get install build-essential libpcre3 libpcre3-dev libssl-dev
tar -xf nginx-1.13.8.tar.gz
cd nginx-1.13.8/
sudo apt update
sudo apt install autoconf automake build-essential libpcre3 libpcre3-dev libssl-dev
./configure --with-http_ssl_module --add-module=../nginx-rtmp-module --with-http_stub_status_module --add-module=../nginx-ts-module
make
sudo make install
Then you need to update the .conf file:
cd /usr/local/nginx/conf/
sudo nano nginx.conf
Conf file:
worker_processes auto;
events {
worker_connections 1024;
}
# RTMP configuration
rtmp {
server {
listen 1935; # Listen on standard RTMP port
chunk_size 4000;
application show {
live on;
# Turn on HLS
hls on;
hls_path /mnt/hls/;
hls_fragment 3;
hls_playlist_length 60;
# disable consuming the stream from nginx as rtmp
deny play all;
# Instruct clients to adjust resolution according to bandwidth
hls_variant _low BANDWIDTH=512000; # Low bitrate, sub-SD resolution
hls_variant _mid BANDWIDTH=1024000; # Medium bitrate, SD resolution
hls_variant _hd720 BANDWIDTH=2048000; # High bitrate, HD 720p resolution
}
}
}
http {
sendfile off;
tcp_nopush on;
#aio on;
directio 512;
default_type application/octet-stream;
server {
listen 8080;
location / {
# Disable cache
add_header 'Cache-Control' 'no-cache';
# CORS setup
add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length';
# allow CORS preflight requests
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
types {
application/dash+xml mpd;
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
location /stats {
stub_status;
}
root /mnt/;
}
To start your nginx server (first kill it then start it):
sudo /usr/local/nginx/sbin/nginx -s stop
sudo /usr/local/nginx/sbin/nginx
To view stats of your nginx server:
Where is the public ip of your server.
http://<ip_of_your_nginx_server>:8080/stats
From your encoder such as OBS:
Stream to your nginx server with that adress:
rtmp:///show/stream_hd720
Do a 1280x720 at 2500kbps and 1 audio stereo at 128kbps
If you want to see your stream on VLC:
Open a network stream then paste that:
http://<ip_of_your_nginx_server>:8080/hls/stream.m3u8
You should see your stream.
If you want to host a HLS player where your viewers can watch your stream for free:
sudo apt install screen
Put your http server in a screen session:
screen -dmS httpSTREAM
Access to your screen:
screen -r httpSTREAM
Then start your server:
python -m SimpleHTTPServer 7788
Create your html page with Hls player:
touch player.html
sudo nano player.html
and paste:
Change that line with the correct ip hls.loadSource('http://<ip_of_your_nginx_server>:8080/hls/stream.m3u8'); to your needs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>CHAN.1</title>
<!-- Bootstrap -->
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<h1>CHAN 2018 - STREAM.1</h1>
<script src="https://cdn.jsdelivr.net/npm/hls.js#latest"></script>
<div class="well">
<div class="embed-responsive embed-responsive-16by9">
<video id="video" width=720 class="video-js vjs-default-skin" controls></video>
</div>
</div>
<script>
if(Hls.isSupported()) {
var video = document.getElementById('video');
var hls = new Hls();
hls.loadSource('http://163.172.128.64:8080/hls/stream.m3u8');
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED,function() {
video.play();
});
}
</script>
<div id="footer">
<font size="2"> © Ekla Ingenierie - 2018 www.ekla.tv</font>
</div>
</body>
</html>
obe#scw-eklaingenierie-c2:~$ cat player.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>CHAN.1</title>
<!-- Bootstrap -->
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<h1>My Stream</h1>
<div class="well">
<div class="embed-responsive embed-responsive-16by9">
<video id="video" width=720 class="video-js vjs-default-skin" controls></video>
</div>
</div>
<script>
if(Hls.isSupported()) {
var video = document.getElementById('video');
var hls = new Hls();
hls.loadSource('http://<ip_of_your_nginx_server>:8080/hls/stream.m3u8');
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED,function() {
video.play();
});
}
</script>
<div id="footer">
<font size="2"> © MyStreaming - 2018</font>
</div>
</body>
</html>
Then access to your player from a chrome browser and paste that link:
http://<ip_of_your_nginx_server>:7788/player.html
Now you do a complete streaming !!
First of all, you have to point your encoders to your server's ip address through the RTMP option, that would be the first thing. Then, after that you have to add a directive to the configuration file you just posted, for example:
# RTMP configuration
rtmp {
server {
listen 1935; # Listen on standard RTMP port
chunk_size 4000;
# This application is to accept incoming stream
application live {
live on; # Allows live input
# Once receive stream, transcode for adaptive streaming
# This single ffmpeg command takes the input and transforms
# the source into 4 different streams with different bitrate
# and quality. P.S. The scaling done here respects the aspect
# ratio of the input.
exec ffmpeg -i rtmp://localhost/$app/$name -async 1 -vsync -1
-c:v libx264 -c:a libvo_aacenc -b:v 256k -b:a 32k -vf "scale=480:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost/show/$name_low
-c:v libx264 -c:a libvo_aacenc -b:v 768k -b:a 96k -vf "scale=720:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost/show/$name_mid
-c:v libx264 -c:a libvo_aacenc -b:v 1024k -b:a 128k -vf "scale=960:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost/show/$name_high
-c:v libx264 -c:a libvo_aacenc -b:v 1920k -b:a 128k -vf "scale=1280:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost/show/$name_hd720
-c copy -f flv rtmp://localhost/show/$name_src;
}
# This application is for splitting the stream into HLS fragments
application show {
live on; # Allows live input from above
hls on; # Enable HTTP Live Streaming
# Pointing this to an SSD is better as this involves lots of IO
hls_path /mnt/hls/;
# Instruct clients to adjust resolution according to bandwidth
hls_variant _low BANDWIDTH=288000; # Low bitrate, sub-SD resolution
hls_variant _mid BANDWIDTH=448000; # Medium bitrate, SD resolution
hls_variant _high BANDWIDTH=1152000; # High bitrate, higher-than-SD resolution
hls_variant _hd720 BANDWIDTH=2048000; # High bitrate, HD 720p resolution
hls_variant _src BANDWIDTH=4096000; # Source bitrate, source resolution
}
}
}
http {
# This optimizes the server for HLS fragment delivery
sendfile off;
tcp_nopush on;
aio on;
directio 512;
# HTTP server required to serve the player and HLS fragments
server {
listen 80;
location / {
root /path/to/web_player/;
}
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
}
root /mnt/;
add_header Cache-Control no-cache; # Prevent caching of HLS fragments
add_header Access-Control-Allow-Origin *; # Allow web player to access our playlist
}
}
}
Related
I do get the following errors and warnings on the firefox console logs, but nothing displays on the Chrome console logs.
errors such as,
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://googleads.g.doubleclick.net/pagead/id. (Reason: CORS request did not succeed). Status code: (null).
warnings such as,
Some cookies are misusing the recommended “SameSite“ attribute
The resource at “<URL>” was blocked because content blocking is enabled.
following are a similar sample of static HTML code and Nginx config file.
HTML,
<!DOCTYPE html>
<html lang="ja">
<head>
<title>title</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Security-Policy" content="frame-src youtube.com www.youtube.com">
<link rel="stylesheet" href="styles.css" type="text/css" />
<script
src="https://ajax.googleapis.com/ajax/libs/webfont/1.6.26/webfont.js"
type="text/javascript"></script>
<script type="text/javascript">
WebFont.load({
google: {
families: ['Noto Sans JP:100,300,regular,500,700,900:japanese,latin'],
},
});
</script>
</head>
<body class="body">
<div class="video">
<div class="yt-video">
<iframe src="https://www.youtube.com/embed/tgbNymZ7vqY" title="test" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
</div>
</body>
</html>
nginx headers & security policy headers in the server block as follows,
add_header Content-Security-Policy "script-src 'self' 'unsafe-inline' 'unsafe-eval' *.youtube.com *.googleapis.com; frame-src 'self' *.youtube.com; object-src 'self'";
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
I would like to know how to get rid of these errors if possible or should i just ignore, any kind of advice would be helpful.
Thank you.
I am total Nginx newbie and I am doing my best to compose a UI. Let me give You my short nginx config file:
upstream wizard {
server wizard:80;
}
server {
listen 80;
server_name localhost;
ssi on;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri /index.html;
}
location /wizard {
proxy_pass http://wizard;
}
}
and the "master" html with SSI command:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Portal</title>
</head>
<body>
<h1>Portal</h1>
<!--#include virtual="/wizard" -->
</body>
</html>
and the index.html from the location pointed by the proxy;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>My web</title>
<h2>IPA</h2>
<script type="module" crossorigin src="/assets/index.41982ecd.js"></script>
<link rel="modulepreload" href="/assets/vendor.d39310c0.js">
<link rel="stylesheet" href="/assets/index.f1b61ee0.css">
</head>
<body>
<div id="app"></div>
</body>
</html>
Now this lines from the last html are problematic:
src="/assets/index.41982ecd.js"
href="/assets/vendor.d39310c0.js"
href="/assets/index.f1b61ee0.css"
Because I get 404 not found. The problem is obvious, nginx fetches the html, does SSI and then the browser tries to load the script, css which are not there (they are in the site pointed by the proxy). I can solve this by adding next location in the nginx config:
location /assets {
proxy_pass http://wizard;
}
But is there another way? I can imagine I will have more web pages with asset folders. I can do the renames but yeah... I am looking for other options to solve this.
This is nginx configuration page.what code i have to change to get an image on maintenance html page.
server {
listen 80;
server_name 10.10.10.72;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/fa/timesheet;
}
location / {
if ($remote_addr != 10.10.10.120) {
return 503;
}
include proxy_params;
proxy_pass http://unix:/home/fa/timesheet/timesheet.sock;
}
#Error pages.
error_page 503 /maintenance.html;
location = /maintenance.html {
root /home/fa/timesheet ;
}
}
My Maintenance HTML page is:
<html>
<body>
<h1 style="text-align:center;">
<h1 style="color:#33B2FF;">Timesheet has gone for time travel..... will be back with more users :)</h1>
<h1 style="color:#83A1B4;">Please visit later.</h1>
</body>
</html>
I have to insert an image on it. Please help.
Thanks in advance
Put all your all custom html and images in a directory maintenance
/home/fa
maintenance/maintenance.html
maintenance/maintenance.png
Put image tag in your maintenance.html
<html>
<body>
<h1 style="text-align:center;">
<h1 style="color:#33B2FF;">Timesheet has gone for time travel..... will be back with more users :)</h1>
<h1 style="color:#83A1B4;">Please visit later.</h1>
<img src="maintenance.png" alt="maintenance" height="200" width="200">
</body>
</html>
And change this lines in your nginx.conf:
error_page 500 502 503 504 /maintenance.html;
location = /maintenance.html {
root /home/fa/maintenance_pages;
}
location = /image.png {
root home/fa/maintenance_pages;
}
And if you have problem in rendering image types read this link also: https://stackoverflow.com/a/19111990/6107715
I searched enough but couldn't sort out how to configure mpeg-dash vod in nginx using nginx_vod_module .
Configuration inside http server block for enabling dash is
location /voddash {
vod dash;
vod_mode local;
root /usr/share/nginx/html;
gzip on;
gzip_types application/dash+xml mpd;
add_header Access-Control-Allow-Headers "origin,range,accept-encoding,referer";
add_header Access-Control-Expose-Headers "Server,range,Content-Length,Content-Range";
add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS";
add_header Access-Control-Allow-Origin "*";
expires 100d;
add_header Last-Modified "Sun, 19 Nov 2000 08:52:00 GMT";
}
Request url is http://localhost/voddash/Input.mp4/manifest.mpd .
I have placed only Input.mp4 in dash location. How can i stream dash content .Also is there anything like streaming of precreated manifest and chunks in nginx for mpeg dash?
I have the same configuration on my server and use the following html + js code to play the dynamically generated manifest.mpd file:
<!doctype html>
<html>
<head>
<title>Dash.js Rocks</title>
<style>
video {
width: 640px;
height: 360px;
}
</style>
</head>
<body>
<div>
<video id="videoPlayer" controls></video>
</div>
<script src="http://dashif.org/reference/players/javascript/nightly/dash.js/dist/dash.all.min.js"></script>
<script>
(function(){
var url = "http://localhost/voddash/Input.mp4/manifest.mpd";
var player = dashjs.MediaPlayer().create();
player.initialize(document.querySelector("#videoPlayer"), url, true);
})();
</script>
</body>
</html>
this is my supervisord web config, with no password
[inet_http_server]
port=127.0.0.1:9001
;username=user
;password=1234
and this is my nginx config for it
location /supervisor/ {
proxy_pass http://127.0.0.1:9001;
proxy_set_header X-Forwarded-Host $server_name;
proxy_set_header X-Real-IP $remote_addr;
add_header P3P 'CP="ALL DSP COR PSAa PSDa OUR NOR ONL UNI COM NAV"';
}
If I access 127.0.0.1:9001 directly from within my server I get the info I need:
root#gosthost:~# curl 127.0.0.1:9001
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Supervisor Status</title>
<link href="stylesheets/supervisor.css" rel="stylesheet" type="text/css" />
<link href="images/icon.png" rel="icon" type="image/png" />
</head>
<body>
<div id="wrapper">
... bla bla bla
</div>
<div class="clr" id="footer">
<div class="left">
Supervisor <span>3.1.3</span>
</div>
<div class="right">
© 2006-<span>2015</span> <strong>Agendaless Consulting and Contributors</strong>
</div>
</div>
</body>
but if I try to access it from outside world it gives me 404:
root#gosthost:~# curl http://46.101.172.89/supervisor/
<head>
<title>Error response</title>
</head>
<body>
<h1>Error response</h1>
<p>Error code 404.
<p>Message: Not Found.
</body>
But that's not nginx's native response. I can see that because nginx signs its own error responses, see below. This is typical nginx response
curl http://46.101.172.89/media/
<html>
<head><title>403 Forbidden</title></head>
<body bgcolor="white">
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.6.2</center>
</body>
</html>
so there is something wrong with supervisor. What could that be?
little bit late, but I had the same problem and was trying everything and found solution
proxy_pass http://127.0.0.1:9001/;
you missed / :)