Fenrirthviti / stream-site

Rachni - nginx RTMP streaming front end
Other
195 stars 71 forks source link

Non-FLV, Unsupported media type! #37

Closed hieunt79 closed 5 years ago

hieunt79 commented 5 years ago

I publish a video with ffmpeg command:

ffmpeg -re -i clip.mp4 -c:v flv -c:a libmp3lame -ar 44100 -ac 1 -f flv rtmp://localhost/live/username?key=123abc

the stream is on but when i click it, there's nothing, just loading. Chrome log with error:

[TransmuxingController] > Non-FLV, Unsupported media type! flv.js:12424
[IOController] > 5457 bytes unconsumed data remain when flush buffer, dropped flv.js:12468 
Uncaught (in promise) Error: Uncaught, unspecified "error" event. (MediaError)
    at EventEmitter.emit (flv.js:1275)
    at EventEmitter.<anonymous> (flv.js:9804)
    at EventEmitter.emit (flv.js:1297)
    at flv.js:3359
....

I'm pretty new to this. Please help, thank you!

Fenrirthviti commented 5 years ago

Are you certain that you configured the RTMP endpoint with nginx-http-flv directives? Can you provide the configuration for nginx that you are using (redact any sensitive information as necessary).

hieunt79 commented 5 years ago

My nginx.conf:

load_module /etc/nginx/modules/ngx_http_flv_live_module.so;
user nginx; 

worker_processes 1;

pid /var/run/nginx.pid;

env PATH;

events {
    worker_connections 1024;
}

include /etc/nginx/conf.d/*.conf;

I use http for testing. Here is my sites-enable/main.conf:

# This server block is used as a proxy to enable the on_publish directive to access an SSL page, as it doesn't directly support it. 
# If you're not using SSL, you can remove this block and simply point to the streamauth.php on line 27 of /conf.d/rtmp.conf
#server {
#   listen 8080;
#   listen [::]:8080;
#   location /on_publish {
#       #allow 127.0.0.1;
#       allow all;
#       deny all;
#       proxy_pass https://yoursite.com/lib/streamauth.php;
#   }
#}

# This block enforces SSL. If you're not using SSL, you can remove it and change the next server block to listen over port 80.
#server {
#   listen 80 default_server;
#   listen [::]:80 default_server;
#
#   return 301 https://$host$request_uri;
#}

server {
        #listen   443 ssl;
                listen 80;
        #server_name     yoursite.com;

        #ssl    on;
        #ssl_config_goes_here

        add_header Strict-Transport-Security max-age=15768000;
        add_header Cache-Control no-cache;

        # To avoid issues with cross-domain HTTP requests
        add_header Access-Control-Allow-Origin *;

        # Adjust root directory as needed
        root /var/www/html;
        index index.php index.html index.htm;

        location / {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Expose-Headers' 'Content-Length';
            add_header 'Access-Control-Allow-Headers' 'Range';
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';

                # Custom headers and headers various browsers *should* be OK with but aren't
                add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';

                # Tell client that this pre-flight info is valid for 20 days
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                add_header 'Content-Length' 0;

                return 204;
            }

            if ($request_method = 'POST') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
                add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
            }

            if ($request_method = 'GET') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
                add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
            }

            # URL rewrite for pretty urls. **required**
            rewrite /(.*)$ / break;
        }

        # Let's Encrypt location, remove if you don't use
        #location ~ /.well-known {
        #   allow all;
        #}

        # PHP-FPM connector, adjust as needed if you use a different method for PHP
        location ~ \.php$ {
            try_files $uri =404;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }

        # Rewrite for index, popout player, reset form, and REST API
        rewrite /login(.*)$ /login.php last;
        rewrite /popout/(.*)$ /lib/popout.php last;
        rewrite /lostpass(.*)$ /reset.php last;

        location /api {
            # Attempt to remove the access log as the ping function can be kinda chatty.
            # This doesn't work (it still logs), but I'm open to suggestions
            access_log off;
            rewrite /(.*)$ /api/index.php last;
        }

        # Required to exclude our data locations from URL rewrite
        location /css { }
        location /img { }
        location /inc { }
        location /js { }
        location /lib { }
        location /xsl { }
        location /profiles { }

        # Serve recorded sessions, adjust as needed.
        # NOTE: This needs to match the location set for the 'rec' recorder block in rtmp.conf
        location /rec {
            root /var/rachni;
            autoindex on; # directory list accepted, turn off to hide videos from the public
        }

        # RTMP stat
        location /stat {
            access_log off;
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }

        location /stat.xsl {
            access_log off;
            root /var/www/html/xsl/;
        }

        # RTMP control
        location /control {
            allow 127.0.0.1;
            #allow your.ser.ver.ip;
            allow all;
            deny all;
            rtmp_control all;
        }

        # Used to grab current viewer count
        location /nclients {
            satisfy any;
            allow all;
            deny all;
            #proxy_pass https://stream.rachni.com/stat;
            proxy_pass http://127.0.0.1/stat;
            xslt_stylesheet /var/www/html/xsl/nclients.xsl app='$arg_app' name='$arg_name';
            add_header Refresh "3; $request_uri";
        }

        # Custom error page not included
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
}

My rtmp config:

rtmp {
        server {
                listen 1935;
                chunk_size 8192;
                ping 10s;
                ping_timeout 5s;
                notify_method get;
                idle_streams off;

                # Live Stream Application
                application live {
                        live on;
                        wait_video on;
                        meta copy;
                        # NOTE: This line should point to your streamauth.php.
                        # However, if you intend to run the site on SSL, the on_publish directive will NOT work with SSL,
                        # so you will need to use a proxy. See lines 1-12 of /sites-available/main.conf.
                        #on_publish http://proxy.url:8080/on_publish;
                        on_publish http://127.0.0.1/lib/streamauth.php;
                        notify_method get;

                        # executes the rolling screenshots script. There are probably better ways of accomplishing this
                        # (using recorder blocks) but I haven't been able to get them to work reliably.
                        exec_push /etc/nginx/conf.d/rtmp_sslive.sh $name &>/var/log/rachni/exec-$name.log;

                        recorder rec {
                                record all manual;
                                record_suffix .flv;
                                record_unique on;
                                record_path /var/rachni/rec;
                                record_notify on;
                                record_lock on;
                                exec_record_done /etc/nginx/conf.d/rtmp_convert.sh $dirname $basename;
                        }
                        exec_kill_signal TERM;
                }
        }
}

When I publish with ffmpeg, I use VLC to play stream at same time:

rtmp://localhost/live/username

And it's on. So I think RTMP work properly.

I use this script to install stream-site in Ubuntu {18.04, 16.04}

Are there anything else you want to know?

Fenrirthviti commented 5 years ago

You're still only using the RTMP endpoint directives. You'll need to configure it in main.conf to have the additional lines:

location /flv-live {
        flv_live on;
        chunked_transfer_encoding  off;
}

And then update the playback URL to match this new location. Example should be correct in current index.php: https://github.com/Fenrirthviti/stream-site/blob/master/index.php#L299-L306

Standard RTMP playback with the normal flash player is still possible, but I have removed all the references to flash so you would need to add the tech for vjs back in manually. I apologize, I forgot to update the main.conf file to reflect the additional directive needed.

hieunt79 commented 5 years ago

I'm able to watch stream now. Thank you for your great work!