I have an nginx web server with the RTMP module running perfectly and pushing out video to several RTMP destinations (Facebook, YouTube, Periscope, etc.).
I now need the stream to output in the HLS protocol so I can build a custom player for it without flash dependency. I've tried following a few other tutorials, but I am struggling.
I have the default config file that came with the installation of nginx with the following added to the end:
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
record off;
push rtmp://<streaming-service/key>
}
}
}
What exactly do I need to add to this config file to retain my ability to push out video to these RTMP destinations as well as have a HLS feed I can use in a player without Flash?
I already have FFMPEG installed on the machine in order to send video to Periscope. I've seen solutions that do not need FFMPEG, but I just wanted to add that I did have it installed and am somewhat familiar with it.
EDIT: for more information, I am sending video through the server via a Teradek encoder.
I solved this with FFMPEG. The pull directive wasn't working properly. Here's the config file that worked for me:
#user nobody;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
server {
listen 80;
server_name localhost;
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp/;
add_header Cache-Control no-cache;
add_header 'Access-Control-Allow-Origin' '*';
}
location / {
root html;
index index.html index.htm;
}
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;
push rtmp://<location/key>
exec ffmpeg -i rtmp://localhost/live/test -vcodec libx264 -vprofile baseline -x264opts keyint=40 -acodec aac -strict -2 -f flv rtmp://localhost/hls/test;
}
application hls {
live on;
hls on;
hls_path /tmp/hls/;
hls_fragment 6s;
hls_playlist_length 60s;
}
}
}
Related
I have successfully setup nginx-rmtp-module for live streaming, i have tested it with obs software, it works great !
But i am having trouble to save the video on s3bucket for future use.
This is what i setup:
rtmp {
server {
listen 1935;
chunk_size 4096;
allow publish 127.0.0.1;
deny publish all;
application live {
live on;
record off;
hls on;
hls_path /var/www/html/stream/hls;
hls_fragment 3;
hls_playlist_length 60;
dash on;
dash_path /var/www/html/stream/dash;
}
}
}
and this is http
server {
listen 8088;
location / {
add_header Access-Control-Allow-Origin *;
root /var/www/html/stream;
}
}
types {
application/dash+xml mpd;
}
It works great, no complain at all ! But i am finding a way to push to my s3bucket. i want when a user go live, i want to save that video on s3bucket for future use.
i have google lots but coudlnt find any solution, is it possible?
i configure server using nginx - rtmp plugin module.
The Problem is rtmp publish.
rtmp plugin module support "on_publish_done" command.
https://github.com/arut/nginx-rtmp-module/wiki/Directives#on_publish_done
and i want like this.
on_publish_done http://MY_SERVER/$APP/$NAME ;
In nginx configure file(nginx.conf) can use $arg_XXX value.
But my conf-file can not observe value. Observe just string "$arg_app", "$arg_name".
How to observe $arg_app, $arg_name ??
this is my conf file.
# HTTP can be used for accessing RTMP stats
http {
access_log /Users/steve/dev/workspace/nginx/logs/access.log;
server {
listen 8080;
location /local_redirect {
rewrite ^.*$ newname? permanent;
}
location /cast {
# Serve HLS fragments
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /Users/steve/dev/workspace/nginx/tmp;
add_header Cache-Control no-cache;
}
}
}
rtmp {
access_log /PATH/nginx/logs/rtmp-access.log;
server {
listen 1935;
chunk_size 4000;
application cast {
live on;
publish_notify on;
hls on;
hls_path /PATH/workspace/nginx/out;
hls_nested on;
hls_fragment 1s;
hls_playlist_length 12s;
}
notify_method get;
on_publish_done http://127.0.0.1:5000/$arg_app/$arg_name ; ##PROBLEM HERE!!
}
}
[the image below shows that a variable with an underscore which is located between character r and b works well! ][1]
for me the code below using bash command with a -c flag works! try it bro
exec_publish_done bash -c "/var/hls/ex.sh ${name}";
I am trying to build a live stream platform using nginx and nginx-http-flv-module (with nginx-rtmp-module).
I have been using nginx-http-flv-module's guide.
I built an nginx server with rtmp and http-flv support.
My nginx.conf file:
#user nobody;
worker_processes 1;
error_log logs/error.log debug;
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 /live {
flv_live on; #open flv live streaming (subscribe)
chunked_transfer_encoding on; #open 'Transfer-Encoding: chunked' response
add_header 'Access-Control-Allow-Origin' '*'; #add additional HTTP header
add_header 'Access-Control-Allow-Credentials' 'true'; #add additional HTTP header
add_header 'Access-Control-Expose-Headers' 'Content-Length';
}
}
}
rtmp {
server {
listen 1935;
ping 30s;
notify_method get;
application myapp {
live on;
}
}
}
I start publishing my stream using OBS and play the stream in the browser using flv.js like this:
<video id="videoElement" controls autoplay></video>
...
<script>
let videoElement = document.getElementById('videoElement');
let flvPlayer = flvjs.createPlayer({
type: 'flv',
isLive: "true",
url: 'http://192.168.1.122:8080/live?port=1935&app=myapp&stream=test'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
</script>
And everything works great! The stream is playing in the browser as expected. But the problem is whenever a second viewer starts watching the stream (if I open it in another browser tab f.e). The player stops playing and starts infinite loading. So what can cause this problem?
I am the owner of nginx-http-flv-module, I am sorry that the bug was caused by the commit on July 7, 2019 and it has been fixed already.
You can try the latest code.
I have installed and started the Nginx server on Ubuntu 14.04. My objective is to stream a video (live) using HLS (HTTP live streaming). I followed this tutorial https://www.vultr.com/docs/setup-nginx-on-ubuntu-to-stream-live-hls-video, and it recommends using OBS-STUDIO. However, I don't know how to stream from the OBS-STUDIO to the Nginx and then view the stream from other machines (e.g. with VLC).
Add a media source for OBS.
Configure the self-defined media server on OBS, add a URL as follows:
URL: rtmp://domain_name:1935/hlslive
stream name: test
Build Nginx with nginx-rtmp-module ,install, and then config nginx.conf
vim /usr/local/nginx/conf/nginx.conf
add or config the following module:
rtmp {
server {
listen 1935; #listen port
chunk_size 4096;
application hlslive { #rtmp push stream request path
live on;
hls on;
hls_path /usr/share/nginx/html/hlslive/test;
hls_fragment 3s;
hls_playlist_length 18s;
}
}
}
also config as a http server for hls m3u8 request:
http {
...
server {
listen 8080;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
run nginx
nginx -c /usr/local/nginx/conf/nginx.conf
Click Begin Push Stream on OBS.
Input the following URL to view the live video.
http://domain_name:8080/hlslive/test/test.m3u8
I'm using avconv (ffmpeg) and nginx to stream frames from a camera over HLS and RTMP. Since my phone doesn't support flash it uses HTML5 video tags and HLS in order to stream the video. One feature that I'm trying to support is to record the live stream and save that to a file. However, I am unable to record the stream due to a cross-domain issue.
The live stream is coming from my machine on port 8080 (I'm referencing it using my internal IP, 10.150.x.x:8080/hls/mystream.m3u8) and the server is run on my machine through port 8000 (also referenced through internal IP). Because they are on different ports it is still viewed as cross domain.
In my nginx.conf I have added Access-Control-Allow-Origin: *
and I've also tried adding Access-Control-Allow-Methods GET, PUT, POST, DELETE, OPTIONS
and Access-Control-Allow-Headers Content-Type, Authorization, X-Requested-With
When I examine the headers using curl -I http://10.150.x.x:8080/hls/mystream.m3u8 and through firefox and chrome from my desktop I can see the appropriate headers. But when I look at the headers using the chrome dev tools for my phone I get "CAUTION: Provisional headers shown."
I attempt to capture the frames using canvas.toDataURL() and it is this function that is giving the security error.
Why is it that even though I have Access-Control-Allow-Origin: * in my nginx.conf I still get a cross domain issue?
nginx.conf:
#user nobody;
worker_processes 1;
error_log logs/error.log debug;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 8080;
server_name 10.150.x.x;
#server_name bsid.ca;
add_header 'Access-Control-Allow-Origin' "*";
#add_header 'Access-Control-Allow-Methods' "GET, PUT, POST, DELETE, OPTIONS";
#add_header 'Access-Control-Allow-Headers' "Content-Type, Authorization, X-Requested-With";
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /path/to/nginxVideo;
}
# sample handlers
#location /on_play {
# if ($arg_pageUrl ~* 127.0.0.1) {
# return 201;
# }
# return 202;
#}
#location /on_publish {
# return 201;
#}
#location /vod {
# alias /var/myvideos;
#}
# rtmp stat
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;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
rtmp {
server {
listen 1935;
ping 30s;
notify_method get;
application myapp {
live on;
# sample play/publish handlers
#on_play http://127.0.0.1:8080/on_play;
#on_publish http://127.0.0.1:8080/on_publish;
# sample recorder
#recorder rec1 {
# record all;
# record_interval 30s;
# record_path /tmp;
# record_unique on;
#}
# sample HLS
hls on;
hls_path /home/richard/Media/nginxVideo/hls;
hls_base_url http://10.150.x.x:8080/hls/;
hls_sync 2ms;
}
# Video on demand
#application vod {
# play /var/Videos;
#}
# Video on demand over HTTP
#application vod_http {
# play http://127.0.0.1:8080/vod/;
#}
}
}
Full error:
Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
UPDATE
After a lengthy discussion with Ray Nicholus it was determined that the issue was that I was setting the crossorigin attribute on my video element after the stream had begun. By setting it earlier I was able to access the frames without the need of a proxy.
Dev tools will not reveal most specifics about the request if it believes the response has not properly acknowledged the cross-origin request. All I can think of is that you are setting the crossorigin attribute after the bytes have started to stream in (at which point the video is already tainted), either that or your server is not properly acknowledging the request. If the request is lacking an Origin header, the former is likely the case.