Logo Computer scientist,
engineer, and educator
• Software • Utility corner

Kevin's Music Server for Android

Version 0.0.4.

What is this?

screenshot Kevin's Music Server for Android provides a web browser interface to control playback of audio files stored on relatively modern (4.x) Android devices. This allows the Android device to be used as a music server, in multi-room audio applications, among other things. It is a cut-down version of kmediad, which supports similar operations on Linux and Windows.

Audio tracks can be selected using a browser from a list of albums, or directly from the filesystem. You can restrict the album listing to particular genres or particular artists rather than displaying all albums on the same page. Album cover art images can be displayed (but see notes below about this.)


Features

  • Simple web interface — works on most desktop web browsers and many mobile browsers
  • Integrates with the Android media catalogue — browse by album, artist, genre, composer, or track
  • Supports file/folder browsing
  • Media catalogue text search
  • Equalizer
  • Cover art (both baked-in and album-folder images)
  • Playback control by headset or remote control

Installation

Download the APK package from the Downloads section at the end of this page, copy it to your Android device, and install it using any file manager. Or simply download the APK directly from this page using your device's Web browser. You may have to tell your device to allow non-market apps. Android Music Server won't ever be appearing on the Android Market, because I can't afford to pay Google to host stuff that I'm giving away for free. Alternatively, if you're worried that this app might transmit all your secret passwords to villains, you're welcome to inspect and build the application yourself (source code is also in the Downloads section), or from github.

Operation

screenshot This app is designed to run quietly in the background, so it has no substantive Android user interface. When you start it, if all is well you'll see the URL to which you should point your web browser. The Web server listens on port 30000 by default, but this can be changed from the settings page. If there are problems, which will generally be network-related, you'll see an error message. The app displays some information about the audio track that is currently playing, if there is one, and provides some buttons to control playback, in a rudimentary way. The "Shutdown" button shuts the application down completely, including its background service.

All real operation of the app is from a Web browser. I hope that the browser interface is relatively self-explanatory — just select an album from one of the various lists and click "Play now", or "Add" to append the tracks to the playlist. Alternatively, click the "Files" link at the bottom of the page and navigate the filesystem to find some audio files. Or just click "Random" to play a randomly-selected album.

You can operate Android Music Server using a web browser on the device itself (if the browser has adequate JavaScript support); but the app is really intended to be operated from a browser on a different machine. It is intended for remote control of music playback; there are many good media players for on-device operation.

Android Music Server responds to remote control events — from a bluetooth headset with control buttons, for example. In particular, it responds to play, pause, step, next track, and previous track events. Of course, for next track and previous track to work, there must be something in the playlist.

Notes

This application is intended to work with relatively modest collections of audio files, that are relatively tidily organized. All lists (of albums, artists, etc) are displayed on a single, possibly long page. In practice it seems to work reasonably well with collections of a few hundred albums, but the user interface will struggle with thousands of albums.

In general this app assumes (as Android generally does) that audio tracks are organized into albums, and that at least the album, title, and artist tags are filled in. To play an album in the right order it also assumes that the track number tag is filled in, or that the titles when arranged into alphabetical order will give the same ordering as the original album. Everything about this application will work somewhat better if files are thoroughly and consistently tagged — but that's true of most music players. I'm told that "free music downloaders" (bootlegging utilities, in other words) do not fill in tags properly, and you can end up with two thousand tracks in the same album, all called "null". If you sup with the Devil, as the saying goes, use a long spoon.

The web interface is completely stateless; that is, everything it needs to know is captured in the URL supplied by the browser. So you can freely bookmark albums, or artists, or filesystem locations.

When browsing the filesystem, you can add files one at a time to the playlist, or add the directory that contains them. The app will filter out playable audio files from other types, so it should be OK to click "Add" on a directory with mixed content. Note that the Add function in a directory only searches that specific directory — it won't descend into subdirectories.

There's no general agreement between Android device vendors about where media data gets stored. On most devices, internal storage will be in /sdcard/Music or /sdcard/Audio, but this is not universal. The filesystem location of external SD cards is even less standardized. On Samsung devices, /storage/exSdCard is a good place to start.

If you connect a Bluetooth audio device (e.g., headset) whilst this app is playing (through speaker or wired headphones), then audio should automatically be diverted to the headset. However, you might need to stop the app, or at least stop playback, to route audio back to the speaker. This slightly odd behaviour is, so far as I know, not a feature of this program — other Android media players behave the same way.

The browser interface updates every five seconds, so don't expect mouse-clicks to be reflected immediately in the browser (although, of course, they should have immediate effect on the audio). This five-second update time is to reduce load on the Android device.

If you click "Play now" on a track whilst an item in the playlist is being played, then playback will resume at the next playlist item when playback of the selected track finishes, if there is anything left to play in the playlist.

You can control the volume of playback by clicking on the loudspeaker buttons in the menu bar at the top of each page, or by going to the "Equalizer, etc" page from the home page, and tweaking the volume slider. If you're using a headset, that might have its own volume control and, if it does, it probably sets the volume on the headset itself, not on the device. So, in that case, to get full volume you probably need to turn up the volume both on the headset and in this application.

Browsing the filesystem will probably be completely useless if you're the kind of person who dumps thousands of music files into a single folder, and relies on the device to order them by tags. You'll just see a page listing thousands of files, and you won't be able to find anything. Browsing by album should still be fine (but see note below about cover art.)

Not a feature of this app, but it's helpful to know that some folders that contain media can be removed from the oversight of the Android media scanner by creating an empty file called .nomedia in those directories. This can be useful for preventing ringtones and the like from appearing in the album list; but bear in mind that this trick affects all apps that use the media scanner.

Cover art

If you choose to browse albums including covers, then the app will attempt to find some cover art to display. The places it looks are as follows.

First, the app will ask the Android media catalogue if any track in the specified album has an embedded image. If it does, then the first track that can provide an image does so. In practice, the Android media catalogue seems to be limited to returning "baked in" images, that is, images that are part of an ID3 tag or similar.

Second, the app will look in the directory that contains the track file, for an image file that looks like it might contain cover art. At present, it considers files names folder or cover, perhaps with a leading "." (hidden files), and with extensions jpg or png. These names are in lower-case only. Naturally, this process will only produce good results if folders contain tracks from the same album only.

The cover art extraction process is subject to a number of limitations.

  • Baked-in cover-art images can be quite large — perhaps even photo-sized. Returning all the images on a page containing, say, a list of two hundred albums is a challenge for an Android device. If the browser is also on a mobile device, then the challenge is compounded. The music server therefore attempts to avoid sending images if it can avoid doing so. It sets an Expires header one hour in the future for all images, and sets a Last-Modified header on all images based on the time the app starts up. In principle, therefore, the browser should not request images very frequently. But...
  • Mobile browsers in particular are often stupid when it comes to handling date headers. Many ignore them completely, and just blindly request all images in every page. Apart from choosing to browse without covers, there's little that can be done to avoid this problem, if you have a stupid browser.
  • We don't know the actual last-modified time of a baked-in cover image. The music server uses its start-up time as the modification baseline, lacking any better information. What this means is that if you restart the app whilst the browser still has images in its cache, the browser will get confused: because the image has a last-modified date in the future, but in the browser's cache it has not yet expired. Clearing the browser cache usually fixes this problem.

Genre support

Android Music Server provides a list of genres, to restrict the listing of albums to specific genres. Needless to say, for this to work the audio files must have valid genre tags.

Querying the Android media catalogue for genre information is excruciatingly slow. I believe that there is some problem with the internal search implementation, which seems to require the whole genre catalogue to be expanded into tracks and then a query run against each track. Whatever the reason, with large numbers of tracks (more than a few hundred) some short-cuts have to be taken. The application therefore assumes that each track in an album has the same genre and, when searching which albums match a genre, only the first track is checked. Of course, it's not all that unusual for different tracks to have different genres in the same album, but testing them all is simply unfeasibly slow.

Genres that have no associated tracks are silently ignored.

Artist support

When an entry is selected from the Artist list, any album that contains at least one track attributed to that artist is included in the album list. That is, an album doesn't have to be limited to a single artist to be included in that artist's listing.

It's not at all uncommon for an album to contain tracks by many different artists. If many albums are of that type, the artist list could be very long.

Playlist operations

On the Playlist page you can shuffle or clear the playlist, if it is not empty. Clicking either of the relevant links causes the page to refresh but, because the HTTP requests made using JavaScript are asynchronous, it can't be guaranteed that the playlist has changed on the server before the page is refreshed. You might need to refresh the page explicitly if changes to the playlist do not show up immediately.

Shuffling only changes the order in which items appear in the playlist — if something is playing when you shuffle, the change in ordering will only be apparent when that track is finished.

Settings

The settings page provides some modest control over operation of the app — the number of items displayed on each browser page, for example. There is no easy way to guess the appropriate settings — they depend on the capabilities of the Android device and of the web browser in use. If you are primarily interacting with the music server through a desktop browser, for example, you'll probably be able to set higher values of the number of items on each pag.

As with most Android settings pages, the changed settings take effect when you click the "back" button to get back to the main screen.

Search

There is a search box in the top menu bar. The music server does a very simple, case-insensitive search for the text string, which may appear anywhere in any album, artist, composer, or track title. The number of matches of each category (album, artist, etc) that are displayed on the results page can be controlled using the Settings page.

Android media catalogue issues

Android maintains a catalogue of media files and their metadata (tags). When a file is added using a USB connection, or presented to the device on an SD card or similar, Android reads the metadata and updates the catalogue. Android Music Server relies entirely on this catalogue for information about albums, artists, etc. Two problems affect this application's use of the media catalogue.

First, the application has to scan the catalogue to get lists of albums, artists, etc., for the display. This process is not usually very time-consuming, but not something that we want to do regularly. In principle, the music server could hook into the media scanner and rescan every time a file is added or deleted, but many files will be of no interest to the application (documents, pictures), and rescanning like this could be overzealous. Instead, there is a link on the home page 'Rescan the media catalog.' This will cause the music server to rebuild its own lists of albums, artists, etc., from Android's catalogue. Of course, you could just restart the app.

The second problem is that the media catalogue can sometimes get out-of-sync with the contents of storage. This isn't usually a problem with files added by USB, but can be a problem with files on removeable storage devices, and is particularly a problem if files are moved around using a general file manager (or, worse, at a command prompt, although most users probably won't do that).

The link 'Rescan the filesystem' will ask Android to start a complete rescan of the filesystem. Android is completely at liberty to ignore this request and, in later versions, is increasingly willing to. With Android 5, rebooting may be the only way to force a complete rescan. Note that the Music Server user interface will not wait for the rescan, and rescanning the filesystem does not imply rescanning the media catalogue (because we have no way to know when the filesystem rescan is finished, if it even started.)

Supported devices

Android Music Server is known to work on at least the following devices. Feel free to report others that work or don't work.
  • Google Nexus 7 second gen., with Android 4.4.4
  • Google Nexus 7 first gen., with Android 5.1.0
  • Samsung Galaxy S3, with Android 4.4.2
  • Samsung Note 3, with Android 4.4.2

Limitations

The are particular issues regarding the display of cover art: please see the section "Cover art" above.

Some Android devices are factory-configured to prevent any incoming network connection. Sorry but, without rooting the device, there's no way to change that, and this app simply won't work. Similarly, if your Android implementation shuts down the WiFi radio to save power when the screen blanks then, again, this app won't work.

Android Music Server relies heavily on JavaScript to create and manage its web user interface. Your browser needs decent JavaScript support — the browser on the android device itself might not be up to the job (but Chrome, at least, seems to work pretty well.)

Only WIFI operation is supported — you won't be able to connect to the app over a mobile network. Even if the app allowed this, most likely the service would not.

The app will not respond very well to changes in WIFI status — if you change access points, for example — and you'll probably need to restart it in such cases.

Android Music Server relies for its tag (e.g., album) support entirely on the Android media scanner. If this isn't working (which is relatively common), results will be variable. The app queries the media scanner when it starts, so media added after starting may not be visible (even if the scanner is working), unless you click the "Rescan media catalogue" link in the home page. Please see the section 'Android media catalogue issues' for more information.

One particular oddity of the Android media scanner is that it will sometimes present video files as 'Music,' presmumably because they have soundtracks. This app doesn't play video, so these entries in the album list are an irritation.

Whilst you can skip forward and back between tracks in the playlist, there is no general foward/rewind facility within a specific track. This is a tricky thing to implement within a web interface.

The app does not choose an open port for its built-in web server — this would be easy to implement, but users would probably prefer the port number to remain the same between sessions. If the port number clashes with something else, or is out of the permitted range, an error message should be displayed.

There is quite a subtle limitation inherent in the way Android audio works. Android Music Server registers itself to receive remote control events (e.g., from a headset), but only when audio is playing. So you can select play/pause, next track, and previous track, if your headset has buttons for these functions. However, if you do a "stop" operation (if your hardware supports it), you won't be able to start again, or use remote control at all, until you resume playback using the web interface. The reason this limitation exists is that the app is designed to run in the background, and perhaps be idle a lot of the time. If it took over the remote control when it was running, it would prevent other media apps using the remote control. There are, in fact, a number of popular media players that suffer from this exact problem, and it can be quite a nuisance.

This application is, in essence, an unsecured web server. It does allow people on the same WIFI network to browse the contents of the device's storage — at least those parts of it that contain audio. The application is not really intended for use in hostile environments.

The user interface is currently English-language only.

The part of Android Music Server that responds to HTTP requests and plays audio (i.e., most of it) is implemented as an Android background service. It is therefore less prone to automatic unloading than the user interface is. It's possible that Android might unload the user interface, whilst leaving the service running. This should be harmless, because when you restart the app, Android will not restart the service if it is still running. It's possible, in conditions of low memory, that Android will unload the service as well. In that case, Android is supposed to reload it when conditions improve, without user intervention. That process should also be transparent to the user except that, of course, whilst unloaded the service will not respond to HTTP requests. However, if the service is unloaded and reloading in this way, it will reinitialize, and the current playlist will be lost.

The Android API specifies an interface by which app can control audio equalizer settings, but manufacturers do not have to implement it in any useful way. That is, the controls may not be connected to anything. "Bass boost" is particularly flakey — on some devices it has an adjustable strength, on some it is just an on/off control, and on some it has no effect at all. Devices that provide their own, vendor-specific audio enhancers frequently do not implement the Android audio API at all. In any event, I am aware of few Android devices where the stock equalizer really works well. On some devices, I'm told that the equalizer API does not even initialize properly. This app attempts to prevent that state of affairs from stopping it even starting, but it make cause problems if the EQ page is requested by a browser later.

Albums and tracks that appear in the search results are displayed either with, or without cover art — the default is without. However, if you have recently browsed albums or tracks by cover, then covers will be included in search results as well.

Legal and copying

Android Music Server is open-source, and released under the terms of the GNU Public Licence, version 2.0. It contains components from a number of different authors. Please see the individual source files for detailed licencing and redistribution rights. Broadly, however, Android Music Server is free of charge and may be freely copied and distributed, so long as the original authors continue to be acknowledged.

I wrote Android Music Server server for my own use; I'm publishing it in case somebody else might get some benefit from it — even if it's only to look at the source code and see how not to write an Android app. It might work for you, it might not. If it doesn't, you're very welcome to fix it.

Revision history

0.0.4 April 18 2015 Added search facility, and preferences page
0.0.3 April 15 2015 Added on-device status display and controls, and equalizer page
0.0.2 April 12 2015 Added preliminary cover art, and genre/artist filtering support
0.0.1 April 3 2015 First release

Downloads

Source code
Android APK package
Copyright © 1994-2015 Kevin Boone. Updated Apr 22 2015