sbMediaContentListener.js
Go to the documentation of this file.
1 /*
2 //
3 // BEGIN SONGBIRD GPL
4 //
5 // This file is part of the Songbird web player.
6 //
7 // Copyright(c) 2005-2008 POTI, Inc.
8 // http://songbirdnest.com
9 //
10 // This file may be licensed under the terms of of the
11 // GNU General Public License Version 2 (the "GPL").
12 //
13 // Software distributed under the License is distributed
14 // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
15 // express or implied. See the GPL for the specific language
16 // governing rights and limitations.
17 //
18 // You should have received a copy of the GPL along with this
19 // program. If not, go to http://www.gnu.org/licenses/gpl.html
20 // or write to the Free Software Foundation, Inc.,
21 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 //
23 // END SONGBIRD GPL
24 //
25 */
26 
27 const Cc = Components.classes;
28 const Ci = Components.interfaces;
29 const Cr = Components.results;
30 
31 // From nsNetError.h
32 const NS_BINDING_ABORTED = 0x804b0002;
33 
34 const DESCRIPTION = "sbMediaContentListener";
35 const CID = "2803c9e8-b0b6-4dfe-8333-53430128f7e7";
36 const CONTRACTID = "@songbirdnest.com/contentlistener/media;1";
37 
38 const CONTRACTID_ARRAY = "@songbirdnest.com/moz/xpcom/threadsafe-array;1";
39 const CONTRACTID_LIBRARYMANAGER = "@songbirdnest.com/Songbird/library/Manager;1";
40 const CONTRACTID_OBSERVERSERVICE = "@mozilla.org/observer-service;1";
41 const CONTRACTID_PREFSERVICE = "@mozilla.org/preferences-service;1";
42 
43 const CATEGORY_CONTENT_LISTENER = "external-uricontentlisteners";
44 
45 const PREF_WEBLIBRARY_GUID = "songbird.library.web";
46 
47 const TYPE_MAYBE_MEDIA = "application/vnd.songbird.maybe.media";
48 const TYPE_MAYBE_PLAYLIST = "application/vnd.songbird.maybe.playlist";
49 
50 // For XPCOM boilerplate.
51 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
52 
53 // For Songbird properties.
54 Components.utils.import("resource://app/jsmodules/sbProperties.jsm");
55 Components.utils.import("resource://app/jsmodules/sbLibraryUtils.jsm");
56 
67  this._typeSniffer = Cc["@songbirdnest.com/Songbird/Mediacore/TypeSniffer;1"]
68  .createInstance(Ci.sbIMediacoreTypeSniffer);
69  this._mm = Cc["@songbirdnest.com/Songbird/Mediacore/Manager;1"]
70  .getService(Ci.sbIMediacoreManager);
71 }
73  _parentContentListener: null,
74 
79  classID: Components.ID(CID),
81  _typeSniffer: null,
82  _mm: null,
83 
87  _handleMediaURI: function _handleMediaURI(aURI) {
88  // TODO: Check a pref to determine if this should be going into our library?
90  getService(Ci.sbILibraryManager);
91  var library;
92  var uri = aURI;
93 
94  if (aURI instanceof Ci.nsIFileURL) {
95  // Local files go into the main library.
96  library = libraryManager.mainLibrary;
97  libraryManager.getContentURI(aURI).spec;
98  }
99  else {
100  // All other files go into the web library.
101  var prefService =
102  Cc[CONTRACTID_PREFSERVICE].getService(Ci.nsIPrefBranch);
103 
104  var webLibraryGUID = prefService.getCharPref(PREF_WEBLIBRARY_GUID);
105  library = libraryManager.getLibrary(webLibraryGUID);
106  }
107 
108  // Try to see if we've already found and scanned this url.
109  var listener = {
110  foundItem: null,
111  onEnumerationBegin: function onEnumerationBegin() {
112  },
113  onEnumeratedItem: function onEnumeratedItem(list, item) {
114  this.foundItem = item;
115  return Ci.sbIMediaListEnumerationListener.CANCEL;
116  },
117  onEnumerationEnd: function onEnumerationEnd() {
118  }
119  };
120 
121  var url = uri.spec;
122  library.enumerateItemsByProperty(SBProperties.contentURL, url, listener );
123  if (!listener.foundItem) {
124  var mediaItem = library.createMediaItem(aURI);
125 
126  // Get metadata going.
127  var scanArray = Cc[CONTRACTID_ARRAY].createInstance(Ci.nsIMutableArray);
128  scanArray.appendElement(mediaItem, false);
129 
130  var metadataService = Cc["@songbirdnest.com/Songbird/FileMetadataService;1"]
131  .getService(Ci.sbIFileMetadataService);
132  var job = metadataService.read(scanArray);
133  }
134 
135  var view = library.createView();
136  var filter = LibraryUtils.createConstraint([
137  [
138  [SBProperties.contentURL, [url]]
139  ]
140  ]);
141  view.filterConstraint = filter;
142 
143  this._mm.sequencer.playView(view, 0);
144  },
145 
146  _handlePlaylistURI: function _handlePlaylistURI(aURI) {
147  var app = Cc["@songbirdnest.com/Songbird/ApplicationController;1"]
148  .getService(Ci.sbIApplicationController);
149  var window = app.activeMainWindow;
150  if (window) {
151  var tabbrowser = window.document.getElementById("content");
152  tabbrowser.handleMediaURL(aURI.spec, true, true, null, null);
153  }
154  },
155 
159  onStartURIOpen: function onStartURIOpen(aURI) {
160  return false;
161  },
162 
166  doContent: function doContent(aContentType, aIsContentPreferred, aRequest, aContentHandler) {
167  // XXXben Sometime in the future we may have a stream listener that we can
168  // hook up here to grab the file as it is being downloaded. For now,
169  // though, cancel the request and send the URL off to the playback
170  // service.
171  var channel = aRequest.QueryInterface(Ci.nsIChannel);
172  var uri = channel.URI;
173 
174  var contentType = channel.contentType;
175 
176  dump("\n---------------------------\nsbMediaContentListener -- contentType: " + contentType + "\n---------------------------\n");
177 
178  // We seem to think this is a media file, let's make sure it doesn't have a
179  // content type that we know for sure isn't media.
180  if(contentType == "text/html" ||
181  contentType == "application/atom+xml" ||
182  contentType == "application/rdf+xml" ||
183  contentType == "application/rss+xml" ||
184  contentType == "application/xml") {
185 
186  // Bah, looks like the content type doesn't match up at all,
187  // just find someone else to load it.
188  return false;
189  }
190 
191  // Let exceptions propogate from here!
192  if (aContentType == TYPE_MAYBE_MEDIA) {
193  if (!this._typeSniffer.isValidMediaURL(uri)) {
194  // Hmm, badness. We can't actually play this file type. Throw an error
195  // here to get the URILoader to keep trying with other content listeners.
196  throw Cr.NS_ERROR_UNEXPECTED;
197  }
198 
199  try {
200  this._handleMediaURI(uri);
201  }
202  catch (e) {
203  Components.utils.reportError(e);
204  throw e;
205  }
206  }
207  else if (aContentType == TYPE_MAYBE_PLAYLIST) {
208  if (!this._typeSniffer.isValidWebSafePlaylistURL(uri)) {
209  // We thought it looked like a playlist but it in the end
210  // it wasn't!
211  throw Cr.NS_ERROR_UNEXPECTED;
212  }
213 
214  try {
215  this._handlePlaylistURI(uri);
216  }
217  catch (e) {
218  Components.utils.reportError(e);
219  throw e;
220  }
221  }
222 
223  // The request is active, so make sure to cancel it.
224  aRequest.cancel(NS_BINDING_ABORTED);
225 
226  return true;
227  },
228 
232  isPreferred: function isPreferred(aContentType, aDesiredContentType) {
233  return aContentType == TYPE_MAYBE_MEDIA ||
234  aContentType == TYPE_MAYBE_PLAYLIST;
235  },
236 
240  canHandleContent: function canHandleContent(aContentType, aIsContentPreferred, aDesiredContentType) {
241  return aContentType == TYPE_MAYBE_MEDIA ||
242  aContentType == TYPE_MAYBE_PLAYLIST;
243  },
244 
248  loadCookie: null,
249 
253  get parentContentListener() {
254  return null;
255  },
256  set parentContentListener(val) {
257  // We don't support parent content listeners.
258  throw Cr.NS_ERROR_NOT_IMPLEMENTED;
259  },
260 
264  QueryInterface: XPCOMUtils.generateQI([Ci.nsIURIContentListener,
265  Ci.nsISupportsWeakReference])
266 }
267 
271 function postRegister(aCompMgr, aFileSpec, aLocation) {
272  XPCOMUtils.categoryManager.addCategoryEntry(CATEGORY_CONTENT_LISTENER,
274  true, true);
275  XPCOMUtils.categoryManager.addCategoryEntry(CATEGORY_CONTENT_LISTENER,
277  true, true);
278 }
279 
280 function preUnregister(aCompMgr, aFileSpec, aLocation) {
281  XPCOMUtils.categoryManager.deleteCategoryEntry(CATEGORY_CONTENT_LISTENER,
282  TYPE_MAYBE_MEDIA, true);
283  XPCOMUtils.categoryManager.deleteCategoryEntry(CATEGORY_CONTENT_LISTENER,
284  TYPE_MAYBE_PLAYLIST, true);
285 }
286 
287 var NSGetModule = XPCOMUtils.generateNSGetModule([sbMediaContentListener],
288  postRegister, preUnregister);
const DESCRIPTION
return foundItem
const CID
const CONTRACTID_LIBRARYMANAGER
const TYPE_MAYBE_MEDIA
const CONTRACTID_OBSERVERSERVICE
sbDeviceFirmwareAutoCheckForUpdate prototype contractID
sbOSDControlService prototype QueryInterface
const Ci
const CONTRACTID
sbDeviceFirmwareAutoCheckForUpdate prototype classDescription
const CONTRACTID_PREFSERVICE
getService(Ci.sbIFaceplateManager)
let window
const Cr
var tabbrowser
this _dialogInput val(dateText)
var libraryManager
return null
Definition: FeedWriter.js:1143
const PREF_WEBLIBRARY_GUID
function url(spec)
var uri
Definition: FeedWriter.js:1135
const Cc
sbDeviceFirmwareAutoCheckForUpdate prototype classID
Javascript wrappers for common library tasks.
const NS_BINDING_ABORTED
function postRegister(aCompMgr, aFileSpec, aLocation)
Array filter(tab.attributes, function(aAttr){return(_this.xulAttributes.indexOf(aAttr.name) >-1);}).forEach(tab.removeAttribute
function sbMediaContentListener()
const CONTRACTID_ARRAY
const CATEGORY_CONTENT_LISTENER
const TYPE_MAYBE_PLAYLIST