{"id":13850344,"url":"https://github.com/wwalexander/river","last_synced_at":"2026-01-21T22:36:23.887Z","repository":{"id":34106214,"uuid":"37934253","full_name":"wwalexander/river","owner":"wwalexander","description":"A personal music server","archived":false,"fork":false,"pushed_at":"2018-03-12T01:22:43.000Z","size":2727,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-07-12T21:37:44.381Z","etag":null,"topics":["ffmpeg","mp3","music","opus","stream"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wwalexander.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-06-23T17:35:58.000Z","updated_at":"2021-08-04T02:20:05.000Z","dependencies_parsed_at":"2022-07-29T20:09:58.707Z","dependency_job_id":null,"html_url":"https://github.com/wwalexander/river","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/wwalexander/river","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wwalexander%2Friver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wwalexander%2Friver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wwalexander%2Friver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wwalexander%2Friver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wwalexander","download_url":"https://codeload.github.com/wwalexander/river/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wwalexander%2Friver/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28645550,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-21T21:29:11.980Z","status":"ssl_error","status_checked_at":"2026-01-21T21:24:31.872Z","response_time":86,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ffmpeg","mp3","music","opus","stream"],"created_at":"2024-08-04T20:01:07.409Z","updated_at":"2026-01-21T22:36:23.871Z","avatar_url":"https://github.com/wwalexander.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"river\n=====\n\nA personal music server\n\nAbout\n-----\n\nRiver is a personal music streaming server that is designed to be an alternative\nto proprietary streaming services. Users set up the River server on the computer\nwhere they store their music library, and stream their songs via client\nprograms. Clients can be built by using the small JSON API provided by the\nserver. Songs in the user's library can be streamed in the Ogg Opus or MP3\nformats (note that [all major browsers support at least one of these\nformats](https://en.wikipedia.org/wiki/HTML5_Audio#Supported_browsers_2)).\nWhen a stream is requested, songs are automatically transcoded to the requested\nformat, if necessary.\n\nRiver integrates with existing music libraries, so setting up River streams your\nmusic without interfering or conflicting with other tools. The server is\ndesigned to be simple to set up for anyone with basic knowledge of the command\nline who is capable of configuring dynamic DNS (or owns a static global IP).\n\nBuilding\n--------\n\n    go build\n\n### FFmpeg/LibAV\n\nRiver calls `ffmpeg`/`avconv` and `ffprobe`/`avprobe` to transcode and read\naudio files. If your operating system has a package manager, look for a package\ncalled `ffmpeg` or `libav-tools` and install it. Otherwise, download an FFmpeg\nbuild from [the official website](https://www.ffmpeg.org/download.html), and\neither copy the `ffmpeg` and `ffprobe` executables to this directory, somewhere\nin your system's PATH, or add the location of the executables to your system's\nPATH. Windows and OS X (`darwin`) releases come with the executables bundled,\nas they lack an official package manager.\n\nUsage\n-----\n\n    river [-cert file] [-key file] [-port port] directory\n\nriver serves the music in the given directory. The music can be accessed via a\nclient on port 21313, or on the port named by the -port flag. If the -cert and\n-key flags are specified, river will listen for HTTPS connections; otherwise,\nriver will listen for HTTP connections.\n\n[river-web](https://github.com/wwalexander/river-web) is a browser-based River\nclient.\n\n### API\n\nNote that track and disc numbers should begin at `1`. Numbers lower than\n`1` indicate that the field is missing or should be treated as such.\n\nAll API methods besides `OPTIONS` require basic authentication, where the\npassword matches the password given to the server by the user. Clients will need\nto prompt the user for the password before accessing the API.\n\nIf you are building a browser client, note that direct `src` links to the stream\nURLs will not work due to the required authentication. You can use URL-based\nbasic authentication (`protocol://:password@host...`) in `src` attributes, but\nthis is unsupported in Internet Explorer and probably other browsers soon. You\ncan use `URL.createObjectURL` in JavaScript instead, e.g.:\n\n```javascript\nvar audio = document.createElement(\"audio\");\nvar xhr = new XMLHttpRequest();\n\nxhr.onload = function() {\n\tvar source = document.createElement(\"source\");\n\tsource.src = URL.createObjectURL(xhr.response);\n\tsource.type = \"audio/ogg\";\n\taudio.appendChild(source);\n}\n\nxhr.open(\"GET\", \"https://www.mydomain.com/songs/iswkgapo.opus\");\nxhr.responseType = \"blob\";\nxhr.setRequestHeader(\"Authorization\", \"Basic \" + btoa(\":asanisimasa\");\nxhr.send();\n```\n\nHowever, this method requires the entire file to be downloaded before playback\nbegins.\n\n#### Get a list of songs in the library\n\n```http\nGET /songs\n```\n\n```http\nHTTP/1.1 200 OK\nContent-Type: application/json\n```\n\n```json\n[\n\t{\n\t\t\"id\":     \"iswkgapo\",\n\t\t\"path\":   \"Bob Dylan/Bringing It All Back Home/Mr. Tambourine Man.flac\",\n\t\t\"time\":   \"2015-05-28T10:06:04-08:00\",\n\t\t\"artist\": \"Bob Dylan\",\n\t\t\"album\":  \"Bringing It All Back Home\",\n\t\t\"disc\":   2,\n\t\t\"track\":  1,\n\t\t\"title\":  \"Mr. Tambourine Man\",\n\t\t\"fmt\":    \"flac\",\n\t\t\"codec\":  \"flac\"\n\t},\n\t{\n\t\t\"id\":     \"wybtohyc\",\n\t\t\"path\":   \"Neutral Milk Hotel/In the Aeroplane over the Sea/Holland, 1945.flac\",\n\t\t\"time\":   \"2015-05-28T10:06:04-08:00\",\n\t\t\"artist\": \"Neutral Milk Hotel\",\n\t\t\"album\":  \"In the Aeroplane over the Sea\",\n\t\t\"disc\":   0,\n\t\t\"track\":  6,\n\t\t\"title\":  \"Holland, 1945\",\n\t\t\"fmt\":    \"flac\",\n\t\t\"codec\":  \"flac\"\n\t}\n]\n```\n\n### Get info for a specific song in the library\n\n```http\nGET /songs/wybtohyc\n```\n\n```http\nHTTP/1.1 200 OK\nContent-Type: application/json\n```\n\n```json\n{\n\t\"id\":     \"wybtohyc\",\n\t\"path\":   \"Neutral Milk Hotel/In the Aeroplane over the Sea/Holland, 1945.flac\",\n\t\"time\":   \"2015-05-28T10:06:04-08:00\",\n\t\"artist\": \"Neutral Milk Hotel\",\n\t\"album\":  \"In the Aeroplane over the Sea\",\n\t\"disc\":   0,\n\t\"track\":  6,\n\t\"title\":  \"Holland, 1945\",\n\t\"fmt\":    \"flac\",\n\t\"codec\":  \"flac\"\n}\n```\n\n#### Reload the library (i.e. after adding music or editing tags)\n\n```http\nPUT /songs\n```\n\n```http\nHTTP/1.1 200 OK\nContent-Type: application/json\n```\n\n```json\n[\n\t{\n\t\t\"id\":     \"iswkgapo\",\n\t\t\"path\":   \"Bob Dylan/Bringing It All Back Home/Mr. Tambourine Man.flac\",\n\t\t\"time\":   \"2015-05-28T10:06:04-08:00\",\n\t\t\"artist\": \"Bob Dylan\",\n\t\t\"album\":  \"Bringing It All Back Home\",\n\t\t\"disc\":   2,\n\t\t\"track\":  1,\n\t\t\"title\":  \"Mr. Tambourine Man\",\n\t\t\"fmt\":    \"flac\",\n\t\t\"codec\":  \"flac\"\n\t},\n\t{\n\t\t\"id\":     \"ihnqqjce\",\n\t\t\"path\":   \"Neutral Milk Hotel/Ferris Wheel on Fire/Home.flac\",\n\t\t\"time\":   \"2015-05-28T10:06:04-08:00\",\n\t\t\"artist\": \"Neutral Milk Hotel\",\n\t\t\"album\":  \"Ferris Wheel on Fire\",\n\t\t\"disc\":   0,\n\t\t\"track\":  3,\n\t\t\"title\":  \"Home\",\n\t\t\"fmt\":    \"flac\",\n\t\t\"codec\":  \"flac\"\n\t},\n\t{\n\t\t\"id\":     \"wybtohyc\",\n\t\t\"path\":   \"Neutral Milk Hotel/In the Aeroplane over the Sea/Holland, 1945.flac\",\n\t\t\"time\":   \"2015-05-28T10:06:04-08:00\",\n\t\t\"artist\": \"Neutral Milk Hotel\",\n\t\t\"album\":  \"In the Aeroplane over the Sea\",\n\t\t\"disc\":   0,\n\t\t\"track\":  6,\n\t\t\"title\":  \"Holland, 1945\",\n\t\t\"fmt\":    \"flac\",\n\t\t\"codec\":  \"flac\"\n\t}\n]\n```\n\n#### Get the stream for a song\n\n##### Opus\n\n```http\nGET /songs/wybtohyc.opus\n```\n\n```http\nHTTP/1.1 200 OK\nContent-Type: audio/ogg\n```\n\n##### MP3\n\n```http\nGET /songs/wybtohyc.mp3\n```\n\n```http\nHTTP/1.1 200 OK\nContent-Type: audio/mpeg\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwwalexander%2Friver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwwalexander%2Friver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwwalexander%2Friver/lists"}