4 * @module MultimediaPlayerApplication
8 * Class representing remote media content for MultiMedia Player.
10 * @class RemoteContent
13 var RemoteContent = function() {
16 this.mediaServer = tizen.mediaserver;
17 this.mediaSources = ko.observableArray([]);
18 this.selectedMediaSource = ko.observable(null);
20 this.mediaContainers = ko.observableArray([]);
21 this.selectedMediaContainer = ko.observable(null);
23 this.mediaContainerItems = ko.observableArray([]);
24 this.selectedMediaContainerItem = ko.observable(null);
26 this.currentBrowseOperation = "";
27 this.alphabetFilter = ko.observable("");
28 this.onMediaSourceLost = null;
30 this.mediaSourcesComputed = ko.computed(function() {
31 if (self.alphabetFilter() !== "") {
32 return ko.utils.arrayFilter(self.mediaSources(), function(mediaSource) {
33 return mediaSource.friendlyName.toString().toLowerCase().trim().indexOf(self.alphabetFilter().toString().toLowerCase().trim()) === 0;
36 return self.mediaSources();
38 this.mediaContainersComputed = ko.computed(function() {
39 if (self.alphabetFilter() !== "") {
40 return ko.utils.arrayFilter(self.mediaContainers(), function(mediaContainer) {
41 return mediaContainer.title.toString().toLowerCase().trim().indexOf(self.alphabetFilter().toString().toLowerCase().trim()) === 0;
44 return self.mediaContainers();
46 this.mediaContainerItemsComputed = ko.computed(function() {
47 if (self.alphabetFilter() !== "") {
48 return ko.utils.arrayFilter(self.mediaContainerItems(), function(mediaItem) {
49 return mediaItem.title.toString().toLowerCase().trim().indexOf(self.alphabetFilter().toString().toLowerCase().trim()) === 0;
52 return self.mediaContainerItems();
57 * Scans network for available DLNA server and adds it to media sources.
59 * @method scanMediaServerNetwork
61 RemoteContent.prototype.scanMediaServerNetwork = function() {
64 if (!!self.mediaServer) {
65 self.clearDisappearedMediaSources();
66 self.mediaServer.scanNetwork(function(source) {
67 self.addMediaSource(source);
69 console.log("An error has occured while scanning network: " + err.message);
76 * Adds given media source to the list.
78 * @method addMediaSource
79 * @param source {Object} media source
81 RemoteContent.prototype.addMediaSource = function(source) {
86 if (!source.friendlyName) {
89 source.timestamp = new Date().getTime();
90 var sourceExists = false;
91 for ( var i = 0; i < self.mediaSources().length; ++i) {
92 var src = self.mediaSources()[i];
93 if (src.id === source.id) {
94 self.mediaSources()[i] = source;
100 self.mediaSources.push(source);
103 self.mediaSources.sort(function(left, right) {
104 var leftFriendlyName = "Unknown";
105 if (!!left.friendlyName && left.friendlyName !== "") {
106 leftFriendlyName = left.friendlyName;
108 leftFriendlyName = leftFriendlyName.toString().trim().toLowerCase();
109 var rightFriendlyName = "Unknown";
110 if (!!right.friendlyName && right.friendlyName !== "") {
111 rightFriendlyName = right.friendlyName;
113 rightFriendlyName = rightFriendlyName.toString().trim().toLowerCase();
114 return leftFriendlyName === rightFriendlyName ? 0 : (leftFriendlyName < rightFriendlyName) ? -1 : 1;
120 * Sets given media source as selected and adds new media container based on the media source and sets it as selected.
122 * @method selectMediaSource
123 * @param mediaSource {Object} media source
125 RemoteContent.prototype.selectMediaSource = function(mediaSource) {
128 console.log(mediaSource);
129 self.selectedMediaSource(null);
131 self.selectedMediaSource(mediaSource);
132 self.resetMediaContainers();
133 self.resetMediaContainerItems();
134 var mediaSourceContainerProps = {
135 DisplayName : mediaSource.root.title,
136 Path : mediaSource.root.id,
137 Type : mediaSource.root.type
139 /*global mediacontent*/
140 var mediaContainer = new mediacontent.MediaContainer(mediaSourceContainerProps);
141 self.mediaContainers.push(mediaContainer);
142 self.selectMediaContainer(mediaContainer);
147 * Sets given media container as selected.
149 * @method selectMediaContainer
150 * @param mediaSourceContainer {Object} media source container
152 RemoteContent.prototype.selectMediaContainer = function(mediaSourceContainer) {
155 console.log(mediaSourceContainer);
156 if (!!mediaSourceContainer) {
157 self.resetMediaContainerItems();
159 for ( var i = self.mediaContainers().length - 1; i >= 0; --i) {
160 if (self.mediaContainers()[i] !== mediaSourceContainer) {
161 self.mediaContainers.pop();
166 console.log(self.mediaContainers());
167 self.selectedMediaContainer(mediaSourceContainer);
168 self.browseMediaSourceContainer(self.selectedMediaSource(), mediaSourceContainer);
173 * Sets given media container item as selected.
175 * @method selectMediaContainerItem
176 * @param mediaContainerItem {Object} media source container
178 RemoteContent.prototype.selectMediaContainerItem = function(mediaContainerItem) {
181 console.log(mediaContainerItem);
182 if (!!mediaContainerItem) {
183 self.selectedMediaContainerItem(mediaContainerItem);
184 if (mediaContainerItem.type === "CONTAINER") {
185 self.mediaContainers.push(mediaContainerItem);
186 self.selectMediaContainer(mediaContainerItem);
192 * Sets selected media source to null and empties media sources.
194 * @method resetMediaSource
196 RemoteContent.prototype.resetMediaSource = function() {
199 self.selectedMediaSource(null);
200 self.mediaSources.removeAll();
201 self.mediaSources([]);
205 * Removes expired media sources and invokes onMediaSourceLost listener.
207 * @method clearDisappearedMediaSources
209 RemoteContent.prototype.clearDisappearedMediaSources = function() {
212 if (self.mediaSources().length) {
213 for ( var i = self.mediaSources().length - 1; i >= 0; --i) {
214 if (new Date().getTime() - self.mediaSources()[i].timestamp > 10000) {
215 var mediaSourceId = self.mediaSources()[i].id;
216 self.mediaSources.remove(self.mediaSources()[i]);
217 if (!!self.onMediaSourceLost) {
218 self.onMediaSourceLost(mediaSourceId);
226 * Sets the listener to receive notifications when media source is lost.
228 * @method setMediaSourceLostListener
229 * @param onMediaSourceLost {Function(mediaSourceId)} Event listener to be set.
231 RemoteContent.prototype.setMediaSourceLostListener = function(onMediaSourceLost) {
234 if (!!onMediaSourceLost) {
235 self.onMediaSourceLost = onMediaSourceLost;
240 * Sets selected media container to null and empties media containers.
242 * @method resetMediaContainers
244 RemoteContent.prototype.resetMediaContainers = function() {
247 self.selectedMediaContainer(null);
248 self.mediaContainers.removeAll();
249 self.mediaContainers([]);
253 * Sets selected media container item to null and empties media container items.
255 * @method resetMediaContainerItems
257 RemoteContent.prototype.resetMediaContainerItems = function() {
260 self.selectedMediaContainerItem(null);
261 self.mediaContainerItems.removeAll();
262 self.mediaContainerItems([]);
266 * Gets media source by its id.
268 * @method getMediaSourceById
269 * @param id (String) media source id
271 RemoteContent.prototype.getMediaSourceById = function(id) {
274 var mediaSource = ko.utils.arrayFirst(self.mediaSources(), function(ms) {
281 * Gets media container by its id.
283 * @method getMediaContainerById
284 * @param id {String} media container id
286 RemoteContent.prototype.getMediaContainerById = function(id) {
289 var mediaContainer = ko.utils.arrayFirst(self.mediaContainers(), function(mc) {
292 return mediaContainer;
296 * Browses given media source container.
298 * @method browseMediaSourceContainer
299 * @param source {Object} media source
300 * @param container {Object} media container
302 RemoteContent.prototype.browseMediaSourceContainer = function(source, container) {
305 var browseCount = 100;
306 var browseOffset = 0;
307 var localOp = "Browse_" + source.id + "_" + container.id;
309 function browseErrorCB(str) {
310 console.log("Error browsing " + container.id + " : " + str);
313 function browseContainerCB(jsonArray) {
314 console.log(jsonArray);
315 if (self.currentBrowseOperation !== localOp) {
318 for ( var i = 0; i < jsonArray.length; ++i) {
319 self.mediaContainerItems.push(mediacontent.mediaObjectForProps(jsonArray[i]));
322 if (jsonArray.length === browseCount) {
323 browseOffset += browseCount;
324 source.browse(container.id, "+DisplayName", browseCount, browseOffset, browseContainerCB, browseErrorCB);
326 self.currentBrowseOperation = "";
330 if (self.currentBrowseOperation === localOp) {
334 self.currentBrowseOperation = localOp;
336 source.browse(container.id, "+DisplayName", browseCount, browseOffset, browseContainerCB, browseErrorCB);
340 * Gets audio media items from selected container.
342 * @method getAudioFromSelectedContainer
344 RemoteContent.prototype.getAudioFromSelectedContainer = function() {
347 if (!!self.mediaContainerItemsComputed() && self.mediaContainerItemsComputed().length) {
348 return ko.utils.arrayFilter(self.mediaContainerItemsComputed(), function(mediaItem) {
349 return mediaItem.type === "AUDIO";
356 * Gets video media items from selected container.
358 * @method getVideoFromSelectedContainer
360 RemoteContent.prototype.getVideoFromSelectedContainer = function() {
363 if (!!self.mediaContainerItemsComputed() && self.mediaContainerItemsComputed().length) {
364 return ko.utils.arrayFilter(self.mediaContainerItemsComputed(), function(mediaItem) {
365 return mediaItem.type === "VIDEO";