Skip to content

Commit

Permalink
pct fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
luigiplr committed Nov 10, 2015
1 parent 031c1c6 commit 7a5eb1e
Show file tree
Hide file tree
Showing 2 changed files with 197 additions and 205 deletions.
347 changes: 166 additions & 181 deletions device.js
Original file line number Diff line number Diff line change
@@ -1,225 +1,210 @@
var Client = require('castv2-client').Client;
var Client = require('castv2-client').Client;
var DefaultMediaReceiver = require('castv2-client').DefaultMediaReceiver;

var events = require('events');
var util = require('util');
var debug = require('debug')('Device');
var debug = require('debug')('chromecast-js');

/* Chromecast
* Supported Media: https://developers.google.com/cast/docs/media
* Receiver Apps: https://developers.google.com/cast/docs/receiver_apps
*/

var Device = function(options) {
events.EventEmitter.call(this);
var self = this;
self.config = options;
this.init();
events.EventEmitter.call(this);
this.config = options;
this.init();
};

exports.Device = Device;
util.inherits(Device, events.EventEmitter);

Device.prototype.connect = function(callback) {
var self = this;

// Always use a fresh client when connecting
if (self.client) self.client.close();
self.client = new Client();
self.client.connect(self.host, function() {
debug('connected, launching app ...');
self.client.launch(DefaultMediaReceiver, function(err, player) {
if (err) {
debug(err);
} else {
self.player = player;
self.emit('connected');
if (callback) callback();
}

player.on('status', function(status) {
if (status){
debug('status broadcast playerState=%s',status.playerState);
} else {
debug('-');
}
});

});
});

self.client.on('error', function(err) {
console.log('Error: %s', err.message);
self.connect(self.host);
self.client.close();
});
};

Device.prototype.init = function() {
var self = this;

self.host = self.config.addresses[0];
self.playing = false;
this.host = this.config.addresses[0];
this.playing = false;
};

Device.prototype.play = function(resource, n, callback) {
var self = this;

options = { autoplay: true };

if (typeof(resource) === 'string'){
var media = {
contentId: resource,
contentType: 'video/mp4'
};
} else {
var media = {
contentId: resource.url,
contentType: 'video/mp4'
};
if (resource.subtitles){
var tracks = [];
var i = 0;
for (var each in resource.subtitles ) {
var track = {
trackId: i,
type: 'TEXT',
trackContentId: resource.subtitles[i].url,
trackContentType: 'text/vtt',
name: resource.subtitles[i].name,
language: resource.subtitles[i].language,
subtype: 'SUBTITLES'
};
tracks.push(track);
i++;
}

media.tracks = tracks;
options['activeTrackIds'] = [0];
}
if (resource.subtitles_style){
media.textTrackStyle = resource.subtitles_style;
self.subtitles_style = resource.subtitles_style;
}
if (resource.cover) {
media.metadata = {
type: 0,
metadataType: 0,
title: resource.cover.title,
images: [
{ url: resource.cover.url }
]
};
}
}

options['currentTime'] = n || 0;

self.player.load(media, options, function(err, status) {
self.playing = true;
if (callback){
callback(err,status);
}
});
var self = this;

// Always use a fresh client when connecting
if (self.client) self.client.close();
debug('chromecast-js: Connect to host: '+ self.host);
//debug('chromecast-js: Config', self.config);
self.client = new Client();
self.client.connect(self.host, function(err, status) {
if (err) {
console.error('chromecast-js: Error connecting', err);
return callback(err);
}
debug('chromecast-js: Connected, launching player...');
self.client.launch(DefaultMediaReceiver, function(err, player) {
if (err) {
console.error('chromecast-js: Error launching MediaReceiver', err);
return callback(err);
}
self.player = player;
self._privatePlayMedia(resource, n, callback);
player.on('status', function(status) {
if (status) {
debug('chromecast-js: PlayerState=%s',status.playerState);
// Propagate status event
self.emit('status', status);
}
});
});
});

self.client.on('error', function(err) {
debug('chromecast-js Error: %s', err.message);
self.client.close();
//TODO: Trigger IDLE state or better yet switch to trigger('device:closed') for these events.
});
};

Device.prototype._privatePlayMedia = function(resource, n, callback) {
var self = this;

options = { autoplay: true,
currentTime: n || 0 };

if (typeof(resource) === 'string') {
var media = {
contentId: resource,
contentType: 'video/mp4'
};
} else {
var media = {
contentId: resource.url,
contentType: 'video/mp4'
};
if (resource.subtitles) {
var tracks = [];
var i = 0;
for (var each in resource.subtitles ) {
var track = {
trackId: i,
type: 'TEXT',
trackContentId: resource.subtitles[i].url,
trackContentType: 'text/vtt',
name: resource.subtitles[i].name,
language: resource.subtitles[i].language,
subtype: 'SUBTITLES'
};
tracks.push(track);
i++;
}

media.tracks = tracks;
options['activeTrackIds'] = [0];
}
if (resource.subtitles_style) {
media.textTrackStyle = resource.subtitles_style;
self.subtitles_style = resource.subtitles_style;
}
if (resource.cover) {
media.metadata = {
type: 0,
metadataType: 0,
title: resource.cover.title,
images: [
{ url: resource.cover.url }
]
};
}
}

debug('chromecast-js: Loading media: %s (%s)', media.contentId, media.contentType);
self.player.load(media, options, function(err, status) {
if (err) {
console.error('chromecast-js: Error loading media', err);
return callback(err);
}
self.playing = true;
callback(null, status);
});
};

Device.prototype.getStatus = function(callback) {
var self = this;

self.player.getStatus(function(err, status) {
if (err) {
console.log("getStatus error: %s", err.message);
} else {
callback(status);
}
});
this.player.getStatus(function(err, status) {
if (err) {
debug("chromecast-js.getStatus error: %s", err.message);
return callback(err);
}
callback(null, status);
});
};

// Seeks to specific offset in seconds into the media
Device.prototype.seekTo = function(newCurrentTime, callback) {
this.player.seek(newCurrentTime, callback);
this.player.seek(newCurrentTime, callback);
};

// Seeks in seconds relative to currentTime
Device.prototype.seek = function(seconds, callback) {
var self = this;

// Retrieve updated status just before seek
self.getStatus(function(newStatus) {
newCurrentTime = newStatus.currentTime + seconds;
self.seekTo(newCurrentTime, callback);
});
var self = this;

// Retrieve updated status just before seek
self.getStatus(function(err, newStatus) {
if (err) return callback(err);
newCurrentTime = newStatus.currentTime + seconds;
self.seekTo(newCurrentTime, callback);
});
};

Device.prototype.pause = function(callback) {
var self = this;
this.playing = false;
this.player.pause(callback);
};

self.playing = false;
self.player.pause(callback);
Device.prototype.unpause = function(callback) {
this.playing = true;
this.player.play(callback);
};

Device.prototype.setVolume = function(volume, callback) {
var self = this;

self.client.setVolume({ level: volume }, callback);
this.client.setVolume({ level: volume }, callback);
};

Device.prototype.setVolumeMuted = function(muted, callback){
var self = this;

self.client.setVolume({ 'muted': muted }, callback);
};

Device.prototype.unpause = function(callback) {
var self = this;

self.playing = true;
self.player.play(callback);
};

Device.prototype.stop = function(callback) {
var self = this;

self.playing = false;
self.player.stop(callback);
this.client.setVolume({ muted: muted }, callback);
};

Device.prototype.subtitlesOff = function(callback) {
var self = this;

self.player.media.sessionRequest({
type: 'EDIT_TRACKS_INFO',
activeTrackIds: [] // turn off subtitles.
}, function(err, status){
if (err) callback(err);
callback(null, status);
});
this.player.media.sessionRequest({
type: 'EDIT_TRACKS_INFO',
activeTrackIds: [] // turn off subtitles.
}, callback);
};

Device.prototype.changeSubtitles = function(num, callback) {
var self = this;

self.player.media.sessionRequest({
type: 'EDIT_TRACKS_INFO',
activeTrackIds: [num] // turn off subtitles.
}, function(err, status){
if (err) callback(err);
callback(null, status);
});
Device.prototype.changeSubtitles = function(subIdx, callback) {
this.player.media.sessionRequest({
type: 'EDIT_TRACKS_INFO',
activeTrackIds: [subIdx]
}, callback);
};

Device.prototype.changeSubtitlesSize = function(num, callback) {
var self = this;

var newStyle = self.subtitles_style;
newStyle.fontScale = num;
self.player.media.sessionRequest({
type: 'EDIT_TRACKS_INFO',
textTrackStyle: newStyle
}, function(err, status){
if (err) callback(err);
callback(null, status);
});
Device.prototype.changeSubtitlesSize = function(fontScale, callback) {
var newStyle = this.subtitles_style;
newStyle.fontScale = fontScale;
this.player.media.sessionRequest({
type: 'EDIT_TRACKS_INFO',
textTrackStyle: newStyle
}, callback);
};

Device.prototype.close = function(callback) {
if ( this.client ) {
this.client.close();
this.client = null;
}
if (callback) callback();
}
// Stop player, wait 5 sec at stand-by screen, then close client.
Device.prototype.stop = function(callback) {
var self = this;
self.player.stop(function() {
debug('chromecast-js: Player Stopped');
setTimeout(function() {
self.client.stop(self.player, function() {
self.client.close();
self.client = null;
debug('chromecast-js: Disconnected');
if (callback) callback();
});
}, 5000);
});
};
Loading

1 comment on commit 7a5eb1e

@kevinchappell
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! Looking forward to reading through this. My only recommendation would be to match indent style to spaces to make the diff easier to follow.

Please sign in to comment.