Skip to content

Commit ba80f43

Browse files
author
Jeremy White
committed
Added support for Apple TV (AirPlay)
1 parent 57edc94 commit ba80f43

File tree

5 files changed

+303
-219
lines changed

5 files changed

+303
-219
lines changed

dist/connect_bridge.js

Lines changed: 148 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ var connectsdk = (function () {
9898
statics: {
9999
PlatformType: {
100100
DEFAULT: "Default",
101+
AIRPLAY: "AirPlay",
101102
GOOGLE_CAST: "GoogleCast",
102103
WEBOS_NATIVE: "WebOSNative",
103104
WEBOS_WEB_APP: "WebOSWebApp"
@@ -181,7 +182,9 @@ var connectsdk = (function () {
181182
var userAgent = navigator.userAgent.toLowerCase();
182183
this.platformType = ConnectManager.PlatformType.DEFAULT;
183184

184-
if (userAgent.indexOf('crkey') > 0 && cast != null)
185+
if (userAgent.indexOf('iphone os') >= 0)
186+
this.platformType = ConnectManager.PlatformType.AIRPLAY;
187+
else if (userAgent.indexOf('crkey') > 0 && cast != null)
185188
this.platformType = ConnectManager.PlatformType.GOOGLE_CAST;
186189
else if (userAgent.indexOf('tv') >= 0 && (userAgent.indexOf('webos') >= 0) || (userAgent.indexOf('web0s') >= 0))
187190
{
@@ -213,17 +216,11 @@ var connectsdk = (function () {
213216
broadcastMessage: nop
214217
};
215218

216-
// webOS
217-
var WebOSCommon = {
218-
interactive: true,
219+
// Base media player (JSON media playback & control commands)
220+
221+
var BaseMediaPlayer = {
219222
init: function () {
220-
window.addEventListener("keydown", this.handleKeyDown.bind(this));
221223
this.on(ConnectManager.EventType.STATUS, this.handleMediaStatusUpdate.bind(this));
222-
223-
this.webOSAppChannels = new WebOSAppChannels();
224-
this.webOSAppChannels.on('message', this.handleMessage.bind(this));
225-
this.webOSAppChannels.on('ready', this.handleReady.bind(this));
226-
this.webOSAppChannels.start();
227224
},
228225

229226
onLoadImage: function (image) {
@@ -248,101 +245,6 @@ var connectsdk = (function () {
248245
}
249246
},
250247

251-
sendMessage: function (to, message) {
252-
this.webOSAppChannels.sendMessage(to, message);
253-
},
254-
255-
broadcastMessage: function (message) {
256-
this.webOSAppChannels.broadcastMessage(message);
257-
},
258-
259-
handleKeyDown: function (evt) {
260-
if (!this.mediaElement) {
261-
return;
262-
}
263-
264-
switch (evt.keyCode) {
265-
case 415: // PLAY
266-
console.log(this.name + " :: play command received");
267-
this.mediaElement.play();
268-
this.emit(ConnectManager.EventType.PLAY);
269-
break;
270-
271-
case 19: // PAUSE
272-
console.log(this.name + " :: pause command received");
273-
this.mediaElement.pause();
274-
this.emit(ConnectManager.EventType.PAUSE);
275-
break;
276-
277-
case 413: // STOP
278-
console.log(this.name + " :: stop command received");
279-
this.emit(ConnectManager.EventType.STOP);
280-
break;
281-
}
282-
},
283-
284-
handleMessage: function (msgData) {
285-
var contentType = msgData.message.contentType;
286-
287-
switch (contentType) {
288-
case "connectsdk.mediaCommand":
289-
this.handleMediaCommand(msgData);
290-
break;
291-
292-
case "connectsdk.serviceCommand":
293-
this.handleServiceCommand(msgData);
294-
break;
295-
296-
default:
297-
this.emit(ConnectManager.EventType.MESSAGE, msgData);
298-
}
299-
},
300-
301-
handleMediaCommand: function (msgData) {
302-
var mediaCommand = msgData.message.mediaCommand;
303-
if (!mediaCommand) {
304-
return;
305-
}
306-
307-
var commandType = mediaCommand.type;
308-
console.log('processing mediaCommand ' + JSON.stringify(mediaCommand) + ' of type ' + commandType);
309-
310-
switch (commandType) {
311-
case "displayImage":
312-
this.handleDisplayImage(msgData);
313-
break;
314-
case "getDuration":
315-
this.handleGetDuration(msgData);
316-
break;
317-
case "getPosition":
318-
this.handleGetPosition(msgData);
319-
break;
320-
case "playMedia":
321-
this.handlePlayMedia(msgData);
322-
break;
323-
case "seek":
324-
this.handleSeek(msgData);
325-
break;
326-
}
327-
},
328-
329-
handleServiceCommand: function (msgData) {
330-
var serviceCommand = msgData.message.serviceCommand;
331-
if (!serviceCommand) {
332-
return;
333-
}
334-
335-
var commandType = serviceCommand.type;
336-
console.log('processing serviceCommand ' + JSON.stringify(serviceCommand) + ' of type ' + commandType);
337-
338-
switch (commandType) {
339-
case "close":
340-
// this is a hack to circumvent the fact that window.close() doesn't work with the webOS app type
341-
window.open(window.location, '_self').close();
342-
break;
343-
}
344-
},
345-
346248
handleDisplayImage: function (msgData) {
347249
var from = msgData.from;
348250
var mediaCommand = msgData.message.mediaCommand;
@@ -459,9 +361,123 @@ var connectsdk = (function () {
459361
requestId: requestId
460362
}
461363
});
462-
}
364+
},
365+
366+
handleMessage: function (msgData) {
367+
var contentType = null;
368+
369+
if (msgData != null && msgData.message != null)
370+
contentType = msgData.message.contentType;
371+
372+
switch (contentType) {
373+
case "connectsdk.mediaCommand":
374+
this.handleMediaCommand(msgData);
375+
break;
376+
377+
case "connectsdk.serviceCommand":
378+
this.handleServiceCommand(msgData);
379+
break;
380+
381+
default:
382+
this.emit(ConnectManager.EventType.MESSAGE, msgData);
383+
}
384+
},
385+
386+
handleMediaCommand: function (msgData) {
387+
var mediaCommand = msgData.message.mediaCommand;
388+
if (!mediaCommand) {
389+
return;
390+
}
391+
392+
var commandType = mediaCommand.type;
393+
console.log('processing mediaCommand ' + JSON.stringify(mediaCommand) + ' of type ' + commandType);
394+
395+
switch (commandType) {
396+
case "displayImage":
397+
this.handleDisplayImage(msgData);
398+
break;
399+
case "getDuration":
400+
this.handleGetDuration(msgData);
401+
break;
402+
case "getPosition":
403+
this.handleGetPosition(msgData);
404+
break;
405+
case "playMedia":
406+
this.handlePlayMedia(msgData);
407+
break;
408+
case "seek":
409+
this.handleSeek(msgData);
410+
break;
411+
}
412+
},
413+
414+
handleServiceCommand: nop
463415
};
464416

417+
// webOS
418+
var WebOSCommon = extend({
419+
interactive: true,
420+
init: function () {
421+
window.addEventListener("keydown", this.handleKeyDown.bind(this));
422+
this.on(ConnectManager.EventType.STATUS, this.handleMediaStatusUpdate.bind(this));
423+
424+
this.webOSAppChannels = new WebOSAppChannels();
425+
this.webOSAppChannels.on('message', this.handleMessage.bind(this));
426+
this.webOSAppChannels.on('ready', this.handleReady.bind(this));
427+
this.webOSAppChannels.start();
428+
},
429+
430+
sendMessage: function (to, message) {
431+
this.webOSAppChannels.sendMessage(to, message);
432+
},
433+
434+
broadcastMessage: function (message) {
435+
this.webOSAppChannels.broadcastMessage(message);
436+
},
437+
438+
handleKeyDown: function (evt) {
439+
if (!this.mediaElement) {
440+
return;
441+
}
442+
443+
switch (evt.keyCode) {
444+
case 415: // PLAY
445+
console.log(this.name + " :: play command received");
446+
this.mediaElement.play();
447+
this.emit(ConnectManager.EventType.PLAY);
448+
break;
449+
450+
case 19: // PAUSE
451+
console.log(this.name + " :: pause command received");
452+
this.mediaElement.pause();
453+
this.emit(ConnectManager.EventType.PAUSE);
454+
break;
455+
456+
case 413: // STOP
457+
console.log(this.name + " :: stop command received");
458+
this.emit(ConnectManager.EventType.STOP);
459+
break;
460+
}
461+
},
462+
463+
handleServiceCommand: function (msgData) {
464+
var serviceCommand = msgData.message.serviceCommand;
465+
if (!serviceCommand) {
466+
return;
467+
}
468+
469+
var commandType = serviceCommand.type;
470+
console.log('processing serviceCommand ' + JSON.stringify(serviceCommand) + ' of type ' + commandType);
471+
472+
switch (commandType) {
473+
case "close":
474+
// this is a hack to circumvent the fact that window.close() doesn't work with the webOS app type
475+
window.open(window.location, '_self').close();
476+
break;
477+
}
478+
}
479+
}, BaseMediaPlayer);
480+
465481
platforms.WebOSNative = extend({
466482
name: "webOS Native Web App"
467483
}, WebOSCommon);
@@ -470,6 +486,32 @@ var connectsdk = (function () {
470486
name: "webOS Web App"
471487
}, WebOSCommon);
472488

489+
// AirPlay
490+
platforms.AirPlay = extend({
491+
name: "AirPlay",
492+
interactive: true,
493+
494+
sendMessage: function (to, message) {
495+
// AirPlay does not have p2p support, so we'll just 'broadcast' this message
496+
this.broadcastMessage(message);
497+
},
498+
499+
broadcastMessage: function (message) {
500+
var messageString;
501+
502+
if (typeof message == 'string')
503+
messageString = message;
504+
else
505+
messageString = JSON.stringify(message);
506+
507+
var iframe = document.createElement('IFRAME');
508+
iframe.setAttribute('src', 'connectsdk://' + messageString);
509+
document.documentElement.appendChild(iframe);
510+
iframe.parentNode.removeChild(iframe);
511+
iframe = null;
512+
}
513+
}, BaseMediaPlayer),
514+
473515
// Google Cast
474516
platforms.GoogleCast = {
475517
name: "Google Cast",

0 commit comments

Comments
 (0)