newCast
This commit is contained in:
parent
986102cf9b
commit
5012f3df7d
@ -1,11 +1,36 @@
|
|||||||
const ChromecastAPI = require('chromecast-api')
|
const ChromecastAPI = require('chromecast-api')
|
||||||
|
|
||||||
const client = new ChromecastAPI()
|
async function getDevice() {
|
||||||
|
const client = new ChromecastAPI()
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
client.on('device', function (device) {
|
||||||
|
// console.log(device)
|
||||||
|
if (device.friendlyName === 'Downstairs') {
|
||||||
|
resolve(device);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
client.on('device', function (device) {
|
async function test() {
|
||||||
var mediaURL = 'http://commondatastorage.googleapis.com/gtv-videos-bucket/big_buck_bunny_1080p.mp4';
|
var mediaURL = 'https://www.youtube.com/watch?v=pb05OXz7-Ko&list=PLATQ8iWXs4GzKzUhHyImBCvVVQWkTnmeM';
|
||||||
|
test = await getDevice()
|
||||||
device.play(mediaURL, function (err) {
|
console.log(test)
|
||||||
|
test.play(mediaURL, function (err) {
|
||||||
if (!err) console.log('Playing in your chromecast')
|
if (!err) console.log('Playing in your chromecast')
|
||||||
})
|
})
|
||||||
})
|
}
|
||||||
|
|
||||||
|
test()
|
||||||
|
|
||||||
|
// console.log(device)
|
||||||
|
// if (device.friendlyName === 'Downstairs') {
|
||||||
|
// test.friendlyName = device.friendlyName,
|
||||||
|
// test.name = device.name,
|
||||||
|
// test.host = device.host
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // device.play(mediaURL, function (err) {
|
||||||
|
// // if (!err) console.log('Playing in your chromecast')
|
||||||
|
// // })
|
||||||
|
// })
|
224
bin/newCast.js
Normal file
224
bin/newCast.js
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
const express = require('express');
|
||||||
|
const bodyParser = require('body-parser');
|
||||||
|
const mdns = require('mdns');
|
||||||
|
const Client = require('castv2-client').Client;
|
||||||
|
const DefaultMediaReceiver = require('castv2-client').DefaultMediaReceiver;
|
||||||
|
const request = require('request');
|
||||||
|
const os = require('os');
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const querystring = require('querystring');
|
||||||
|
|
||||||
|
const PORT = process.env.PORT || 3002;
|
||||||
|
const app = express();
|
||||||
|
const devices = new Map();
|
||||||
|
let playlist = [];
|
||||||
|
|
||||||
|
const browser = mdns.createBrowser(mdns.tcp('googlecast'));
|
||||||
|
|
||||||
|
function deviceRegister(name, address, port) {
|
||||||
|
let id = devices.size;
|
||||||
|
let client = new Client();
|
||||||
|
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
client.connect(address, () => {
|
||||||
|
client.launch(DefaultMediaReceiver, (err, player) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
devices.set(id, { name, address, port, client, player });
|
||||||
|
resolve(player);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createEventListeners(player) {
|
||||||
|
player.on('status', function(status) {
|
||||||
|
console.log('status broadcast playerState=%s', status.playerState);
|
||||||
|
if (status.playerState === 'IDLE') {
|
||||||
|
playlist.splice(0, 1);
|
||||||
|
writePlaylist();
|
||||||
|
if (playlist.length > 0) {
|
||||||
|
player.load(playlist[0], { autoplay: true}, (err, status) => {
|
||||||
|
console.log('Play!');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function writePlaylist() {
|
||||||
|
let songs = playlist.map(p => p.metadata.title).join('\n');
|
||||||
|
let content = `http://dk.ngrok.io/api
|
||||||
|
${songs}`
|
||||||
|
fs.writeFileSync(path.join(os.homedir(), 'playlist.txt'), content, 'utf8');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMediaObject(name, artist, songUrl, picture) {
|
||||||
|
return {
|
||||||
|
contentId: songUrl,
|
||||||
|
contentType: 'audio/mpeg3',
|
||||||
|
streamType: 'LIVE', // or LIVE
|
||||||
|
|
||||||
|
// Title and cover displayed while buffering
|
||||||
|
metadata: {
|
||||||
|
type: 0,
|
||||||
|
metadataType: 0,
|
||||||
|
title: `${name} - ${artist}`,
|
||||||
|
images: [
|
||||||
|
{ url: picture }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let idx = 0;
|
||||||
|
browser.on('serviceUp', (service) => {
|
||||||
|
if (idx !== 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
idx = 1;
|
||||||
|
console.log('found device "%s" at %s:%d', service.name, service.addresses[0], service.port);
|
||||||
|
// ondeviceup(service.addresses[0]);
|
||||||
|
deviceRegister(service.name, service.addresses[0], service.port).then(player => {
|
||||||
|
console.log('Player registered');
|
||||||
|
return player;
|
||||||
|
}).then(createEventListeners).catch((err) => {
|
||||||
|
console.error(err.message);
|
||||||
|
});
|
||||||
|
browser.stop();
|
||||||
|
});
|
||||||
|
|
||||||
|
browser.start();
|
||||||
|
|
||||||
|
app.use(bodyParser.urlencoded({ extended: false }));
|
||||||
|
app.use(bodyParser.json());
|
||||||
|
|
||||||
|
app.get('/api', (req, res, next) => {
|
||||||
|
let stack = app._router.stack;
|
||||||
|
let methodList = [];
|
||||||
|
Object.keys(stack).forEach(key => {
|
||||||
|
let route = stack[key].route;
|
||||||
|
if (route) {
|
||||||
|
methodList.push(`${route.stack[0].method.toUpperCase()} ${route.path}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
res.type('text/plain').send(`Available routes:
|
||||||
|
|
||||||
|
${methodList.join('\n')}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/api/devices', (req, res, next) => {
|
||||||
|
let result = [];
|
||||||
|
|
||||||
|
for (let [id, { name, address }] of devices) {
|
||||||
|
result.push({id, name, address});
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send({result});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/api/devices/:id', (req, res, next) => {
|
||||||
|
let device = devices.get(parseInt(req.params.id, 10));
|
||||||
|
let result = {}
|
||||||
|
if (device) {
|
||||||
|
result.name = device.name;
|
||||||
|
result.address = device.address;
|
||||||
|
result.port = device.port;
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send(result);
|
||||||
|
});
|
||||||
|
|
||||||
|
app.patch('/api/devices/:id', (req, res, next) => {
|
||||||
|
let state = req.body.state.toLowerCase();
|
||||||
|
let device = devices.get(parseInt(req.params.id, 10));
|
||||||
|
|
||||||
|
if (!device) {
|
||||||
|
res.send(500, 'FAIL');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state === 'pause') {
|
||||||
|
playlist = [playlist[0], ...playlist];
|
||||||
|
device.player.pause((err, state) => {
|
||||||
|
console.log('Pause');
|
||||||
|
});
|
||||||
|
return res.send('PAUSED');
|
||||||
|
} else if (state === 'play') {
|
||||||
|
device.player.play((err, state) => {
|
||||||
|
console.log('Play');
|
||||||
|
});
|
||||||
|
return res.send('PLAY');
|
||||||
|
} else if (state === 'skip') {
|
||||||
|
playlist.splice(0, 1);
|
||||||
|
if (playlist.length > 0) {
|
||||||
|
device.player.load(playlist[0], { autoplay: true }, (err, state) => {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
res.send('SKIP');
|
||||||
|
writePlaylist();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post('/api/devices/:id/songs', (req, res, next) => {
|
||||||
|
let song = req.body.song;
|
||||||
|
let { player } = devices.get(parseInt(req.params.id, 10));
|
||||||
|
|
||||||
|
if (!song) {
|
||||||
|
res.send(400, 'Please submit a "song" post paramater');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
request.get(`https://api.spotify.com/v1/search?q=${querystring.escape(song)}&type=track&market=DE`, (err, data, body) => {
|
||||||
|
if (err || data.statusCode !== 200) {
|
||||||
|
// console.error(err, data);
|
||||||
|
res.send(500, 'FAIL');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
body = JSON.parse(body);
|
||||||
|
let track = body.tracks.items[0];
|
||||||
|
if (track) {
|
||||||
|
let id = track.id;
|
||||||
|
|
||||||
|
request.get(`https://api.spotify.com/v1/tracks/${id}`, (err, data, body) => {
|
||||||
|
if (err || data.statusCode !== 200) {
|
||||||
|
// console.error(err, data);
|
||||||
|
res.send(500, 'FAIL');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
body = JSON.parse(body);
|
||||||
|
|
||||||
|
if (body) {
|
||||||
|
let albumImage = body.album.images[0].url;
|
||||||
|
let title = body.name;
|
||||||
|
let artist = body.artists[0].name;
|
||||||
|
let url = body.preview_url;
|
||||||
|
|
||||||
|
let media = getMediaObject(title, artist, url, albumImage);
|
||||||
|
|
||||||
|
playlist.push(media);
|
||||||
|
console.log(playlist);
|
||||||
|
writePlaylist();
|
||||||
|
|
||||||
|
if (playlist.length === 1) {
|
||||||
|
player.load(media, { autoplay: true }, (err, status) => {
|
||||||
|
console.log('PLAY');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
res.send({albumImage, artist, title, url});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
app.listen(PORT, () => {
|
||||||
|
console.log(`Listening on port ${PORT}`);
|
||||||
|
});
|
16
package-lock.json
generated
16
package-lock.json
generated
@ -1548,6 +1548,22 @@
|
|||||||
"resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
|
||||||
"integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
|
"integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
|
||||||
},
|
},
|
||||||
|
"mdns": {
|
||||||
|
"version": "2.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mdns/-/mdns-2.5.1.tgz",
|
||||||
|
"integrity": "sha512-JglS7Ed3Yf0BCpyC7LXA1MUrumMV8jj4g67nT3+m886SFYllz2HWBg8ObywFXWbBSv5gW0meMOOS4vVa2jZGCw==",
|
||||||
|
"requires": {
|
||||||
|
"bindings": "~1.2.1",
|
||||||
|
"nan": "^2.14.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"bindings": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz",
|
||||||
|
"integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"media-typer": {
|
"media-typer": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
|
"castv2-client": "^1.2.0",
|
||||||
"chromecast-api": "^0.3.1",
|
"chromecast-api": "^0.3.1",
|
||||||
"cookie-parser": "~1.4.4",
|
"cookie-parser": "~1.4.4",
|
||||||
"debug": "~2.6.9",
|
"debug": "~2.6.9",
|
||||||
@ -18,6 +19,7 @@
|
|||||||
"fs": "0.0.1-security",
|
"fs": "0.0.1-security",
|
||||||
"http-errors": "~1.6.3",
|
"http-errors": "~1.6.3",
|
||||||
"inquirer": "^7.0.6",
|
"inquirer": "^7.0.6",
|
||||||
|
"mdns": "^2.5.1",
|
||||||
"morgan": "~1.9.1",
|
"morgan": "~1.9.1",
|
||||||
"net": "^1.0.2",
|
"net": "^1.0.2",
|
||||||
"path": "^0.12.7",
|
"path": "^0.12.7",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user