The document discusses various JavaScript interfaces for working with media like audio and video elements, exploring methods for controlling playback, retrieving metadata, and building a custom media player. It also covers APIs for geolocation, local storage, and accessing location-based data through Yahoo's YQL service to determine place names from latitude and longitude coordinates.
3. JavaScript Interfaces
Working with media
<audio controls="controls" autobuffer="autobuffer"
preload="auto">
<source src="my.mp3"/>
<source src="my.oga"/>
<ul>
<li><a href="my.mp3">Download as audio/mp3</a></li>
<li><a href="my.oga">Download as audio/ogg</a></li>
</ul>
</audio>
4. JavaScript Interfaces
Roll your own player
$('audio').each(function(){
var audio = this,
$button = $('<button>Play</button>')
.click(function(){
audio.play();
});
$(this)
.removeAttr('controls')
.after($button);
});
Using jQuery
5. JavaScript Interfaces
Roll your own
currentSrc
Returns the address of the current media resource (or empty).
networkState
Returns a number (0-3) to indicate the network activity of the element:
0 = not initialized
1 = initialized, but idle
2 = actively downloading
3 = no resource
buffered
Returns a TimeRange for what’s been buffered by the browser.
duration
Returns the length (in seconds) of the media object, NaN when resource isn’t found.
currentTime
Current playback position (in seconds). Can be set to seek a time.
initialTime
Returns the initial (possibly sought) playback position when the resource was loaded.
6. JavaScript Interfaces
Roll your own
readyState
A numeric value (0-4) representing the current state of the element:
0 = no information available
1 = metadata received
2 = have current data, but not enough to do anything yet
3 = have a little future data, but not a lot
4 = have enough data to advance without risking a stop (at the default playback rate).
paused
Returns true or false based on the state of the media.
ended
Returns true if playback has reached the end of the media resource.
playbackRate
Returns the current playback rate (usually 1.0), but is also settable.
defaultPlaybackRate
Returns the default playback rate (usually 1.0), but is also settable.
7. JavaScript Interfaces
Roll your own
played
Returns a TimeRange object that tells how much of the media resource has been played.
load()
Triggers the reset and restart of a media resource.
play()
Plays the audio.
pause()
Pauses the audio.
canPlayType( type )
Returns “probably,” “maybe” or empty (for no) based on how confident the browser is.
seeking
Returns true if the user agent is currently seeking.
seekable
Returns a TimeRange object that represents the “seekable” area of the media resource.
8. JavaScript Interfaces
Test for native support
var
audio = document.createElement('audio'),
test = { mp3: 'audio/mpeg',
oga: 'audio/ogg; codecs="vorbis"' },
supported = [];
if ( audio.canPlayType &&
typeof audio.canPlayType == 'function' )
{
for ( format in test )
{
if ( "" != audio.canPlayType( test[format] ) )
{
supported.push(format);
}
}
}
11. JavaScript Interfaces
Something for later…
if ( window.localStorage )
{
var cache = window.localStorage;
cache.setItem( 'test', 'I am storing nuts for the winter.' );
}
13. JavaScript Interfaces
Something for later…
if ( window.localStorage )
{
var cache = window.localStorage;
console.log( cache.getItem('test') );
}
14. JavaScript Interfaces
Something for later…
if ( window.localStorage )
{
var cache = window.localStorage;
console.log( cache.getItem('test') );
cache.clear();
console.log( cache.getItem('test') );
}
15. JavaScript Interfaces
Something for later…
length
The number of items stored.
key( n )
Returns the name of the nth key (or null).
getItem( key )
Returns the value for the given key (or null).
setItem( key, value )
Stores a value for a given key.
16. JavaScript Interfaces
Local Storage…
…is restricted by domain
…persists until deleted
(programmatically or by the user)
…is limited in size (usually 5MB)
…is (currently) limited to strings
20. JavaScript Interfaces
Local Storage…
…is restricted by domain
…persists until deleted
(programmatically or by the user)
…is limited in size (usually 5MB)
…is (currently) limited to strings
…mutable
22. JavaScript Interfaces
Play nicely in the sandbox
// create a Squirrel instance with your unique key
var $S = new Squirrel( 'scale-song' );
// write a value to the cache
$S.write( 'doe', 'ray' );
// read it back
$S.read( 'doe' ); // 'ray'
// write a value to a sub-cache
$S.write( 'song', 'doe', 'a dear, a female dear' );
// read back the original value
$S.read( 'doe' ); // 'ray'
// read back the sub-cached value
$S.read( 'song', 'doe' ); // 'a dear, a female dear'
Using Squirrel.js (http://github.com/easy-designs/Squirrel.js)
23. JavaScript Interfaces
Play nicely in the sandbox
// removing a single property from the sub-cache
$S.remove( 'song', 'doe' );
// try to read the sub-cached value
$S.read( 'song', 'doe' ); // null
// read the root value
$S.read( 'doe' ); // 'ray'
Using Squirrel.js (http://github.com/easy-designs/Squirrel.js)
24. JavaScript Interfaces
Play nicely in the sandbox
// add some more content to the sub-cache
$S.write( 'song', 'doe', 'a dear, a female dear' );
$S.write( 'song', 'ray', 'a drop of golden sun' );
// clear the whole sub-cache
$S.clear( 'song' );
// check that it's been cleared
$S.read( 'song', 'doe' ); // null
$S.read( 'song', 'ray' ); // null
// check that the root value's still intact
$S.read( 'doe' ); // 'ray'
Using Squirrel.js (http://github.com/easy-designs/Squirrel.js)
25. JavaScript Interfaces
Play nicely in the sandbox
// remove a property form the main cache
$S.remove( 'doe' );
// check it's value
$S.read( 'doe' ); // null
// write a bit more data in the root and in a sub-cache
$S.write( 'doe', 'ray' );
$S.write( 'song', 'doe', 'a dear, a female dear' );
$S.write( 'song', 'ray', 'a drop of golden sun' );
// clear the whole cache
$S.clear();
// check it's all gone
$S.read( 'song', 'doe' ); // null
$S.read( 'song', 'ray' ); // null
$S.read( 'doe' ); // null
Using Squirrel.js (http://github.com/easy-designs/Squirrel.js)
33. JavaScript Interfaces
Comparison: initialize
var db = window.openDatabase( var request = window.indexedDB.open(
"CandyDB", "", "CandyDB", "My candy store database"
"My candy store database", 1024 );
);
indexedDB
Web Database
37. JavaScript Interfaces
Comparison: create The Data
var kids = [ { name: "Anna" }, { name: "Betty" }, { name: "Christine" } ];
var db = window.openDatabase( var request = window.indexedDB.open(
"CandyDB", "1", "CandyDB", "My candy store database"
"My candy store database", 1024); );
db.transaction( function(tx){ request.onsuccess = function(e) {
var i=0, len=kids.length; var objectStore = e.result
while ( i < len ) .objectStore("kids"),
{ var i=0, len=kids.length;
var kid = kids[i++]; while ( i < len ) {
tx.executeSql( var kid = kids[i++];
"INSERT INTO kids (name) “ + objectStore.add(kid)
“VALUES (:name);", [kid], .onsuccess = function(e) {
function(tx, results) { console.log(
console.log( "Saved record for " +
"Saved record for " + kid.name + " with id " +
kid.name + " with id " + e.result );
results.insertId ); };
}); }
} };
});
indexedDB
Web Database
38. JavaScript Interfaces
Comparison: simple read
db.readTransaction( function(tx) { request.onsuccess = function(e) {
// Enumerate the entire table. // Enumerate the entire object store.
tx.executeSql( request = e.result
"SELECT * FROM kids", .objectStore("kids")
function( tx, results ) { .openCursor();
var rows = results.rows, request.onsuccess = function(event) {
i=0, len=rows.length, item; var cursor = event.result;
while ( i < len ) { // If cursor is null … done
item = rows.item(i++); if (!cursor) { return; }
console.log( item.name ); console.log( cursor.value.name );
} cursor.continue();
} };
}); };
});
indexedDB
Web Database
39. JavaScript Interfaces
Comparison: joined read Web Database
db.readTransaction(function(tx) {
tx.executeSql(
"SELECT name, COUNT(candySales.kidId) " +
"FROM kids " +
"LEFT JOIN candySales ON kids.id = candySales.kidId " +
"GROUP BY kids.id;",
function(tx, results) {
var rows = results.rows, i=0, len=rows.length;
while ( i<len ) {
var item = rows.item(i++);
console.log( item.name + "bought " + item.count + "pieces" );
}
});
});
40. JavaScript Interfaces
Comparison: joined read indexedDB
var candyEaters = [];
request.onsuccess = function(event) {
var db = event.result,
transaction = db.transaction(["kids", "candySales"]);
transaction.oncomplete = function(){ console.log(candyEaters); },
kidCursor, saleCursor, salesLoaded=false, count;
var kidsStore = transaction.objectStore("kids");
kidsStore.openCursor().onsuccess = function(event) {
kidCursor = event.result;
count = 0;
attemptWalk();
}
var salesStore = transaction.objectStore("candySales");
var kidIndex = salesStore.index("kidId");
kidIndex.openObjectCursor().onsuccess = function(event) {
saleCursor = event.result;
salesLoaded = true;
attemptWalk();
}
//…
41. JavaScript Interfaces
Comparison: joined read indexedDB
// …
function attemptWalk() {
if (!kidCursor || !salesLoaded) return;
if ( saleCursor && kidCursor.value.id == saleCursor.kidId )
{
count++;
saleCursor.continue();
}
else
{
candyEaters.push({ name: kidCursor.value.name, count: count });
kidCursor.continue();
}
}
} // end request.onsuccess
42. JavaScript Interfaces
In the wikiHow app…
Categories
A NY
HA
VE
Badges
E M MA
H AV NY
Articles Questions Quiz
Results
Content
Content
Content User Triggered
Preloaded
45. JavaScript Interfaces
What’s in a name?
function getPlaceFromFlickr( lat, lon, callback )
{
// the YQL statement
var yql = 'select * from flickr.places where lat=' +
lat + ' and lon=' + lon;
// assembling the YQL webservice API
var url = 'http://query.yahooapis.com/v1/public/yql?q=' +
encodeURIComponent(yql) +
'&format=json&diagnostics=false&callback=' + callback;
// create a new script node and add it to the document
var s = document.createElement('script');
s.setAttribute( 'src', url );
document.getElementsByTagName('head')[0].appendChild(s);
};
// …
46. JavaScript Interfaces
What’s in a name?
// callback in case there is a place found
function output(o){
if ( typeof(o.query.results.places.place) != 'undefined' )
{
console.log( o.query.results.places.place.name );
}
}
47. JavaScript Interfaces
What’s in a name?
if ( navigator.geolocation )
{
navigator.geolocation.getCurrentPosition(
function(position){
getPlaceFromFlickr(
position.coords.latitude,
position.coords.longitude,
'output'
);
},
function(error){
alert('ouch');
}
);
}
48. JavaScript Interfaces
Bonus: Offline Cache
CACHE MANIFEST
# Cache manifest version 1.0
# Change the version number to trigger an update
index.php
c/main.css
j/main.js
i/logo.png
NETWORK:
live-feed.php
rss.json
cache.manifest served with MIME of text/cache-manifest
<html manifest="cache.manifest">
navigator.onLine // true or false
49. JavaScript Interfaces
Slides available at
http://slideshare.net/AaronGustafson
This presentation is licensed under
Creative Commons
Attribution-Noncommercial-Share Alike 3.0
flickr Photo Credits
“HTML5 logo in Braille” by Ted Drake
“Dual Samsung Monitors” by steve-uk
“Statue of Liberty” by gadl
“Lego” by DavePress
“iFlickr touch screen” by exfordy
“Green Plant” by kevin1024