Best practices for loading videos on a web page? - javascript

Would like to understand how AirBnb is able to load a 20MB background video file so fast on their homepage. After inspecting their homepage on WebPageTest, I noticed that the video did not show up in any of the downloaded resources, which made it score so high. When I've tried this tactic, via loading the video asynchronously via AJAX, the video still shows up on WebPageTest as a downloaded resource, but just after the DOM loads. So I'm really not sure how AirBnb is able to make this work. Does anyone have an idea?

AirBnb isn't doing anything special here. They're just starting playback of media using progressive download, which just means playback starts while the video is still downloading.
On their CDN, they have uploaded some fairly large MP4 files with two important characteristics:
The indexing information (MOOV atom) has been moved to the beginning of the MP4 file
The video is encoded in a format and codec that your browser supports
Because of these characteristics, all the site has to do is tell your browser to begin playing the source URL, and it will do the right thing: it makes a web request to the CDN and begins downloading the file. As soon as enough data has been transferred to start playback, it does so.
Finally, I can't say for sure why WebPageTest doesn't show you the video MP4s that are driving the video, but they are certainly there, and the URLs look like https://a0.muscache.com/airbnb/static/Xxxxx-X1-1.mp4. I suspect they're looking at your User Agent to decide which file to send you, and are not sending any video at all to bots like Google and WebPageTest.
You're not getting the real story through WebPageTest. Instead of relying on a third party to evaluate the page in their environment, you should watch the traffic you are actually being sent using Fiddler or the Network tab on Chrome Developer Tools.

Related

Prevent downloading videos in temp folder while watching videos in web browser

I created a web application using Java and html5. I have uploaded few videos in tomcat server war folder.Say my war file name is "web". Then my videos are inside /opt/Apache/WebApps/web/videos/sample.mp4".
I am using html5 video tag for playing the videos.Most of the video size is more than 100mb.
My video tag is like
<video src="/videos/sample.mp4"></video>
Whenever I played the video, automatically download inside our temp folder of my c drive. My system RAM size is 128mb. So when I watched two or more videos, suddenly PC gets struck due to less memory.
How to avoid this using jQuery, Java servlet,jsp
Base on my experience, you can't. But try to make it harder to download.
Browsers make grabbing too easy
Because that's what browsers were designed to do: Serve content - which means give the content to the user. To show you how easy it is, here's how I usually grab videos on virtually any video streaming site:
Prepare the network tab of your preferred browser debugger and let the video load. Then look for it in the loaded resources. Videos are usually streamed in .flv or .mp4, and audio in .mp3. When you spot the url, open a new tab/window and open the link there. The browser will then download the file.
Making it harder
Here are methods on making a grabber's life harder. Like I said earlier, these are not fool-proof methods, but can at least ward off skiddies.
Video to Canvas technique
Recently I came across this article from HTML5Doctor while researching motion detection in JS. This involves streaming your video via a , then with some JS, literally copy the video to a . Here's an example where the video is up front, while the canvas at the back get's fed with data from that same video.
Essentially, what you do is:
Predefine on the HTML or dynamically insert a to the DOM. This is the "player" that the user sees.
Dynamically create a video tag via JS, append it to the DOM hidden and give it a url to stream. This will be the video source for the canvas.
Then with JS, you periodically grab data from the you just created and draw it to the . With this step, the video gets fed to the canvas.
That's the very basic of the entire routine. Since your player is now the canvas and the true video hidden, you can try right-clicking all you want and save. Since the canvas acts like an image on the page, you can only save a shot of a frame that was displayed on the canvas. As for controls, JS has an API for controlling so you can create custom buttons and sliders.
However, if they know you are doing this, they will find your hidden video element, and you are screwed. This leads us to the next method that complements this front-end only technique, with aid from the server side.
Temporary resource urls
One thing you can do to prevent this method is to prevent the link from being reusable. Make the link disposable, temporary, one-time use only. Once the player loads using the disposable url, dispose of it. Make it unusable.
Similar to CSRF prevention, when a browser requests a page with your video, have it generate a random token and store it in some storage on the server side for later reference. At the same time, append it to the url of your video, something like this:
//we load some video with id 1234324 from your site using this url
//and the token generated on page load is appended as sid
http://yoursite.com/media.php?video_id=1234324&sid=a0s9d8a98a0d98asd09809wq0e9
Now when your player loads the video, it will use this url that carries the token. Have the server validate the token.
If it's good, stream the video and destroy the token from the server to avoid reuse. This essentially makes the url "one time use only". If an invalid token is used, return the appropriate headers as the response, like a 403 perhaps.
To add a bit more security, impose an expiry of the url by storing it's timestamp along with the token. Then compare the request timestamp with the stored timestamp if it's still within the "use window". Make this "use window" short enough to be used by the player on the page, but not long enough for a skiddie to grab that url and paste it into another tab/window/downloader.

How to disable video/audio downloading in web pages?

I have a website that I put my videos/audios on it.
I use HTML5 and tag to show videos.
But videos/audios can be downloaded if client opens view source page and then copy the file address.
How can I disable downloading these files, I just want client to see videos/hear audios in the web page.
Many online video/audio services like Youtube disabled downloading videos by this way. How they did that? What is a working way to disable, or at least make this progress much harder?
Youtube encodes their video into the MPEG-DASH format, which plays back through byte streams via the browser's implementation of the Media Source Extensions API. See See more on Wikipedia.
You can do the same by encoding your video into MPEG-DASH files, then playing it back in your code through a library like dash.js. Watch how the dash.js player works live by checking out the DASH Reference Client.
I've encoded MPEG-DASH video using Sorenson Squeeze, but there are other encoders you could use.
And just to clarify... this will make downloading more difficult... but will NOT provide a real DRM solution. For that you need to check out EME.
MPEG-DASH seems like a nice solution but is definitely not perfect. There are many ways to bypass this and still being able to download the video. On the other hand putting a lot of effort in protection might not be worth it since people can always make screen recordings etc.
But if you still want to go for a more secure option you can try using
Encrypted Media Extensions i.e. with Amazon s3 cloud.

prevent html5 video from being downloaded through inspect element

We have a module in our project where there is an option of uploading mp4 videos , we are using html5 video tag player for playing the videos.
Problem we are facing is the privacy of the videos.At the time its very easy for the user to download our file either through right click save as video or by taking the url from the src of the video tag by inspect element.
To do so I have studied a lot, and got the idea about the blob url through youtube videos which are not accesible through anyway.
I tried to study about the blob-url, created one for my video url but still they are accessible and can be easily downloaded. Like youtube blob-url its not working.
I also studied this ques question first answer, through which i got the idea about youtube mechanism of buffering video and how the blob url shown in inspect element for youtube is a spoof.
Most importantly I want to know how can we spoof our website url so that no one can download it through inspect element. Is it possible for us to do so and how? Any link related to this please share with me.I have tried to study a lot but still missing something.
What mechanism actually youtube follow for creating blob url and to save its videos?
As your video has to arrive at the users device there is effectively no way you can stop a user intercepting and storing the file if they want to.
The typical solution to this problem is to encrypt the file and only share the key to the encrypted video with the people you want to view it. A 'bad' user can still download the video file but will not be able to play it back without the correct key.
How you get the key to the users can be very simple (you tell them it directly via some separate communication channel, like email) or more sophisticated using some sort of DRM approach.
DRM is controversial (see Firefox discussion at link below) but it is being baked into the standards with HTML5 EME (Encrypted Meida Extensions) so is becoming more mainstream. EME essentially allow a browser request a trusted (by the video producer) element in the browser/device to decode and play an encrypted video. See a good overview of EME at the second link below.
https://blog.mozilla.org/blog/2015/05/12/update-on-digital-rights-management-and-firefox/
http://www.html5rocks.com/en/tutorials/eme/basics/

Storing large file in chromecast memory

The problem
I made a receiver application that is just showing a video in loop on the Chromecast. The problem is that the Chromecast doesn't seems to be caching the video in it's cache. So the video keeps getting downloaded every time it finishes a loop and it takes a lot of bandwidth. The video will be hosted on external server so the Chromecast will have to download it from internet every time (I cannot change that spec).
Just for you know, when debugging the receiver application on a desktop chrome application, the video is cached by the browser, so the problem doesn't seems to come from http responses for the caching behaviour.
A solution I explored
I tried to download the video file in ajax and play it. The problem is the Chromecast seems to crash when my Javascript tries to read the responseText field of the xhr when the result has more than 28MB (I tried with a 50MB file (it crashed) and a 28MB file (it didn't crash), the limit could actually be 32MB).
EDIT:
I also tried this example and it also makes the chromecast crash...
The question
Is it possible to cache a video of 50-100MB on the Chromecast and prevent it from downloading it every time or is there a memory trick I could be doing to store that video in the Chromecast memory? Loading the video once per application use would be my target result to reduce bandwidth usage.
I'm a bit unsure about this answer because I find it a bit too obvious. But I'll give it a try:
You said you had no trouble with a setup where you download 28MB via ajax. Why don't you cut it down even further? You could for example go with 4MB. I'm suggesting this because it may alleviate problems arising from "bursts" of computation as you for example mentioned with reading the responseText field of the xhr object.
After you decided on an appropriate chunk size you could use https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-p5-range-22#section-3 to download your video in parts and then concatenate it in javascript according to your needs. See also Download file in chunks in Chrome Javascript API?
If you have access to the server you could also split the file on the server side such that you can send requests from the client like so:
example.com/movies/my_movie.mp4?chunk=1
Try using an Application Cache manifest file to ensure that the file is only downloaded once:
<html manifest="some.manifest">
where some.manifest has the contents:
CACHE MANIFEST
# version 1.0
the_video_to_cache.webm
This will ensure that future HTTP requests for the resource will not cause download. The video will only re-download when the manifest file changes (so you can change the #-prefixed comment string to cause a re-download). Note that the new version will be shown on first page load after the download completes. After an update, the user will see an out-of-date video one time (while the new version downloads) and then see the new version on the next visit.
Note that this may not work if your video is larger that the permitted size of the app cache.
I'm don't have chromecast, and not sure. Is it possible to use experimental features, like Quota Management API? This API, could add some extra memory for you stored data, may be you should try to use it.

How to download video in background HTML5 / JS

Is there a way to make a video download in the background (Possible on a different thread?) than I get my images and do webrequests?
Situation:
I show a video, video plays fine.
But, once I start getting 2 images at the same time from that server, the page won't response and will wait for my video to have finished loading, then it loads the images within a few seconds. (about 100kb per image).
If I try to open any other page on the same browser and the crashed page's server it won't load untill the crashed page is done loading, however any other site(For example google) will just load fine.
So is there a way to make the browser not want to download full video, or maybe just give priority to images?
This sounds like the server throttling your requests, as everything apart from scripts always load asynchronously in a browser.
It might be that you are only allowed so much bandwidth per second from the server - or so many connections - and that could be the reason why the server won't respond until your first request has finished.
Check your server configuration and perhaps have a play with it to exclude this possibility.
Maybe you can try a worker, it provides a way to execute background scripts (you will have to split your video and images in separate files), as you can see in the Use Cases it refers to "Prefetching and/or caching data for later use" as a possible scenario. Hope it helps.
More info here:
http://www.html5rocks.com/en/tutorials/workers/basics/#toc-examples

Categories