UNPKG

airplay-js

Version:

JS Native Apple AirPlay client library for AppleTV

177 lines (144 loc) 4.69 kB
/** * node-airplay * * @file airplay device * @author zfkun(zfkun@msn.com) * @thanks https://github.com/benvanik/node-airplay/blob/master/lib/airplay/device.js */ var events = require( 'events' ); var util = require( 'util' ); var Client = require( './client' ).Client; function Device ( id, info, name, callback ) { var self = this; events.EventEmitter.call( this ); this.id = id; this.info = info; this.name = name; // this.serverInfo = null; this.pingDelay = 5 * 1000; // 心跳间隔 this.client = new Client( { host: info[0], port: 7000 // ,user: 'zfkun', pass: '' }, function () { self.client.serverInfo(function( info ) { self.serverInfo = info; self.onReady( callback ); }); } ); this.client.on( 'ping', function () { self.emit( 'ping' ); }); self.hls = require( '../airplay' ).createHLS(); self.hls.on( 'start', function () { console.info( '[HLS] start: %s', self.hls.getURI() ); }); self.hls.on( 'stop', function () { console.info( '[HLS] stop: %s', self.hls.getURI() ); }); self.hls.on( 'request', function ( req ) { // var uri = url.parse( req.url, true ); console.info( '[HLS] request: %s', req.url ); }); self.hls.on( 'process', function ( d ) { console.info( '[HLS] segment process: %s, %s, %s', d.index, d.file, d.out.toString() ); }); self.hls.on( 'segment', function ( d ) { console.info( '[HLS] segment created: %s, %s, %s', d.index, d.file, d.out ); }); self.hls.on( 'open', function ( d ) { console.info( '[HLS] opend: %s, %s', d.file, util.inspect( d.info ) ); }); self.hls.on( 'error', function ( err ) { console.info( '[HLS] segment error: ', util.inspect( err ) ); }); } util.inherits( Device, events.EventEmitter ); exports.Device = Device; Device.prototype.onReady = function ( callback ) { this.ready = !0; if ( callback ) { callback( this ); } this.emit( 'ready', this ); }; Device.prototype.isReady = function () { return !!this.ready; }; Device.prototype.close = function() { if ( this.client ) { this.client.close(); } this.client = null; this.ready = !1; this.emit( 'close', this ); }; Device.prototype.match = function ( info ) { for ( var key in info ) { if ( this.info[ key ] != info[ key ] ) { return !1; } } return !0; }; Device.prototype.getInfo = function() { var info = this.info; var txtRecord = info.txtRecord || {}; var serverInfo = this.serverInfo; return { id: this.id, name: info.name, fullName: info.fullname, deviceId: txtRecord.deviceid || serverInfo.deviceId, features: serverInfo.features || txtRecord.features, model: serverInfo.model, interfaceName: info.networkInterface, interfaceIndex: info.interfaceIndex, addresses: info.addresses, flags: txtRecord.flags, pk: txtRecord.pk, osVersion: serverInfo.osVersion, protocolVersion: serverInfo.protocolVersion, sourceVersion: serverInfo.sourceVersion || txtRecord.srcvers, vv: serverInfo.vv || txtRecord.vv, slideshowFeatures: [], supportedContentTypes: [] }; }; Device.prototype.play = function(media, position, callback){ var self = this //#TODO: Check if has ffmpeg and if not, go directly to simpleplay // console.log(typeof(media)) self.hls.start( 7001 + this.id ); console.log("going to play: "+media) self.hls.open( media , function ( info ) { device.simpleplay( self.hls.getURI(), '0.000000', function ( res ) { console.info( '->> ', res ); setTimeout(function(){ device.status( function ( info ) { console.info( '->> ', info ? info : 'no info >(' ); if ( info ) { console.log(info) } }); }, 4000); }); }); self.hls.on('NoFFMPEG', function(){ self.simpleplay(media, position, callback); self.emit('NoFFMPEG') }) }; // extend airplay apis: 'localName[:clientName]' [ 'status:playbackInfo', 'authorize', 'simpleplay', 'stop', 'scrub', 'reverse', 'rate', 'volume', 'photo' ].forEach(function ( api ) { api = api.split( ':' ); api[1] = api[1] || api[0]; Device.prototype[ api[0] ] = function() { this.client[ api[1] ].apply( this.client, arguments ); }; });