hacks.mozilla.org

Daily Archive for June 9th, 2009

add some ambiance to your videos

Note: this post was originally posted to the silverorange labs blog and was written by Mike Gauthier. Mike and other people at silverorange put this demo together for the 35 days project and we thank them.

Also note that the demo below is extremely CPU-intensive. If you’re interested in the effect and you don’t have a really fast CPU you can just watch a screencast of the effect.

Last note: This demo requires Firefox 3.5 Beta99 or later.. If you have Beta 4 installed you should be able to use Help -> Check for updates… to get to the latest beta. Beta 4 included a bug where video data couldn’t be copied to the canvas.

Our work with Mozilla led us to do some experiments on what can be done with the new HTML5 functionality in Firefox 3.5. With <canvas> and the new HTML5 <video> element, we created a demo that pulls color information out of a live playing video and uses it to style a border around the video. The result is not unlike the tackiest of back-lit LCD tvs.

How It Works

The color calculation is done by drawing video frames to a HTML5 canvas element and then computing the average color of the canvas. To make computing the average color faster, the video frame is resampled onto a smaller canvas (this demo uses 50×50). Color accuracy can be improved at the cost of speed by using a larger canvas. Pushing video frames to the canvas is done as follows:

var canvas = document.getElementById('canvas');
var video = document.getElementById('video');
var context = canvas.getContext('2d');
 
// push frame to canvas
context.drawImage(video, 0, 0, canvas.width, canvas.height);
 
// get image data for color calculation
var data = context.getImageData(0, 0, canvas.width, canvas.height);

The computed color is then changed over time using a YUI animation.

The edges of the video are feathered using an SVG mask. Firefox 3.5 allows SVG masks to be applied to elements using a special CSS+SVG property. First, an SVG mask is defined inline in the document (note: this could also be defined externally). The mask is then applied to the video element using the following CSS rule:

#video {
    mask: url(index.html#m1);
}

There are two of other CSS+SVG properties available in FF3.5: clip-path and filter. To reference SVG styles in CSS use url(filename#element-id) or just url(#element-id) if the SVG is defined in the same file as the CSS.

Finally, the demo uses some new HTML CSS 3.0 features from Firefox 3.5. The box-shadow property, text-shadow property and rgba color model are used:

#main-feature {
    -moz-box-shadow: #000 0px 5px 50px;
}
#description {
    text-shadow: rgba(255, 255, 255, 0.4) 1px 1px 2px;
}

geolocation in Firefox 3.5

This post is from Doug Turner, one of the engineers who is behind the Geolocation support in Firefox 3.5.

Location is all around us. As of this writing, I am in a coffee shop in Toronto, Canada. If I type google into the url bar, it takes me to www.google.ca, the Canadian version of Google, based on my IP address. And when I want to find the closest movie theater to where I am located, I typically just type in my postal code. That information is often stored with the site so that it’s easier to find the movie theater next time. In these two situations, having the web application automatically figure out where I am is much more convenient. In fact, I have no idea what the postal code is for Toronto. I know how to find it, but that is a lot of work to simply tell a web application where I am.

Firefox 3.5 includes a simple JavaScript API that allows you to quickly geo-enable your web application. It allows users to optionally share their location with websites without having to type in a postal code. What follows is a general overview of how to use geolocation in Firefox 3.5, how it works, and examines some of the precautions you should take when using geolocation.

The Basics

Getting the user’s location is very easy:

function showPosition(position) {
    alert(position.coords.latitude + “ “ +
    position.coords.longitude);
}
 
navigator.geolocation.getCurrentPosition(showPosition);

The call to getCurrentPosition gets the users current location and puts it into an alert dialog. Location is expressed in terms of longitude and latitude. Yes, it’s that simple.

When you ask for that information the user will see a notification bar like this:

Their options are to allow or not, and to remember or not.

Handling Errors

It is important to handle two error cases in your code:

First, the user can deny or not respond to the request for location information. The API allows you to set an optional error callback. If the user explicitly cancels the request your error callback will be called with an error code. In the case where the user doesn’t respond, no callback will be fired. To handle that case you should include a timeout parameter to the getCurrentPosition call and you will get an error callback when the timer expires.

navigator.geolocation.getCurrentPosition(successCallback,
                                         errorCallback,
                                         {timeout:30000});

With this code your errorCallback function will be called if the user cancels. It will also be called if 30 seconds pass and the user hasn’t responded.

Second, the accuracy of the user’s location can vary quite a bit over time. This might happen for a few reasons:

  • Different methods for determining a person’s location have different levels of accuracy.
  • The user might choose not to share his or her exact location with you.
  • Many GPS devices have limited accuracy depending on the view of the sky. Over time if your view of the sky gets worse, so can the accuracy.
  • Many GPS devices can take several minutes to go from a very rough location to a very specific location, even with a good view of the sky.

These cases can and will happen, and supporting changes in accuracy is important to provide a good user experience.

If you want to monitor the location as it changes, you can use the watchPosition callback API:

navigator.geolocation.watchPosition(showPosition);

showPosition will be called every time there is a position change.

Note that you can also watch for changes in position by calling getCurrentPosition on a regular basis. But for power savings and performance reasons we suggest that you use watchPosition when you can. Callback APIs generally save power and are only called when required. This will make the browser more responsive, especially on mobile devices.

For more information, please take a look at the API draft specification which has other examples which may be useful.

Under the Hood

There are a few common ways to get location information. The most common are local WiFi networks, IP address information, and attached GPS devices. In Firefox 3.5 we use local WiFi networks and IP address information to try and guess your location.

There are a few companies that drive cars around listening for WiFi access points spots and recording the access point’s signal strength at a specific point on the planet. They then throw all of this collected data into a big database. Then they have algorithms that allow you to ask the question “If I see these access points, where am I?”. This is Firefox 3.5’s primary way of figuring out your location.

But not everyone has a WiFi card. And not every place has been scanned for WiFi. In that case Firefox will use your local IP address to try to figure out your location using a reverse database lookup that roughly maps your IP address to a location. IP derived locations often have much lower accuracy than a WiFi derived location. As an example, here in Toronto, a location from WiFi is accurate to within 150 meters. The same location using just an IP address is about 25 km.

Privacy

Protecting a user’s privacy is very important to Mozilla – it’s part of our core mission. Within the realm of data that people collect online, location can be particularly sensitive. In fact, the EU considers location information personally identifiable information (PII) and must be handled accordingly (Directive 95/46/EC). We believe that users should have strict control over when their data is shared with web sites. This is why Firefox asks before sharing location information with a web site, allows users to easily “forget” all of the places that the user has shared their location with, and surfaces sharing settings in Page Info.

Firefox does what it can to protect our users’ privacy but in addition the W3C Geolocation working group has proposed these privacy considerations for web site developers and operators:

  • Recipients must only request location information when necessary.
  • Recipients must only use the location information for the task for which it was provided to them.
  • Recipients must dispose of location information once that task is completed, unless expressly permitted to retain it by the user.
  • Recipients must also take measures to protect this information against unauthorized access.
  • If location information is stored, users should be allowed to update and delete this information.
  • The recipient of location information must not retransmit the location information without the user’s consent. Care should be taken when retransmitting and use of HTTPS is encouraged.
  • Recipients must clearly and conspicuously disclose the fact that they are collecting location data, the purpose for the collection, how long the data is retained, how the data is secured, how the data is shared if it is shared, how users may access, update and delete the data, and any other choices that users have with respect to the data. This disclosure must include an explanation of any exceptions to the guidelines listed above.

Obviously these are voluntary suggestions, but we hope that it forms a basis for good web site behavior that users will help enforce.

Caveats

We have implemented the first public draft of the Geolocation specification from the W3C . Some minor things may change, but we will encourage the working group to maintain backwards compatibly.

The only issue that we know about that may effect you is the possible renaming of enableHighAccuracy to another name such as useLowPower. Firefox 3.5 includes the enableHighAccuracy call for compatibility reasons, although it doesn’t do anything at the moment. If the call is renamed, we are very likely to include both versions for compatibility reasons.

Conclusion

Firefox 3.5 represents the first step in support for Geolocation and a large number of other standards that are starting to make their way out of the various working groups. We know that people will love this feature for mapping applications, photo sites and sites like twitter and facebook. What is most interesting to us is knowing that people will find new uses for this that we haven’t even thought of. The web is changing and location information plays a huge role in that. And we’re happy to be a part of it.