Question

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.

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top