6

i have this simple script that i found in the webRTC doc i triet to run it but it seems i'm missing something

const leftVideo = document.getElementById('leftVideo');
const rightVideo = document.getElementById('rightVideo');

leftVideo.addEventListener('canplay', () => {
const stream = leftVideo.captureStream();
rightVideo.srcObject = stream;
});

i get this error on stream capture when i inspect it Uncaught DOMException: Failed to execute 'captureStream' on 'HTMLMediaElement': Cannot capture from element with cross-origin data at HTMLVideoElement.leftVideo.addEventListener this my index.html

<video id="leftVideo" playsinline controls loop muted>
    <source src="test1.webm" type="video/webm"/>
    <p>This browser does not support the video element.</p>
</video>

<video id="rightVideo" playsinline autoplay></video>
Walid Ammar
  • 4,038
  • 3
  • 25
  • 48
moxched
  • 163
  • 2
  • 10
  • You need to learn about CORS. If you do not control the origin of the video then there is nothing you can do about that error. – mpm Sep 14 '18 at 00:18
  • 2
    Are you using file system `file://`, a local server `localhost` or a local IP? The file system will be blocked with CORS. – rafaelcastrocouto Sep 14 '18 at 00:28
  • for the moment just a file system , any trick to bypass it ? and is it only blocked in the file system or the other domains too ? – moxched Sep 14 '18 at 00:36

1 Answers1

16
  1. Either you can set crossOrigin as shown in this link Example:

<video crossOrigin="anonymous" src="https://cdn.myapp.com:81/video.mp4"></video>

you want to make sure link is using https

Reference: https://stackoverflow.com/a/35245146/8689969

  1. or you can create a readable stream using fetch, follow up doc on this link: https://developer.mozilla.org/en-US/docs/Web/API/ReadableStream which gives you blob url that should help resolving that issue: Example:

// Fetch the original image
    fetch(video.filePath,  {
      mode: 'cors',
      headers: {
        'Access-Control-Allow-Origin':'*'
      }
    })
    // Retrieve its body as ReadableStream
    .then(response => {
      const reader = response.body.getReader();

      return new ReadableStream({
        start(controller) {
          return pump();
          function pump() {
            return reader.read().then(({ done, value }) => {
              // When no more data needs to be consumed, close the stream
              if (done) {
                  controller.close();
                  return;
              }
              // Enqueue the next data chunk into our target stream
              controller.enqueue(value);
              return pump();
            });
          }
        }  
      })
    })
    .then(stream => new Response(stream))
    .then(response => response.blob())
    .then(blob => URL.createObjectURL(blob))
    .then((url) => {
      // gives the blob url which solves cors error in reading stream(using captureStream() func)

      console.log(url);

      // do your thing
    })
    .catch(err => console.error(err));
  • Good luck...
Ramu N
  • 391
  • 4
  • 5
  • @Gsk you are right, edited with code-snippet exampels – Ramu N Jul 18 '19 at 19:00
  • 1
    The fetch part may be simplified. No need for a stream reader. Something like this: fetch(myRequest) .then(response => response.blob()) .then(function(myBlob) { var objectURL = URL.createObjectURL(myBlob); myImage.src = objectURL; }); ``` – Alan Nov 11 '20 at 22:48
  • Thank you! @RamuN ! I added CORS policy to my source server (s3, cloudfront) but it still occur `cross-origin data` error. After adding `crossOrigin="anonymous"` on a video tag, it works! Thanks! – hynuah_iia Dec 07 '21 at 07:29