What's up, it's been a while since I've posted! I'm excited about this one and I'm glad that you're here. :) I'm going to be building a SoundCloud music player using Node.js. This project's code can be found in my SweetCode repository alongside other code.
Contents
There are three main sections in this post. Following the post will walk you through the entire journey of building the SoundCloud music player - from setting up the 'Hello, world' server to changing the volume of the player:
- Hello, SoundCloud Player
- Playing Music
- Adding Functionality
Hello, SoundCloud Player
Creating the App
Let's start it off by making our server.js file. This is going to be our Node.js server, and it can stay simple for this project because a lot of the work will be done on the client-side. For this app, I'm going to be using Express as our minimalist server framework, and EJS as our view engine. If you're unfamiliar with setting up/running a Node.js server up, check this post out.
server.js -
var express = require('express');
var app = require('express')();
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.static('public'));
app.get('/', function (req, res) {
res.render("client");
});
app.listen(5000, function () {
console.log('listening on *:5000');
});
Structuring the App
As you can see in our first route, we're going to be rendering client. "Client" is actually our .ejs file that is going to live in a folder called views. We've also got a public folder, this is where most of our JavaScript will live. Here is what the current folder structure looks like:
Whenever I am starting work on a new project, I like to start simple and figure out what to focus on first. This project is mostly about making the browser play music from SoundCloud, so I want to keep the view as simple as possible for now. Let's set up our client.ejs file with a simple play button (this will give us a button to set the set up of our music player, it does nothing for now!).
client.ejs -
<body>
<button>Play</button>
</body>
Playing Music
Understanding NPM Packages and Bundling
Okay so we're to the cool part! But how are we going to do this, what are we going to use? Well, we could use the vanilla SoundCloud API or we could search for some sort of wrapper package that someone has made for the SoundCloud API. I think I'm going to use this soundcloud-audio npm package written by Dmitri Voronianski, it seems solid and it's got good documentation to get us going.
Since this npm package is written for the server-side, we're going to have to use some sort of bundler to allow us to use it on the client-side (the browser). You can find an explanation for this here. The bundler I am going to use is Browserify.
Writing the Player
Let's write our player.js file and then I'll show you how to bundle it and use it with your play button. Inside of our public folder, let's create our player.js. For this example, I'm going to be using this mix by Biskwiq.
In player.js let's first require our soundcloud-audio package and create our player. Creating the player requires you to use your own client id (I have scraped one from the web that you can use!)
EDIT: This key no longer works, you will need to find another!
We can give the window a function called play in which the player will call its resolve function with the link to the desired SoundCloud song.
player.js -
const SoundCloudAudio = require('soundcloud-audio');
const player = new SoundCloudAudio('95f22ed54a5c297b1c41f72d713623ef');
window.play = function () {
player.resolve("https://soundcloud.com/biskwiq/dawntheopus", function (track) {
player.play();
});
}
Sweet, now all we have to do is include this script to our client.ejs file and assign it to the play button like so:
<script src="player-bundle.js"></script>
<body>
<button onclick="play()">Play</button>
</body>
Oh wait! That's player-bundle.js, not player.js. We need to make this bundle file so that we can use this player on the client-side. Download Browserify by running this command in the root of your project:
npm install --save browserify
Don't forget to use --save with your installs! Your packages need to be saved with your local node modules, rather than globally, to be bundled.
Now we can bundle the player.js by running the following command:
browserify public/player.js -o public/player-bundle.js
This will tell browserify to take the player.js file and bundle it up and throw its output into the same folder with the name player-bundle.js. Whenever we make a change to the player.js we need to rebundle it with this command. Running this command again will overwrite the bundle file without prompting.
Sweet! The play button now streams that song! NOTE: The volume will be high as we have not touched that setting yet. :)
Adding Functionality
So it plays music, but it doesn't do much else yet. I definitely expect a music player to have a pause button, and be able to change the volume. Let's do it! I'm first going to give my client.ejs the buttons:
client.ejs -
<script src="player-bundle.js"></script>
<body>
<button onclick="play()">Play</button>
<button onclick="pause()">Pause</button>
Volume: <input type="range" min="0" max="100" value="80" class="slider" id="volume-range">
</body>
First, let's implement the pause function for the player since we're referencing it in the onclick but it's not actually defined yet. It's very easy, the function we want to use is already on the player constant we made:
player.js -
const SoundCloudAudio = require('soundcloud-audio');
const player = new SoundCloudAudio('95f22ed54a5c297b1c41f72d713623ef');
window.play = function () {
player.resolve("https://soundcloud.com/biskwiq/dawntheopus", function (track) {
player.play();
});
}
window.pause = function () {
player.pause();
}
Don't forget to rebundle your player.js file!!
Bam, the song pauses! Now let's get that volume control working so that we don't blow our ears off again. Our player is going to need to know what volume level to set the volume to, so let's make a function that takes a level. Note that this level needs to be a decimal, we'll be passing in a whole number then dividing it by 100 so that it's in decimal form for the player's setVolume function.
player.js -
const SoundCloudAudio = require('soundcloud-audio');
const player = new SoundCloudAudio('95f22ed54a5c297b1c41f72d713623ef');
window.play = function () {
player.resolve("https://soundcloud.com/biskwiq/dawntheopus", function (track) {
player.play();
});
}
window.pause = function () {
player.pause();
}
window.setVolume = function (level) {
level = level / 100;
player.setVolume(level);
}
Since we're not using a button for the volume, we can't use an onclick. What we can do is get the "volume-range* control and call the setVolume function whenever it the control gets input.
client.ejs -
<script src="player-bundle.js"></script>
<body>
<button onclick="play()">Play</button>
<button onclick="pause()">Pause</button>
Volume: <input type="range" min="0" max="100" value="80" class="slider" id="volume-range">
</body>
<script>
var volume = document.getElementById("volume-range");
volume.oninput = function () {
setVolume(this.value);
}
</script>
Review
If you followed along with me, congrats! You just made a SoundCloud music player. You used an Express Node.js server to serve a bundled npm package that wraps functionality for the SoundCloud API. If you want to continue development on this project, I've got a few suggestions:
- Add a timeline for the song so that the user can change the time of the song.
- Add some styling so that the player looks better!
- Add a queue so that the user can add songs to be played next (also add a next button).
- Show the currently playing song's cover art, title, and artist name.
- Make it so that the player is shared across web browsers (if one user plays, skips, etc. then that function also happens for other users on the site). Look into socket.io.
Thanks for sticking around until the end. If you've got any questions feel free to comment/message me directly here, or on my socials: @rhenness & @ryhenness most places. :)
If you liked this post, you might also like Make a Node.js Twitter Bot: Bogus Definition.
Top comments (0)