Resource icon

[Linux] [OSX] Essential Now Playing on Linux

NOTE: This was tested solely on Ubuntu 17.10, so though this can work on OSX, you will have to work out those details.

I really like to show the current song that is playing on my stream. Most of the music I listen to is on YouTube, so I would like to display the title of the video I'm listening to in my stream. I also strictly use Chrome. There used to be a really nice plugin called Untamed Now Playing which used Chrome's old NPAPI to write to a text file, but NPAPI has since been discontinued. If you are in the same boat as me, then this guide is for you. (Note that if you are using FireFox, there is already a plugin out there for you).

The plugin that exists now is called Essential Now Playing by singular1ty. Alas, the new protocol Chrome uses to transfer data from plugins requires a third-party application and ENP's application is written in C#. Fortunately, there is no need to go to wine, as the new protocol can be used by any platform.

Here's a super simple, fool-proof guide. Read this if you don't want to know or care about the details:

Obviously, you must have the Essential Now Playing companion plugin installed on Chrome. Make sure to go to chrome://extensions and enable developer mode. Then look under the ENP plugin and copy the extension ID to a file or somewhere where you can retrieve it later. The ID can be found as follows:

Screenshot from 2018-06-13 08-31-13.png


First of all, make sure nodejs and npm are installed. You can get both bundled here (or just google a tutorial, it's super simple). Determine which directory you want to have the text file output to and open a terminal shell there. Then run the following:

Bash:
npm install chrome-native-messaging
npm install write

Then create a .js file and take note of its name. Open it, and enter the following:

JavaScript:
#!/usr/local/bin/node

var fs = require('fs');
var writeFile = require('write');
var nativeMessage = require('chrome-native-messaging');

var input = new nativeMessage.Input();
var transform = new nativeMessage.Transform(messageHandler);
var output = new nativeMessage.Output();

process.stdin
    .pipe(input)
    .pipe(transform)
    .pipe(output)
    .pipe(process.stdout)
;

function messageHandler(msg, push, done) {
    writeFile('np.txt', msg.song + " | ", function(err) {});
    push(msg);
    done();
}

This will take in stdio from chrome and write them to a file in the same directory called "np.txt." It will also add a "|" separator character to the end. If you wish to change that then you should edit line 19 where it says

Code:
msg.song + " | "

Now that you have the js file, there is one last step, which is to create the manifest file. Create a new file and make sure it is named "com.flyinglawnmower.obsnp.json." Then enter the following in it:

JSON:
{
  "name": "com.flyinglawnmower.obsnp",
  "description": "Now Playing Helper",
  "path": "/PATH/TO/JSFILE.js",
  "type": "stdio",
  "allowed_origins": [
    "chrome-extension://ID/"
  ]
}

Replace "/PATH/TO/JSFILE.js" with the path to the .js file you created earlier, including the js file itself. Replace ID with the ID you found from earlier. (For me, it is aocghdlnkcebaipehcejjpeiijpdjldo. I'm not sure if its the same on every system?)

The final step is to move this file to the native messaging host directory, which is different for each operating system. Adhere to this link to determine the correct path (it's under the "Native Messaging Host Location" subheading). At the time of writing this guide, for OSX it is "~/Library/Application Support/Google/Chrome/NativeMessagingHosts/" and for Linux it is "~/.config/google-chrome/NativeMessagingHosts/."

Assuming everything went to plan, it should be working now! If you go to a youtube page, click the play button in the top right, and then click "Start," it should output to a text file in the same directory as the js file. You can then use the text file as input for the text object in OBS Studio. If it doesn't work, try opening a terminal in the directory you chose and running "node ./{jsfile}", replacing {jsfile} with the name of the js file. If there's an error then that is your problem! If not, try running the plugin while running the program in node.

Happy streaming!

For more experienced users:

The way the new Chrome protocol works is by stdio. The way Chrome is able to know what program to stdout/stdin to is by using a manifest file, the details about which can be found here. Note that when creating the manifest file, the name you choose for the file and the name you use in the manifest should be the same. Also, the name of the manifest is the port over which the plugin will output data.

The source code used by ENP specifically to parse the bytes can be found here. I would recommend using this code as your guide if you wish to create an app to deal with the input yourself. Keep in mind that the first four bytes are length information. Alternatively, you can use the chrome-native-messaging library on npm if you want to use node but don't want to deal with the bytes.

Of course, you could always use wine and run the native app. To me that seems needlessly inefficient for something as straight-forward as stdi/o, though.
Author
char
Views
3,750
First release
Last update
Rating
0.00 star(s) 0 ratings
Top