Skip to content

Commit

Permalink
Merge pull request #216 from feedbee/shared2
Browse files Browse the repository at this point in the history
Refactoring of shared.js: plugin-api.js proposal
  • Loading branch information
feedbee authored Oct 1, 2017
2 parents f666078 + 8a1041f commit cdfbe53
Show file tree
Hide file tree
Showing 68 changed files with 885 additions and 1,033 deletions.
78 changes: 63 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ Allows your keyboard media keys (play/pause, next, previous) to work
when you're listening to music on various streaming websites.

# Supported Sites

* 163 Music
* 22tracks
* 8tracks
* Amazon Cloud Player
* Bandcamp
Expand All @@ -22,53 +22,60 @@ when you're listening to music on various streaming websites.
* iloveradio.de
* Jamstash
* Jango.com
* JB Hi-Fi Now
* Livestream.com
* Mixcloud
* Music Choice
* Music Choice (untested)
* Myspace
* Myzuka.fm
* Naxos Music Library
* Netflix
* Noon Pacific
* Noon Pacific (untested)
* NRK Radio
* Ok.ru
* Overcast
* Overcast (untested)
* Pandora
* Phish Tracks
* Picarto.tv
* Plex
* Plex (untested)
* Pocketcasts.com
* Prostopleer
* Qobuz
* Rdio
* Relax-Hub.com
* Saavn.com
* Slacker
* Sirius XM Radio
* SomaFM
* Songza
* Soundcloud
* Sowndhaus
* Spotify
* Spreaker
* Streamsquid
* Subsonic (and Madsonic)
* Superplayer.fm
* Synology Audio Station v.5
* Superplayer.fm (untested)
* Synology Audio Station v.5 (untested)
* thesixtyone
* Tidal
* Tracksflow.com
* Tidal (untested)
* tunein.com
* Twitch.tv
* Ustream.tv
* vk.com (Vkontakte)
* XFINITY (untested)
* Xiami Music
* YouTube
* Zvooq
* Яндекс.Музыка (Yandex.Music)
* Яндекс.Радио (Yandex.Radio)

# Untested Sites (after latest changes)

* Music Choice (account is needed)
* Noon Pacific (account is needed)
* Overcast (account is needed)
* Plex (can't simulate click, not working)
* Superplayer.fm (regional restrictions)
* Synology (special environment is needed)
* Tidal (regional restrictions)
* XFINITY (account is needed)

# Usage

1. Install extension from the [chrome web store][crx].
Expand Down Expand Up @@ -112,8 +119,49 @@ document.addEventListener("MediaNext", function () {
});
```

# Please contribute!
# Please, contribute!

* Looking for plugins for other music players. Create Pull Requests to contribute. Create Issues to inform us about
broken sites (but PR is preferable).

Plugin creation is simple. If you have found a website with media content, that isn't supported by keysocket, just
write a plugin by yourself and create new Pull Request to share it with others. How to do it?

First of all, determine the fixed part of website's URL, where a media content is shown. In `extension/manifest.json`
add an item into `content_scripts` array like this:

```
{
"matches": ["*://example.com/player*"],
"js": ["plugin-api.js", "keysocket-example-service-name.js"]
},
```

Create new file into `extension` folder using the pattern `keysocket-example-service-name.js` (use your service name to
replace `example-service-name` part). Write plugin's code there. Check other plugins for examples.

Typically, plugin can interact with a player using either button press simulation or public API call. The second option
implies you writing custom JS code to talk to player, while the first one requires just to mention DOM selectors to
configure keysocket.

```javascript
keySocket.init('example-service-name', {
"play-pause": '...',
"prev": '...',
"next": '...',
"stop": '...'
});
```

In the code above two arguments were passed to `keySocket.init` function. The first argument is a plugin name, it used for
logging and can be anything you want. The second argument is a map used to bind keysocket events (which is caused by
user pressing control keys) to buttons or code, that handles this event. The events are `play-pause`, `prev`, `next`
and `stop`. Any of them can be omitted in the map.

So, passing a function as an event handler, you set the code, that will be called when event is thrown. Passing anything
else, which expected to be a string, you define DOM selector to look up for a DOM object to simulate click on it.

* Looking for adapters for other music players.
Different websites require different approaches to dial with them. So, make a research to find the best solution in
your case. Look through the other plugins (`extension/keysocket-*.js` files) for the reference.

[crx]: https://chrome.google.com/webstore/detail/fphfgdknbpakeedbaenojjdcdoajihik
19 changes: 8 additions & 11 deletions extension/keysocket-163.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
function onKeyPress(key) {
if (key === NEXT) {
var nextButton = document.querySelector('.m-playbar .nxt');
simulateClick(nextButton);
} else if (key === PLAY) {
var playPauseButton = document.querySelector('.m-playbar .ply');
simulateClick(playPauseButton);
} else if (key === PREV) {
var backButton = document.querySelector('.m-playbar .prv');
simulateClick(backButton);
keySocket.init(
"163",
{
"play-pause": ".m-playbar .ply",
"prev": ".m-playbar .prv",
"next": ".m-playbar .nxt"
// stop is omitted
}
}
);
19 changes: 8 additions & 11 deletions extension/keysocket-amazon-cloud-player.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
function onKeyPress(key) {
if (key === NEXT) {
var nextButton = document.querySelector('.button.icon-fastForward');
simulateClick(nextButton);
} else if (key === PLAY) {
var playPauseButton = document.querySelector(".button.playButton");
simulateClick(playPauseButton);
} else if (key === PREV) {
var backButton = document.querySelector('.button.icon-fastBackward');
simulateClick(backButton);
keySocket.init(
"amazon-cloud-player",
{
"play-pause": ".button.playButton",
"prev": ".button.icon-fastBackward",
"next": ".button.icon-fastForward"
// stop is omitted
}
}
);
20 changes: 8 additions & 12 deletions extension/keysocket-bandcamp.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
var playTarget = '.inline_player .playbutton';
var nextTarget = '.inline_player .nextbutton';
var prevTarget = '.inline_player .prevbutton';

function onKeyPress(key) {
if (key === PREV) {
simulateClick(document.querySelector(prevTarget));
} else if (key === NEXT) {
simulateClick(document.querySelector(nextTarget));
} else if (key === PLAY) {
simulateClick(document.querySelector(playTarget));
keySocket.init(
"bandcamp",
{
"play-pause": ".inline_player .playbutton",
"prev": ".inline_player .prevbutton",
"next": ".inline_player .nextbutton"
// stop is omitted
}
}
);
19 changes: 8 additions & 11 deletions extension/keysocket-birp.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
function onKeyPress(key) {
if (key === NEXT) {
var nextButton = document.getElementById('fap-next');
simulateClick(nextButton);
} else if (key === PLAY) {
var playPauseButton = document.getElementById('fap-play-pause');
simulateClick(playPauseButton);
} else if (key === PREV) {
var backButton = document.getElementById('fap-previous');
simulateClick(backButton);
keySocket.init(
"birp",
{
"play-pause": "#playbtn",
"prev": ".fa-fast-backward",
"next": ".fa-fast-forward"
// stop is omitted
}
}
);
12 changes: 0 additions & 12 deletions extension/keysocket-bop.js

This file was deleted.

19 changes: 8 additions & 11 deletions extension/keysocket-bugs.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
function onKeyPress(key) {
if (key === NEXT) {
var nextButton = document.getElementsByTagName('button')[4];
simulateClick(nextButton);
} else if (key === PLAY) {
var playPauseButton = document.getElementsByTagName('button')[3];
simulateClick(playPauseButton);
} else if (key === PREV) {
var backButton = document.getElementsByTagName('button')[2];
simulateClick(backButton);
keySocket.init(
"bugs",
{
"play-pause": ".btnPlay > button, .btnStop > button",
"prev": ".btnPrev > button",
"next": ".btnNext > button"
// stop is omitted
}
}
);
26 changes: 16 additions & 10 deletions extension/keysocket-builtin-player.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
function onKeyPress(key) {
var videoElement = document.getElementsByTagName("video")[0];

if (key === PLAY) {
if (videoElement.paused) {
videoElement.play();
}
else {
videoElement.pause();
keySocket.init(
"builtin-player",
{
"play-pause": function () {
var videoElement = document.getElementsByTagName("video")[0];

if (videoElement.paused) {
videoElement.play();
}
else {
videoElement.pause();
}
}
// prev is skipped
// next is skipped
// stop is omitted
}
}
);
44 changes: 8 additions & 36 deletions extension/keysocket-deezer.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,9 @@
function onKeyPress(key) {
if (document.getElementById('player_control_play')) { // old deezer style
if (key === NEXT) {
var nextButton = document.getElementById('player_control_next');
simulateClick(nextButton);
} else if (key === PLAY) {
var isPlaying = document.getElementById('player_control_play').style.display === 'none';
var playPauseButton = null;
if (isPlaying) {
playPauseButton = document.getElementById('player_control_pause');
} else {
playPauseButton = document.getElementById('player_control_play');
}
simulateClick(playPauseButton);
} else if (key === PREV) {
var backButton = document.getElementById('player_control_prev');
simulateClick(backButton);
}
} else { // new deezer style
if (key === NEXT) {
var nextButton = document.getElementsByClassName('control-next')[0];
simulateClick(nextButton);
} else if (key === PLAY) {
var isPlaying = document.getElementsByClassName('control-play')[0] ? false : true;
var playPauseButton = null;
if (isPlaying) {
playPauseButton = document.getElementsByClassName('control-pause')[0];
} else {
playPauseButton = document.getElementsByClassName('control-play')[0];
}
simulateClick(playPauseButton);
} else if (key === PREV) {
var backButton = document.getElementsByClassName('control-prev')[0];
simulateClick(backButton);
}
keySocket.init(
"deezer",
{
"play-pause": ".control-play, .control-pause",
"prev": ".control-prev",
"next": ".control-next"
// stop is omitted
}
}
);
13 changes: 8 additions & 5 deletions extension/keysocket-digitallyimported.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
function onKeyPress(key) {
if (key === PLAY) {
var playPauseButton = document.querySelector('#webplayer-region .controls a:first-child');
simulateClick(playPauseButton);
keySocket.init(
"digitallyimported",
{
"play-pause": "#webplayer-region .controls a:first-child"
// prev is skipped
// next is skipped
// stop is omitted
}
}
);
Loading

0 comments on commit cdfbe53

Please sign in to comment.