mp3.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // Copyright 2009 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview provides a reusable mp3 UI component given a mp3 URL.
  16. *
  17. * goog.ui.media.Mp3 is actually a {@link goog.ui.ControlRenderer}, a stateless
  18. * class - that could/should be used as a Singleton with the static method
  19. * {@code goog.ui.media.Mp3.getInstance} -, that knows how to render Mp3s. It is
  20. * designed to be used with a {@link goog.ui.Control}, which will actually
  21. * control the media renderer and provide the {@link goog.ui.Component} base.
  22. * This design guarantees that all different types of medias will behave alike
  23. * but will look different.
  24. *
  25. * goog.ui.media.Mp3 expects mp3 urls on {@code goog.ui.Control.getModel} as
  26. * data models, and render a flash object that will play that URL.
  27. *
  28. * Example of usage:
  29. *
  30. * <pre>
  31. * goog.ui.media.Mp3.newControl('http://hostname/file.mp3').render();
  32. * </pre>
  33. *
  34. * Mp3 medias currently support the following states:
  35. *
  36. * <ul>
  37. * <li> {@link goog.ui.Component.State.DISABLED}: shows 'flash not available'
  38. * <li> {@link goog.ui.Component.State.HOVER}: mouse cursor is over the mp3
  39. * <li> {@link goog.ui.Component.State.SELECTED}: mp3 is playing
  40. * </ul>
  41. *
  42. * Which can be accessed by
  43. *
  44. * <pre>
  45. * mp3.setEnabled(true);
  46. * mp3.setHighlighted(true);
  47. * mp3.setSelected(true);
  48. * </pre>
  49. *
  50. * Requires flash to actually work.
  51. *
  52. */
  53. goog.provide('goog.ui.media.Mp3');
  54. goog.require('goog.string');
  55. goog.require('goog.ui.media.FlashObject');
  56. goog.require('goog.ui.media.Media');
  57. goog.require('goog.ui.media.MediaRenderer');
  58. /**
  59. * Subclasses a goog.ui.media.MediaRenderer to provide a Mp3 specific media
  60. * renderer.
  61. *
  62. * This class knows how to parse mp3 URLs, and render the DOM structure
  63. * of mp3 flash players. This class is meant to be used as a singleton static
  64. * stateless class, that takes {@code goog.ui.media.Media} instances and renders
  65. * it. It expects {@code goog.ui.media.Media.getModel} to return a well formed,
  66. * previously checked, mp3 URL {@see goog.ui.media.PicasaAlbum.parseUrl},
  67. * which is the data model this renderer will use to construct the DOM
  68. * structure. {@see goog.ui.media.PicasaAlbum.newControl} for an example of
  69. * constructing a control with this renderer.
  70. *
  71. * This design is patterned after http://go/closure_control_subclassing
  72. *
  73. * It uses {@link goog.ui.media.FlashObject} to embed the flash object.
  74. *
  75. * @constructor
  76. * @extends {goog.ui.media.MediaRenderer}
  77. * @final
  78. */
  79. goog.ui.media.Mp3 = function() {
  80. goog.ui.media.MediaRenderer.call(this);
  81. };
  82. goog.inherits(goog.ui.media.Mp3, goog.ui.media.MediaRenderer);
  83. goog.addSingletonGetter(goog.ui.media.Mp3);
  84. /**
  85. * Flash player arguments. We expect that {@code flashUrl_} will contain a flash
  86. * movie that takes an audioUrl parameter on its URL, containing the URL of the
  87. * mp3 to be played.
  88. *
  89. * @type {string}
  90. * @private
  91. */
  92. goog.ui.media.Mp3.PLAYER_ARGUMENTS_ = 'audioUrl=%s';
  93. /**
  94. * Default CSS class to be applied to the root element of components rendered
  95. * by this renderer.
  96. *
  97. * @type {string}
  98. */
  99. goog.ui.media.Mp3.CSS_CLASS = goog.getCssName('goog-ui-media-mp3');
  100. /**
  101. * Flash player URL. Uses Google Reader's mp3 flash player by default.
  102. *
  103. * @type {string}
  104. * @private
  105. */
  106. goog.ui.media.Mp3.flashUrl_ =
  107. 'http://www.google.com/reader/ui/3523697345-audio-player.swf';
  108. /**
  109. * Regular expression to check if a given URL is a valid mp3 URL.
  110. *
  111. * Copied from http://go/markdownlite.js.
  112. *
  113. * NOTE(user): although it would be easier to use goog.string.endsWith('.mp3'),
  114. * in the future, we want to provide media inlining, which is basically getting
  115. * a text and replacing all mp3 references with an mp3 player, so it makes sense
  116. * to share the same regular expression to match everything.
  117. *
  118. * @type {RegExp}
  119. */
  120. goog.ui.media.Mp3.MATCHER =
  121. /(https?:\/\/[\w-%&\/.=:#\+~\(\)]+\.(mp3)+(\?[\w-%&\/.=:#\+~\(\)]+)?)/i;
  122. /**
  123. * A static convenient method to construct a goog.ui.media.Media control out of
  124. * a mp3 URL. It checks the mp3 URL, sets it as the data model
  125. * goog.ui.media.Mp3 renderer uses, sets the states supported by the renderer,
  126. * and returns a Control that binds everything together. This is what you
  127. * should be using for constructing Mp3 videos, except if you need more fine
  128. * control over the configuration.
  129. *
  130. * @param {goog.ui.media.MediaModel} dataModel A media model that must contain
  131. * an mp3 url on {@code dataModel.getUrl}.
  132. * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper, used for
  133. * document interaction.
  134. * @return {!goog.ui.media.Media} A goog.ui.Control subclass with the mp3
  135. * renderer.
  136. */
  137. goog.ui.media.Mp3.newControl = function(dataModel, opt_domHelper) {
  138. var control = new goog.ui.media.Media(
  139. dataModel, goog.ui.media.Mp3.getInstance(), opt_domHelper);
  140. // mp3 ui doesn't have a non selected view: it shows the mp3 player by
  141. // default.
  142. control.setSelected(true);
  143. return control;
  144. };
  145. /**
  146. * A static method that sets which flash URL this class should use. Use this if
  147. * you want to host your own flash mp3 player.
  148. *
  149. * @param {string} flashUrl The URL of the flash mp3 player.
  150. */
  151. goog.ui.media.Mp3.setFlashUrl = function(flashUrl) {
  152. goog.ui.media.Mp3.flashUrl_ = flashUrl;
  153. };
  154. /**
  155. * A static method that builds a URL that will contain the flash player that
  156. * will play the {@code mp3Url}.
  157. *
  158. * @param {string} mp3Url The URL of the mp3 music.
  159. * @return {string} An URL of a flash player that will know how to play the
  160. * given {@code mp3Url}.
  161. */
  162. goog.ui.media.Mp3.buildFlashUrl = function(mp3Url) {
  163. var flashUrl = goog.ui.media.Mp3.flashUrl_ + '?' +
  164. goog.string.subs(
  165. goog.ui.media.Mp3.PLAYER_ARGUMENTS_, goog.string.urlEncode(mp3Url));
  166. return flashUrl;
  167. };
  168. /**
  169. * Creates the initial DOM structure of a mp3 video, which is basically a
  170. * the flash object pointing to a flash mp3 player.
  171. *
  172. * @param {goog.ui.Control} c The media control.
  173. * @return {!Element} A DOM structure that represents the control.
  174. * @override
  175. */
  176. goog.ui.media.Mp3.prototype.createDom = function(c) {
  177. var control = /** @type {goog.ui.media.Media} */ (c);
  178. var div = goog.ui.media.Mp3.superClass_.createDom.call(this, control);
  179. var dataModel =
  180. /** @type {goog.ui.media.MediaModel} */ (control.getDataModel());
  181. var flash = new goog.ui.media.FlashObject(
  182. dataModel.getPlayer().getTrustedResourceUrl(), control.getDomHelper());
  183. flash.setFlashVar('playerMode', 'embedded');
  184. flash.render(div);
  185. return div;
  186. };
  187. /**
  188. * Returns the CSS class to be applied to the root element of components
  189. * rendered using this renderer.
  190. * @return {string} Renderer-specific CSS class.
  191. * @override
  192. */
  193. goog.ui.media.Mp3.prototype.getCssClass = function() {
  194. return goog.ui.media.Mp3.CSS_CLASS;
  195. };