Git Product home page Git Product logo

streamkeys's Introduction

Streamkeys v1.8.4 Build Status

Chrome extension to send "global" (ie. across the browser) hotkeys to various online media players.

It is available on the Chrome Store:

https://chrome.google.com/webstore/detail/streamkeys/ekpipjofdicppbepocohdlgenahaneen?hl=en

Installation

Requirements

  • Node.js

Install

Clone the repo and then install dependencies:

$ npm install

Then to build the extension in watch mode, run:

$ npm run develop

In Chrome, load the unpacked extension from build/unpacked-dev/.

NPM Scripts

  • npm test: Run unit tests.

  • npm run develop: Lints code/*, runs browserify, copies built code to build/unpacked-dev/ and test/streamkeys-ext/ in watch mode

  • npm run grunt:dev: Lints code/*, runs browserify and copies built code to build/unpacked-dev/ and test/streamkeys-ext/

  • npm run grunt:rel: Lints code/*, runs browserify and uglify and copies built code to build/unpacked-prod/ and test/streamkeys-ext/

  • npm run grunt:watch: Watches for changes to JS files in code/*, lints code/*, runs browserify and copies built code to build/unpacked-dev/

  • npm run grunt:lint: Lints code/*

Info

This extension works by sending click events to the elements that control the music player. Each music site has an associated controller which contains the css selectors for the play/pause/next/previous/mute buttons (where available). In addition there is a BaseController module which contains common functions that are shared across all controllers.

The background script routes hotkey presses from the user to the correct tab (ie., the media player(s) tab) if the media player site is enabled.

Adding Sites

Adding a new site to the extension is straight forward. There are 3 steps:

1. Add site controller

Figure out the css selectors for a site's media player buttons and create a new controller in code/js/controllers/. Naming scheme is {Sitename}Controller.js. You should copy code from an exisiting controller as a template. Here is an example controller for Fooplayer:

Filename: FooplayerController.js

"use strict";
(function() {
  var BaseController = require("BaseController");

  new BaseController({
    playPause: "#play_btn",
    playNext: "#next_btn",
    playPrev: "#prev_btn",
    mute: "#mute_btn",

    playState: "#play_btn.playing",
    song: "#song",
    artist: "#artist"
  });
})();
Special controller properties:
  • buttonSwitch - Used to determine playing state. Set to true if a site only shows the pause button when it's playing and only shows the play button when it's paused.
  • playState - Used to determine playing state. Set to the selector that will return true if the player is playing. Example: playState: "#play_btn.playing"
  • iframe - Used when the player is nested inside an iframe. Set to the selector of the iframe containing the player. Example: iframe: "#player-frame"

Note: One of buttonSwitch or playState should (almost) always be set. If buttonSwitch is true then your controller must define both play and pause selectors. If a playState is defined, then you controller might have either a single playPause selector or both play and pause selectors.

2. Add site to sitelist

Next, add the site to the Sitelist object in code/js/modules/Sitelist.js.

"fooplay": { name: "Fooplay", url: "http://www.fooplayer.com" }

The object key name is very important. It serves two purposes: constructs the site's controller name as well as builds the regular expression which will be used to check URLs to inject the controller into. It is important that the url is correct, and that the object's key name is contained in the URL.

If it is not possible for the object's key name to be part of the sites URL then you can add the optional alias array field to the object which will add the array's contents into the regular expression to match URLs. For example, for lastFM:

"last": { name: "LastFm", url: "http://www.last.fm", controller: "LastfmController.js", alias: ["lastfm"] }

the alias here will match URLs: last.* AND lastfm.*

The logic to construct the controller name is: Capitalized object key + "Controller". So, using the above example we should name our LastFM controller: "LastController" based on that key name.

If it is not possible for the controller file to be named according to that scheme then add the optional controller property to the site object and put the FULL controller name there, for example: "SonyMusicUnlimitedController.js"

Tests

There is a Karma test suite that simulates core extension functionality. The automated Travis-CI will trigger on every pull request/push.

To run the tests locally, simply

$ npm test

Linux MPRIS support

On Linux you can enable basic MPRIS support in options. Currently, this requires single player mode to be enabled. It requires an extra host script to be installed. The host script currently supports Chromium, Google Chrome and Brave.

Install host script

To install the host script, run the following commands:

$ extension_id="ekpipjofdicppbepocohdlgenahaneen"
$ installer=$(find $HOME/.config -name "mpris_host_setup.py" | grep ${extension_id})
$ python3 "${installer}" install ${extension_id}

A restart of the browser is necessary to load the changes.

Uninstall host script

To uninstall the host script, run the following commands:

$ extension_id="ekpipjofdicppbepocohdlgenahaneen"
$ installer=$(find $HOME/.config -name "mpris_host_setup.py" | grep ${extension_id})
$ python3 "${installer}" uninstall

License (MIT)

Copyright (c) 2018 Alex Gabriel under the MIT license.

streamkeys's People

Contributors

alextsits avatar berrberr avatar brandonjyuhas avatar bsinky avatar d3vr avatar dependabot-preview[bot] avatar dependabot[bot] avatar dr-nyt avatar garethblain avatar inverse avatar joepvl avatar jppitz avatar lalwanivikas avatar lentinj avatar miklosme avatar milushov avatar nemchik avatar ovcharik avatar pwnb0t avatar realdubb avatar rorgy avatar sab666 avatar shayneholmes avatar shuuji3 avatar sstgithub avatar taschmidt avatar timdorr avatar tobeorla avatar waldfee avatar y-gagar1n avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

streamkeys's Issues

Youtube playlist issues

Hello,

I installed Streamkeys today and tried to play a youtube playlist, for instance:
https://www.youtube.com/watch?v=N7ys8qVZwAk&list=PLzyYbaYKbahmvcGjNg1Ak9vvmrhr_0Ogo

I tried using my Mac keyboard to go to next or previous song (ie f5 and f7 keys), but nothing happened.. I opened my console and got this error:

STREAMKEYS-ERROR: Element not found for click.

My UA-string is:

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36

Perhaps there is a bug in the controller to handle Youtube?

  • Marinus

Deezer doesn't work

Maybe they changed their website, because it is in the supported list, but media controls do not work.

add minimalistic ui

Could I interest you in adding a minimalistic ui similar to Grooveshark Control? Mostly I'm just interested in a clickable pause & skip buttons rather than just keyboard shortcuts. Like & dislike buttons for the radio would be nice also.

Fix Jango pause selector

Jango pause selector should be #btn-playpause instead of #btn-playPause

The button is located inside an iframe document.querySelector('[name=content]').contentDocument.querySelector(query_selector);

Using 100% CPU

Since the last major update (1.4? not sure) the extension has a bug that often makes it use 100% CPU. Probably an endless loop.

I often have a plex tab open, not sure if it's specific to that.

I will try to debug and find a way to reproduce, but I thought I would first open a ticket so others people can contribute.

Hooking up controllers to jshint

Shall we hook up the controllers to jshint (within Gruntfile.js)? the main problem that I can see is the exposing of objects for example BaseController as a dependency. This could be achieved through AMD.

Fix slacker

Slacker has a new site with different selectors.

Tagging releases

Might be nice tagging releases for a clearer indication of what commits are in what release on the app store.

Default Hotkeys

I don't use the default hotkey settings, and it reverts do default every time the extension is updated. Is there any way to prevent this?

Blocks default system media key commands

First off, I've been waiting a while for an extension that works as flawlessly as this one! Thanks a ton for all your work :)

More often than not I'm listening to Spotify and this extension works perfectly. However, if I'm listening to music in a local music player app (ex. media player, winamp, itunes) and I have Chrome open my media key command never seem to make it to the app.

debounce between actions

Hi!
I like your work, but have few issues:)

I am using Google music as music service and it allow to use the "google music app" (chrome app). Correct me if I wrong, but there is two music tabs when "music app" lunched, and when I trying to pause the song with hotkey I can hear small pause(interruption), but music continues.
Sound like I quickly pressed "pause" button for two times.

Sometimes I had reproduce this but on vk.com but I have not strict flow to describe it better. It could be related to what I described above.

Anyway, I think, that simple debounce between action will be enough to prevent this.

Tnx!

Forward event to system if no applicable player in browser

I pefer the dedicated desktop app for Spotify, but Soundcloud doesn't have one for Windows, so I have to use that in the browser.
I'd like to use the same keys for both.

If I disable sreamkeys, I can control spotify from the keyboard.
If I enable streamkeys, it seems to gobble up the events even if I have no players open in chrome, so Spotify doensn't respond.

Oddly, it seemed to work the way I want when I first installed the plugin, but not after rebooting.

Ability to disable supported sites and/or adding sites priorities

The situation I have:

I've got vk.com open for all of the time, also I've got google music open. I don't use vk for music, but I obviously do use gmusic =) So the problem's that when I press the hotkey both of them start playing simultaneously.

What I suggest is to add the possibility to disable controls for certain sites or maybe to assign them priorities like if several supported sites found open - use the one with the highest priority unless some tab with supported site is focused (use the focused tab then)

Hope I could explain it =)

UPD: well I've found a way to access options.html but it seems to be outdated and unused

Add support for mutual exclusion

An extension I used to use had the feature that when one media source was playing and another one started, the new one would pause the old one. I would really like this feature, and I may even do a PR for it.

Slacker Next Song broken

I'm not able to get the 'Next Song' to work with Slacker. I have it bound to a custom hotkey (tried several different keys with no luck). But the 'Play/Pause' is working with Slacker, and with Pandora both work.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.