Cross-origin problem loading video with pixi.js - pixi.js

I'm using pixi.js 4.8.8 and getting the cross-origin problem trying to load a webm video.
Chrome says "Access to video at 'http://techslides.com/demos/sample-videos/small.webm' from origin 'http://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource."
I did set videoElement.crossOrigin = 'anonymous' and I pass true as the cross-origin parameter to PIXI.Texture.fromVideo. What am I doing wrong? The webm plays fine if I just paste the URL into Chrome, so it should be accessible.
Here is the relevant code:
// create a video element...
const videoElement = document.createElement('video');
videoElement.crossOrigin = 'anonymous';
videoElement.setAttribute('preload', 'auto');
videoElement.setAttribute('playsinline', '');
videoElement.setAttribute('autoplay', '');
const sourceElement = document.createElement('source');
sourceElement.src = 'http://techslides.com/demos/sample-videos/small.webm';
videoElement.appendChild(sourceElement);
// next create a video texture; args = video, scale mode, cross-origin, autoplay
const videoTexture = PIXI.Texture.fromVideo(videoElement, PIXI.settings.SCALE_MODE, true, false);
// create a sprite to render
const sprite = new PIXI.Sprite(videoTexture);

Related

Why youtube-dl u3m8 to react js get (cors error)

I have a site that shows a live broadcast from youtube
Website built from reactjs and nodejs
In frontend I use video.js and hls.js, to view a live broadcast from M3U8 links, and it works for me with a sample link:
https://multiplatformf.akamaihd.net/i/multi/will/bunny/big_buck_bunny_,640x360_400,640x360_700,640x360_1000,950x540_1500,.f4v.csmil/master.m3u8
In nodejs (backEnd) I use youtube-dl model to create or get an M3U8 link, I send it to react and put it in the src value in video html tag.
react component code:
let videoSrc = data.url;
if (Hls.isSupported()) {
var hls = new Hls();
hls.loadSource(videoSrc);
hls.attachMedia(video);
}
node js code:
let video = youtubedl(`yotubeUrl`, [])
let stream = this;
video.on('info', function (info) {
console.log(info.url)
stream.updateYoutubeStream(info.url) // personal function to update m3u8 url
}).on('error', err => {
console.log(err)
})
But he gives me a cors error
enter image description here
And unable to connect with me
What is the problem? And how can it be fixed?
Thank you very much

Serve clickable download URL in NodeJS

At my endpoint in my NodeJS server, after retrieving an audio file stored as a Buffer in MongoDB, I want to represent it with a URL (much like how you do with URL.createObjectURL(blob) in the frontend on the browser). I then plan to res.render() the URL in HTML through Handlebars on the client, so that the user can click on it to download it:
<a href={{url}}>Click me to download the file!</a>
In the NodeJs server, I have converted the MongoDB Buffer into a JavaScript ArrayBuffer through:
var buffer = Buffer.from(recordingFiles[0].blobFile);
var arrayBuffer = Uint8Array.from(buffer).buffer;
I am unsure where to proceed from here. I seen solutions using fs or res.download(), but they don't seem applicable to my situation. Thanks in advance for any help!
Hopefully this can help.
var blob = new Blob(BUFFER, {type: "audio mime type"});
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
var fileName = reportName;
link.download = fileName;
link.click();
Do you always need to preload the audio file onto the page?
If not, then I would advise you to add a separate endpoint to download the file on demand. The frontend link can send a get request to the endpoint and download the file only if the user clicked it.
Otherwise you'd always be downloading the buffer behind the scenes, even if the user didn't intend to download it. This is especially problematic on slow connections.
Frontend:
<a href={{`${baseUrl}/download/${audioId}`}}>Click me to download the file!</a>
Backend:
const stream = require('stream');
app.get('/download/:audioId', function (request, response) {
// Retrieve the tag from our URL path
const audioId = request.params.audioId;
const fileData; // TODO: Get file buffer from mongo.
const fileContents = Buffer.from(fileData, 'base64');
const readStream = new stream.PassThrough();
readStream.end(fileContents);
response.set('Content-disposition', 'attachment; filename=' + fileName);
response.set('Content-Type', '<your MIME type here>');
readStream.pipe(response);
});
A list of relevant MIME types can be found here.

How do I stream video using Node JS and Use it in my Django Project?

I am working on a Django project related to Video Streaming. All my basic functionalities(like Authentication, login, etc.) are being made using Django. Now I want to Stream Video on my Web App.
I didn't find a solution to Stream my videos directly using Django. So, I decided to stream my video using Node.js and integrate this feature in my Django Project.
Here is the Node-Express Code I used for Streaming my Videos in my frontend.
app.get("/video", function (req, res) {
const range = req.headers.range;
if (!range) {
res.status(400).send("Requires Range header");
}
const videoPath = "mySample.mp4";
const videoSize = fs.statSync("mySample.mp4").size;
const CHUNK_SIZE = 10 ** 6; // 1MB
const start = Number(range.replace(/\D/g, ""));
const end = Math.min(start + CHUNK_SIZE, videoSize - 1);
const contentLength = end - start + 1;
const headers = {
"Content-Range": `bytes ${start}-${end}/${videoSize}`,
"Accept-Ranges": "bytes",
"Content-Length": contentLength,
"Content-Type": "video/mp4",
};
// HTTP Status 206 for Partial Content
res.writeHead(206, headers);
const videoStream = fs.createReadStream(videoPath, { start, end });
videoStream.pipe(res);
});
If someone can tell me how can I integrate this with my Django Project.
Thanks :)
You can simply use the Node API landing point as the source URL in your HTML template.
This is how I displayed the video in my ReactJS app, but it should work in simple HTML page too.
<video controls>
<source
id="hi"
src="http://localhost:5001/****/video" // this url was the node API
/>
</video>
You can stream video using Django channel see the link
https://benwilber.github.io/nginx/rtmp/live/video/streaming/django/2018/10/20/building-a-live-video-streaming-website-part-2-the-applications.html

Generate image using html2canvas not importing images from remote server

I am using html2canvas lib to generate png image from html code. The html combine local images (from images folder) and remote images (from url address - server). The image is looking great but the remote images is missing. any idea how can i fix that issue?
$('#save').click(function () {
var elm = $('.media_container_1200628').get(0);
var width = "1200";
var height = "628";
html2canvas(elm).then(function (canvas) {
Canvas2Image.saveAsPNG(canvas, width, height);
})
});
As explained in the documentation you should allow cross-origin images to taint the canvas.
https://html2canvas.hertzen.com/configuration
In your specific case you can do the following:
$('#save').click(function () {
var elm = $('.media_container_1200628').get(0);
var width = "1200";
var height = "628";
html2canvas(elm, { allowTaint: true }).then(function (canvas) {
Canvas2Image.saveAsPNG(canvas, width, height);
})
});

Detecting socket.io client from image resource request

I'm writing a socket.io based webcam streaming application that should emit a 'streamComplete' event when the feed times out. The problem is, image resources requests don't seem to send the same headers/cookies as a normal AJAX request. This seems to make it impossible for socket.io to identify the request with a socket so that it can later tell the client that the stream is complete.
On the server side, I have a node.js proxy that serves up mjpeg (moving jpeg) images. When a client selects a feed in the app, the 'src' attribute of an img element in the DOM changes to point to the route of the camera feed.
I've looked into the HTML5 CORS enabled image specification which appears to try to address this issue, but as far as I can tell the feature isn't fully implemented in most browsers. If it is, I can't figure out how to allow those requests on the node.js side -- whenever I add crossorigin='use-credentials' to the image, an error saying
"Cross-origin image load denied by Cross-Origin Resource Sharing
policy."
Obviously I should be able to get around that since I control the server side, but the following node header rules doesn't seem to be working even though they seem extremely relaxed:
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With, XMLHttpRequest, X-HTTP-Method-Override, Content-Type");
res.header('Access-Control-Allow-Methods', 'POST, GET, PUT, OPTIONS');
One option that I have considered is tacking on the socketID to the image request and registering the listener on req.io.sockets.sockets[req.body.socketID]. That seems a little hacky though and I'm sure could bring up other concerns like race conditions. Here's the portion of my code where I am trying to accomplish this.
app.use(express.bodyParser());
app.use(express.cookieParser());
app.use(express.session({secret: 'blahblahblah'}));
// Allow all cross origin requests.
app.use(allowCrossOrigin);
app.get('/streams/:cam_id/:framerate', function(req, res,next) {
var camId = req.params.cam_id
, framerate = req.params.framerate
, type = (framerate === 0) ? 'jpeg' : 'mjpeg'
, reqString = 'http://blahblah.com/feeds/'
, proxy;
// Query database for stream info.
var query = new drupalInterface.Query(camId);
// When query comes back build the URL request string and create proxy.
query.on('results:available', function(results) {
var reqArr = [
results.site_name
, results.camera_name
, type
, framerate
];
reqString = reqString + reqArr.join('/') + '?status_frame=true&random=' + Math.random();
// Create new proxy for current client.
req.proxy = new MjpegProxy(reqString);
// Make request to telepresence server.
req.proxy.proxyRequest(req, res, next);
// Forward to express.io route for emitting stream event info to clients.
req.io.route('initializeProxyStream');
});
});
app.io.route('initializeProxyStream', function(req) {
var socket = app.io.sockets.sockets[req.query.socketID];
// If connecting directly to /stream don't try to listen for socket connection.
if(req.io) {
req.proxy.once('streamComplete', function() {
socket.emit('streamComplete');
});
}
});
I'm not sure express.io is even needed for what I am doing, but it seems like it makes sense in this context.
Was I on the right track with the crossorigin attribute? Is there some middleware that I'm missing?

Resources