A personal music server
River is a personal music streaming server that is designed to be an alternative to proprietary streaming services. Users set up the River server on the computer where they store their music library, and stream their songs via client programs. Clients can be built by using the small JSON API provided by the server. Songs in the user's library can be streamed in the Ogg Opus or MP3 formats (note that all major browsers support at least one of these formats). When a stream is requested, songs are automatically transcoded to the requested format, if necessary.
River integrates with existing music libraries, so setting up River streams your music without interfering or conflicting with other tools. The server is designed to be simple to set up for anyone with basic knowledge of the command line who is capable of configuring dynamic DNS (or owns a static global IP).
go build
River calls ffmpeg
/avconv
and ffprobe
/avprobe
to transcode and read
audio files. If your operating system has a package manager, look for a package
called ffmpeg
or libav-tools
and install it. Otherwise, download an FFmpeg
build from the official website, and
either copy the ffmpeg
and ffprobe
executables to this directory, somewhere
in your system's PATH, or add the location of the executables to your system's
PATH. Windows and OS X (darwin
) releases come with the executables bundled,
as they lack an official package manager.
river [-cert file] [-key file] [-port port] directory
river serves the music in the given directory. The music can be accessed via a client on port 21313, or on the port named by the -port flag. If the -cert and -key flags are specified, river will listen for HTTPS connections; otherwise, river will listen for HTTP connections.
river-web is a browser-based River client.
Note that track and disc numbers should begin at 1
. Numbers lower than
1
indicate that the field is missing or should be treated as such.
All API methods besides OPTIONS
require basic authentication, where the
password matches the password given to the server by the user. Clients will need
to prompt the user for the password before accessing the API.
If you are building a browser client, note that direct src
links to the stream
URLs will not work due to the required authentication. You can use URL-based
basic authentication (protocol://:password@host...
) in src
attributes, but
this is unsupported in Internet Explorer and probably other browsers soon. You
can use URL.createObjectURL
in JavaScript instead, e.g.:
var audio = document.createElement("audio");
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var source = document.createElement("source");
source.src = URL.createObjectURL(xhr.response);
source.type = "audio/ogg";
audio.appendChild(source);
}
xhr.open("GET", "https://www.mydomain.com/songs/iswkgapo.opus");
xhr.responseType = "blob";
xhr.setRequestHeader("Authorization", "Basic " + btoa(":asanisimasa");
xhr.send();
However, this method requires the entire file to be downloaded before playback begins.
GET /songs
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"id": "iswkgapo",
"path": "Bob Dylan/Bringing It All Back Home/Mr. Tambourine Man.flac",
"time": "2015-05-28T10:06:04-08:00",
"artist": "Bob Dylan",
"album": "Bringing It All Back Home",
"disc": 2,
"track": 1,
"title": "Mr. Tambourine Man",
"fmt": "flac",
"codec": "flac"
},
{
"id": "wybtohyc",
"path": "Neutral Milk Hotel/In the Aeroplane over the Sea/Holland, 1945.flac",
"time": "2015-05-28T10:06:04-08:00",
"artist": "Neutral Milk Hotel",
"album": "In the Aeroplane over the Sea",
"disc": 0,
"track": 6,
"title": "Holland, 1945",
"fmt": "flac",
"codec": "flac"
}
]
GET /songs/wybtohyc
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "wybtohyc",
"path": "Neutral Milk Hotel/In the Aeroplane over the Sea/Holland, 1945.flac",
"time": "2015-05-28T10:06:04-08:00",
"artist": "Neutral Milk Hotel",
"album": "In the Aeroplane over the Sea",
"disc": 0,
"track": 6,
"title": "Holland, 1945",
"fmt": "flac",
"codec": "flac"
}
PUT /songs
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"id": "iswkgapo",
"path": "Bob Dylan/Bringing It All Back Home/Mr. Tambourine Man.flac",
"time": "2015-05-28T10:06:04-08:00",
"artist": "Bob Dylan",
"album": "Bringing It All Back Home",
"disc": 2,
"track": 1,
"title": "Mr. Tambourine Man",
"fmt": "flac",
"codec": "flac"
},
{
"id": "ihnqqjce",
"path": "Neutral Milk Hotel/Ferris Wheel on Fire/Home.flac",
"time": "2015-05-28T10:06:04-08:00",
"artist": "Neutral Milk Hotel",
"album": "Ferris Wheel on Fire",
"disc": 0,
"track": 3,
"title": "Home",
"fmt": "flac",
"codec": "flac"
},
{
"id": "wybtohyc",
"path": "Neutral Milk Hotel/In the Aeroplane over the Sea/Holland, 1945.flac",
"time": "2015-05-28T10:06:04-08:00",
"artist": "Neutral Milk Hotel",
"album": "In the Aeroplane over the Sea",
"disc": 0,
"track": 6,
"title": "Holland, 1945",
"fmt": "flac",
"codec": "flac"
}
]
GET /songs/wybtohyc.opus
HTTP/1.1 200 OK
Content-Type: audio/ogg
GET /songs/wybtohyc.mp3
HTTP/1.1 200 OK
Content-Type: audio/mpeg