Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

spotify-connect-ws

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

spotify-connect-ws - npm Package Compare versions

Comparing version 0.0.2 to 0.1.0

.npmignore

12

package.json
{
"name": "spotify-connect-ws",
"version": "0.0.2",
"version": "0.1.0",
"description": "A WebSockets solution for Spotify's Connect API made using socket.io.",
"main": "index.js",
"main": "lib",
"module": "lib/index.js",
"author": "Lawrence Holmes",

@@ -10,7 +11,6 @@ "license": "MIT",

"lint": "eslint .",
"build": "yarn lint && babel -d ./build ./src"
"build": "yarn lint && babel -d ./lib ./src",
"watch": "babel -d ./lib ./src --watch"
},
"dependencies": {
"babel-core": "^6.26.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"node-fetch": "^1.7.3"

@@ -20,2 +20,4 @@ },

"babel-cli": "^6.26.0",
"babel-core": "^6.26.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-env": "^1.6.1",

@@ -22,0 +24,0 @@ "eslint": "^4.10.0",

@@ -8,3 +8,3 @@ WebSockets for Spotify Connect API

It should be noted that this project does not fully solve the problems discussed in [this issue](#), in that there is still polling taking place (one request per second right now) and therefore hitting rate limits is a possibility.
It should be noted that this project does not fully solve the problems discussed in [this issue](https://github.com/spotify/web-api/issues/492), in that there is still polling taking place (one request per second right now) and therefore hitting rate limits is a possibility.

@@ -17,2 +17,4 @@ ### Important Note

If you want to skip the server setup and go straight to working with your app, use this testing url in the meantime: https://spotify-connect-ws.herokuapp.com/connect
Server:

@@ -48,2 +50,4 @@ ```bash

const io = openSocket('/connect')
// or if using testing url
const io = openSocket('https://spotify-connect-ws.herokuapp.com/connect')

@@ -50,0 +54,0 @@ io.emit('initiate', { accessToken: 'access token' })

@@ -1,3 +0,1 @@

require('babel-core/register')
module.exports = require('./socket')

@@ -13,3 +13,6 @@ import {

const C = {
CONNECT_ERROR: 'connect_error'
CONNECT_ERROR: 'connect_error',
HAS_SCRUBBED_THRESHOLD: 1500,
HAS_FINISHED_THRESHOLD: 2000,
POLL_RATE: 1000
}

@@ -30,2 +33,12 @@

const handleError = error => {
const message = error.message || error
if (message !== socket.lastSentError) {
socket.emit(C.CONNECT_ERROR, error)
socket.lastSentError = message
} else {
socket.pollRate = socket.pollRate < 5000 ? socket.pollRate + 1000 : 5000
}
}
socket.on('disconnect', () => {

@@ -43,79 +56,87 @@ clearInterval(socket.poll)

if (accessToken) {
socket.accessToken = accessToken
}
socket.accessToken = accessToken
socket.poll()
})
socket.poll = () => {
getPlayerState(socket.accessToken)
.then(playerState => {
socket.emit('initial_state', playerState)
socket.playerState = playerState
socket.poll = setInterval(() => {
getPlayerState(socket.accessToken).then(playerState => {
if (playerState.item.id !== socket.playerState.item.id) {
// track has changed
socket.emit('track_change', playerState.item)
socket.hasNotifiedTrackEnd = false
} else {
// track is the same, check if it has been scrubbed
if (playerState.is_playing) {
const negativeProgress =
playerState.progress_ms >
socket.playerState.progress_ms + 1500
const positiveProgess =
playerState.progress_ms <
socket.playerState.progress_ms - 1500
if (negativeProgress || positiveProgess) {
socket.emit(
'seek',
playerState.progress_ms,
playerState.timestamp
)
}
}
}
if (playerState.is_playing !== socket.playerState.is_playing) {
// play state has changed
const event = playerState.is_playing
? 'playback_started'
: 'playback_paused'
socket.emit(event)
}
if (playerState.device.id !== socket.playerState.device.id) {
// device has changed
socket.emit('device_change', playerState.device)
} else {
// device is the same, check volume
if (
playerState.device.volume_percent !==
socket.playerState.device.volume_percent
) {
// device has changed
socket.emit('volume_change', playerState.device.volume_percent)
}
}
if (!playerState.device) {
handleError('No active device')
return
}
if (!socket.hasSentInitialState) {
socket.emit('initial_state', playerState)
socket.playerState = playerState
socket.hasSentInitialState = true
return
}
if (
!socket.hasNotifiedTrackEnd &&
playerState.progress_ms + 2000 > playerState.item.duration_ms
) {
socket.emit('track_end', playerState.item)
socket.hasNotifiedTrackEnd = true
// reset poll rate if no errors were encountered
socket.pollRate = C.POLL_RATE
if (playerState.item.id !== socket.playerState.item.id) {
// track has changed
socket.emit('track_change', playerState.item)
socket.hasNotifiedTrackEnd = false
} else {
// track is the same, check if it has been scrubbed
if (playerState.is_playing) {
const negativeProgress =
playerState.progress_ms >
socket.playerState.progress_ms + C.HAS_SCRUBBED_THRESHOLD
const positiveProgess =
playerState.progress_ms <
socket.playerState.progress_ms - C.HAS_SCRUBBED_THRESHOLD
if (negativeProgress || positiveProgess) {
socket.emit(
'seek',
playerState.progress_ms,
playerState.timestamp
)
}
}
}
if (playerState.is_playing !== socket.playerState.is_playing) {
// play state has changed
const event = playerState.is_playing
? 'playback_started'
: 'playback_paused'
socket.emit(event)
}
if (playerState.device.id !== socket.playerState.device.id) {
// device has changed
socket.emit('device_change', playerState.device)
} else {
// device is the same, check volume
if (
playerState.device.volume_percent !==
socket.playerState.device.volume_percent
) {
// volume has changed
socket.emit('volume_change', playerState.device.volume_percent)
}
}
socket.playerState = playerState
})
}, 1000)
if (
!socket.hasNotifiedTrackEnd &&
playerState.progress_ms + C.HAS_FINISHED_THRESHOLD >
playerState.item.duration_ms
) {
socket.emit('track_end', playerState.item)
socket.hasNotifiedTrackEnd = true
}
socket.playerState = playerState
})
.catch(e => socket.emit(C.CONNECT_ERROR, e))
})
.catch(handleError)
setTimeout(socket.poll, socket.pollRate)
}
socket.on('play', track => {
if (track) {
playTrack(socket.accessToken, track).catch(e =>
socket.emit(C.CONNECT_ERROR, e)
)
playTrack(socket.accessToken, track).catch(handleError)
} else {
setPlayState(socket.accessToken, 'play').catch(e =>
socket.emit(C.CONNECT_ERROR, e)
)
setPlayState(socket.accessToken, 'play').catch(handleError)
}

@@ -125,23 +146,15 @@ })

socket.on('resume', () => {
setPlayState(socket.accessToken, 'play').catch(e =>
socket.emit(C.CONNECT_ERROR, e)
)
setPlayState(socket.accessToken, 'play').catch(handleError)
})
socket.on('pause', () => {
setPlayState(socket.accessToken, 'pause').catch(e =>
socket.emit(C.CONNECT_ERROR, e)
)
setPlayState(socket.accessToken, 'pause').catch(handleError)
})
socket.on('seek', positionMs => {
seek(socket.accessToken, positionMs).catch(e =>
socket.emit(C.CONNECT_ERROR, e)
)
seek(socket.accessToken, positionMs).catch(handleError)
})
socket.on('set_volume', volumePercent => {
setVolume(socket.accessToken, volumePercent).catch(e =>
socket.emit(C.CONNECT_ERROR, e)
)
setVolume(socket.accessToken, volumePercent).catch(handleError)
})

@@ -154,11 +167,7 @@

socket.on('previous_track', () => {
previousTrack(socket.accessToken).catch(e =>
socket.emit(C.CONNECT_ERROR, e)
)
previousTrack(socket.accessToken).catch(handleError)
})
socket.on('transfer_playback', device => {
transferPlayback(socket.accessToken, device).catch(e =>
socket.emit(C.CONNECT_ERROR, e)
)
transferPlayback(socket.accessToken, device).catch(handleError)
})

@@ -165,0 +174,0 @@

@@ -13,2 +13,8 @@ import fetch from 'node-fetch'

})
.then(response => {
if (response.status === 202) {
return resolve({})
}
return response
})
.then(r => r.json())

@@ -15,0 +21,0 @@ .then(response => {

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc