API Documentation for: 1.0.0
Show:

File:HTMLAudioTagPool.js

/*
 * HTMLAudioTagPool
 * Visit http://createjs.com/ for documentation, updates and examples.
 *
 *
 * Copyright (c) 2012 gskinner.com, inc.
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 * @module SoundJS
 */

// namespace:
this.createjs = this.createjs || {};

(function () {
	"use strict";

	/**
	 * HTMLAudioTagPool is an object pool for HTMLAudio tag instances.
	 * @class HTMLAudioTagPool
	 * @param {String} src The source of the channel.
	 * @protected
	 */
	function HTMLAudioTagPool() {
			throw "HTMLAudioTagPool cannot be instantiated";
	}

	var s = HTMLAudioTagPool;

// Static Properties
	/**
	 * A hash lookup of each base audio tag, indexed by the audio source.
	 * @property _tags
	 * @type {{}}
	 * @static
	 * @private
	 */
	s._tags = {};

	/**
	 * An object pool for html audio tags
	 * @property _tagPool
	 * @type {TagPool}
	 * @static
	 * @private
	 */
	s._tagPool = new TagPool();

	/**
	 * A hash lookup of if a base audio tag is available, indexed by the audio source
	 * @property _tagsUsed
	 * @type {{}}
	 * @private
	 * @static
	 */
	s._tagUsed = {};

// Static Methods
	/**
	  * Get an audio tag with the given source.
	  * @method get
	  * @param {String} src The source file used by the audio tag.
	  * @static
	  */
	 s.get = function (src) {
		var t = s._tags[src];
		if (t == null) {
			// create new base tag
			t = s._tags[src] = s._tagPool.get();
			t.src = src;
		} else {
			// get base or pool
			if (s._tagUsed[src]) {
				t = s._tagPool.get();
				t.src = src;
			} else {
				s._tagUsed[src] = true;
			}
		}
		return t;
	 };

	 /**
	  * Return an audio tag to the pool.
	  * @method set
	  * @param {String} src The source file used by the audio tag.
	  * @param {HTMLElement} tag Audio tag to set.
	  * @static
	  */
	 s.set = function (src, tag) {
		 // check if this is base, if yes set boolean if not return to pool
		 if(tag == s._tags[src]) {
			 s._tagUsed[src] = false;
		 } else {
			 s._tagPool.set(tag);
		 }
	 };

	/**
	 * Delete stored tag reference and return them to pool. Note that if the tag reference does not exist, this will fail.
	 * @method remove
	 * @param {String} src The source for the tag
	 * @return {Boolean} If the TagPool was deleted.
	 * @static
	 */
	s.remove = function (src) {
		var tag = s._tags[src];
		if (tag == null) {return false;}
		s._tagPool.set(tag);
		delete(s._tags[src]);
		delete(s._tagUsed[src]);
		return true;
	};

	/**
	 * Gets the duration of the src audio in milliseconds
	 * @method getDuration
	 * @param {String} src The source file used by the audio tag.
	 * @return {Number} Duration of src in milliseconds
	 * @static
	 */
	s.getDuration= function (src) {
		var t = s._tags[src];
		if (t == null || !t.duration) {return 0;}	// OJR duration is NaN if loading has not completed
		return t.duration * 1000;
	};

	createjs.HTMLAudioTagPool = HTMLAudioTagPool;


// ************************************************************************************************************
	/**
	 * The TagPool is an object pool for HTMLAudio tag instances.
	 * #class TagPool
	 * @param {String} src The source of the channel.
	 * @protected
	 */
	function TagPool(src) {

// Public Properties
		/**
		 * A list of all available tags in the pool.
		 * #property tags
		 * @type {Array}
		 * @protected
		 */
		this._tags = [];
	};

	var p = TagPool.prototype;
	p.constructor = TagPool;


// Public Methods
	/**
	 * Get an HTMLAudioElement for immediate playback. This takes it out of the pool.
	 * #method get
	 * @return {HTMLAudioElement} An HTML audio tag.
	 */
	p.get = function () {
		var tag;
		if (this._tags.length == 0) {
			tag = this._createTag();
		} else {
			tag = this._tags.pop();
		}
		if (tag.parentNode == null) {document.body.appendChild(tag);}
		return tag;
	};

	/**
	 * Put an HTMLAudioElement back in the pool for use.
	 * #method set
	 * @param {HTMLAudioElement} tag HTML audio tag
	 */
	p.set = function (tag) {
		// OJR this first step seems unnecessary
		var index = createjs.indexOf(this._tags, tag);
		if (index == -1) {
			this._tags.src = null;
			this._tags.push(tag);
		}
	};

	p.toString = function () {
		return "[TagPool]";
	};


// Private Methods
	/**
	 * Create an HTML audio tag.
	 * #method _createTag
	 * @param {String} src The source file to set for the audio tag.
	 * @return {HTMLElement} Returns an HTML audio tag.
	 * @protected
	 */
	p._createTag = function () {
		var tag = document.createElement("audio");
		tag.autoplay = false;
		tag.preload = "none";
		//LM: Firefox fails when this the preload="none" for other tags, but it needs to be "none" to ensure PreloadJS works.
		return tag;
	};

}());