GithubHelp home page GithubHelp logo

mrlemur / bottle-radio Goto Github PK

View Code? Open in Web Editor NEW
58.0 5.0 10.0 2.67 MB

Radio in a bottle. All in one solution for your own radio station.

License: MIT License

Dockerfile 8.86% Shell 4.40% HTML 3.48% CSS 2.61% JavaScript 71.09% Go 9.55%

bottle-radio's Introduction

Bottle Radio

Bottle radio

All in one application to run an automated radio station with the ability to live stream a performance.

This is a service that contains a number of applications running as Docker containers to provide a cohesive experience that allows both amateurs and professionals to run a self hosted web radio station.

Bottle Radio is currently in alpha. This means things will be subject to change without notice, possibly introducing breaking changes. You should only proceed if you are comfortable with Docker and starting from scratch if needed.

Live Demo

See the real thing in action at bottleradio.com.

Background

I was looking in to the possibility to run a 24/7 web radio station and started investigating what was already available. I wanted the following features in the solution:

  • Ability to play from Spotify when nothing else broadcasting
  • Ability to have someone live stream a DJ set or a show from their computer
  • Have the switch between the two modes be seamless, with a jingle in between

After struggling with applications like AzuraCast and LibreTime, I could not find something stable enough for what I wanted. AzuraCast had a lot of what I wanted, but the live streaming function rarely worked. With LibreTime, most functions worked but I found the scheduling too restrictive and the setup was a pain.

It was then I decided to use the best parts from these systems, and distill them in to a service with just the functionality I required.

Application structure

The application consists of multiple Docker containers, managed by a single docker-compose.yaml file. These are:

  • Traefik - a reverse proxy that manages the routes to all the containers and provides automatic HTTPS
  • Mopidy - an extensible music server that is used to provide Spotify playback
  • Liquidsoap - a scripting language that handles the switching between Spotfy and live broadcast streams
  • Icecast - a streaming server that sends the final stream to listeners
  • Frontend - a React application built from the ground up to be a responsive player interface

Installation

Prerequisites

  • (for production use): a domain name where you can control DNS records
  • Docker Engine (tested on Ubuntu 18.04.1)
  • Port 80, 443 and 8005 forwarded to Docker host
  • Spotify Premium account

DNS

For testing locally, a domain of docker.localhost will suffice.

For production, please set the following A records:

Type Name IPv4 Address
A @ Docker Host public IP
A *. Docker Host public IP

Setup

  1. Clone this repo to your host
  2. Change to the directory bottle-radio
  3. Copy .env-example to .env
  4. Alter the variables in .env as per below
  5. Run docker-compose up and check for any errors (may need to run with sudo depending on environment)
  6. The first run might take a while as it needs to build the image
  7. If all looks OK, hit CTRL+C to kill, and then run docker-compose up -d to run it in the background

Keep a backup of yout .env file as this is used to setup the application.

Example:

git clone https://github.com/MrLemur/bottle-radio.git
cd bottle-radio
cp .env-example .env
sudo docker-compose up

Configuration

.env file values:

Field Description Example Value
DOMAIN root domain of Docker host 1 example.com
LETSENCRYPT_EMAIL email address incase of SSL certificate issues [email protected]
REACT_ICECAST_URL stream + your root domain name in HTTPS URL https://stream.example.com/
REACT_KEY random number above 1 million 436587547365
LIQUIDSOAP_DJ_USERNAME username to be used for live broadcasts broadcast-dj
LIQUIDSOAP_DJ_PASSWORD password to be used for live broadcasts broadcast-password
ICECAST_SOURCE_PASSWORD icecast password for mopidy mopidy-password
ICECAST_ADMIN_PASSWORD icecast password for admin interface admin-password
ICECAST_PASSWORD icecast password for other uses (not used) normal-password
ICECAST_RELAY_PASSWORD icecast password for relaying (not used) relay-password
MOPIDY_AUTH username/pasword in .htpasswd format 2 spotify-admin:576rdfD\$67gddvgskjs
SPOTIFY_USERNAME Spotify premium username example
SPOTIFY_PASSWORD Spotify premium password example-password
SPOTIFY_CLIENT_ID value from here 687468-47843rh7f8
SPOTIFY_CLIENT_SECRET value from here bBYUBLYBh87B87G\$=

1 Use docker.localhost when running locally - only tested with Chromium based browsers

2 Use this site to generate the value using with bcrypt encryption

Customisation

These changes will require the containers to be stopped and restarted.

Custom Links

Links to other pages can be added by editing the frontend/src/links.json file. This is a JSON list, with display being the link display text and href being the URL.

Example:

[
  {
    "display": "This is an example link",
    "href": "https://example.com/"
  },
  {
    "display": "Homepage",
    "href": "https://myhomepage.com/"
  }
]
Station Name

There is currently no variable to set the station name in the .env file. In the meantime, you can do a search and replace for all files in the frontend/ directory for bottle radio and you should be able to replace the appropriate values with your station name.

Please leave the "Powered by Bottle Radio" link alone (within frontend/src/components/Container.jsx) in order to redirect questions to this project.

Logo

Logos are currently in the frontend/public/ directory. These are:

  • favicon.ico - favourite icon that appears in the browser tab
  • logo192.png - smaller version of main logo
  • logo512.png - main logo used in frontend

These logos are used in multiple places (browser, offline app), so make sure they are the same dimensions as the existing ones and are the same logo, just resized. Circular logos work best.

Jingle

There is a jingle that will play when transitioning from the automated broadcast to a live stream, and vice versa. This can be found in conf/jingle.mp3. It works best if the jingle is between 9-14 seconds long.

Usage

Follow the below steps after setup to get your station on air!

  1. Go to https://spotify.your.domain/
  2. Use the username/password you set for MOPIDY_AUTH variable
  3. Click on iris
  4. Find a playlist and hit the play Button
  5. Go to https://your.domain
  6. Click the play button
  7. After 20-30 seconds, you should now hear the stream

Listening

The frontend player interface will be available at https://your.domain/. This is what listeners will use.

The following features are available:

  • currently playing artist and track tracks
  • button to view streaming/buy links for the now playing tracks
  • visualiser in time to the music player
  • customised Links
  • button to show HTML code to embed player in another site
  • a little hidden something

Automated playback with Spotify

This can be accessed at https://spotify.your.domain/ and clicking on the iris link.

By using Mopidy, Spotify playback can be achieved when there is not a live stream in progress. The best way to ensure uninterrupted playback is to start a very long playlist (48+ hours), or multiple playlists queued. For best results, set the player to repeat and shuffle.

Streaming

This application will accept input from any Icecast 2 compatible source client (Butt, Mixxx) without any configuration changes. Follow the steps below to start live streaming:

  • Configure the host as your.domain
  • Set port as 8005
  • Set protocol to be Icecast 2
  • Set the mount point to /.
  • Set the username to what was configured in LIQUIDSOAP_DJ_USERNAME
  • Set the password to what was configured in LIQUIDSOAP_DJ_PASSWORD
  • Start broadcasting
  • Once the connection time hits around 11 seconds, you will be live on air!
  • This time until you are live can depend on jingle length and network latency. Experiment to see what works best!

Contribute

This project is still in very early stages, so any contributions would be greatly appreciated!

You can raise a bug or feature request here.

If you want to contribute code, please fork this repo and submit a PR!

bottle-radio's People

Contributors

brianshano avatar dependabot[bot] avatar mrlemur avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

bottle-radio's Issues

Auto update Playlists

Hello,

Thank you for this. I installed it yesterday.

I've also created an algorithm that creates Spotify playlists vis Spotify API. I ask Bottle to play this playlist.

Everything's fine except that when I update the playlist I have to log in to Iris to manually go and ask it to update it. Is there a possibility that when the spotify playlist changes, the radio adapts automatically?

Have a nice day
Alex

Docker-Compose up fails with: Error: error:0308010C:digital envelope routines::unsupported

Hello!

Bottle Radio is exactly what I have been looking for after going down the same road with Azuracast than you did - I really appreciate your description :) Unfortunately it took me over a year to find this repo, and it seems there are some issues I am unable to solve. They are all related to the installation of the components used failing. I am not a developer but I am running my fair share of docker-deployed services, so I assume this compose script requires a little more knowledge than described in your installation guide. Or it is simply outdated.

This has been verified on three of my VPS (2x 20.04, 1x 18. 04). By just following your install instructions, docker-compose up fails with:

Building frontend
Step 1/16 : FROM node:alpine as builder
alpine: Pulling from library/node
97518928ae5f: Already exists
4796d9078153: Pull complete
c3cb450ea517: Pull complete
dc9de54e9683: Pull complete
Digest: sha256:e64dc950217610c86f29aef803b123e1b6a4a372d6fa4bcf71f9ddcbd39eba5c
Status: Downloaded newer image for node:alpine
 ---> bb1fcdaff936
Step 2/16 : WORKDIR /app
 ---> Running in adc96fe3d4b2
Removing intermediate container adc96fe3d4b2
 ---> 8a31341c92ff
Step 3/16 : COPY package.json .
 ---> 314398f99893
Step 4/16 : COPY yarn.lock .
 ---> 563f211c8248
Step 5/16 : RUN yarn
 ---> Running in cdeb18573813
yarn install v1.22.15
[1/4] Resolving packages...
[2/4] Fetching packages...
info [email protected]: The platform "linux" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
info [email protected]: The platform "linux" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning "@emotion/styled > @emotion/[email protected]" has unmet peer dependency "@babel/core@^7.0.0".
warning "@emotion/styled > @emotion/babel-plugin > @babel/[email protected]" has unmet peer dependency "@babel/core@^7.0.0-0".
warning " > @testing-library/[email protected]" has unmet peer dependency "@testing-library/dom@>=7.21.4".
warning "react-scripts > @typescript-eslint/eslint-plugin > [email protected]" has unmet peer dependency "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta".
[4/4] Building fresh packages...
Done in 70.39s.
Removing intermediate container cdeb18573813
 ---> 86cd90de1149
Step 6/16 : COPY . .
 ---> d7f65d513081
Step 7/16 : RUN yarn build
 ---> Running in 3ad84968c56f
yarn run v1.22.15
$ react-scripts build
Creating an optimized production build...
Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:67:19)
    at Object.createHash (node:crypto:130:10)
    at module.exports (/app/node_modules/webpack/lib/util/createHash.js:135:53)
    at NormalModule._initBuildHash (/app/node_modules/webpack/lib/NormalModule.js:417:16)
    at handleParseError (/app/node_modules/webpack/lib/NormalModule.js:471:10)
    at /app/node_modules/webpack/lib/NormalModule.js:503:5
    at /app/node_modules/webpack/lib/NormalModule.js:358:12
    at /app/node_modules/loader-runner/lib/LoaderRunner.js:373:3
    at iterateNormalLoaders (/app/node_modules/loader-runner/lib/LoaderRunner.js:214:10)
    at iterateNormalLoaders (/app/node_modules/loader-runner/lib/LoaderRunner.js:221:10)
    at /app/node_modules/loader-runner/lib/LoaderRunner.js:236:3
    at runSyncOrAsync (/app/node_modules/loader-runner/lib/LoaderRunner.js:130:11)
    at iterateNormalLoaders (/app/node_modules/loader-runner/lib/LoaderRunner.js:232:2)
    at Array.<anonymous> (/app/node_modules/loader-runner/lib/LoaderRunner.js:205:4)
    at Storage.finished (/app/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:55:16)
    at /app/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:91:9
/app/node_modules/react-scripts/scripts/build.js:19
  throw err;
  ^

Error: error:0308010C:digital envelope routines::unsupported
    at new Hash (node:internal/crypto/hash:67:19)
    at Object.createHash (node:crypto:130:10)
    at module.exports (/app/node_modules/webpack/lib/util/createHash.js:135:53)
    at NormalModule._initBuildHash (/app/node_modules/webpack/lib/NormalModule.js:417:16)
    at /app/node_modules/webpack/lib/NormalModule.js:452:10
    at /app/node_modules/webpack/lib/NormalModule.js:323:13
    at /app/node_modules/loader-runner/lib/LoaderRunner.js:367:11
    at /app/node_modules/loader-runner/lib/LoaderRunner.js:233:18
    at context.callback (/app/node_modules/loader-runner/lib/LoaderRunner.js:111:13)
    at /app/node_modules/react-scripts/node_modules/babel-loader/lib/index.js:59:103 {
  opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
  library: 'digital envelope routines',
  reason: 'unsupported',
  code: 'ERR_OSSL_EVP_UNSUPPORTED'
}

Node.js v17.2.0
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
ERROR: Service 'frontend' failed to build: The command '/bin/sh -c yarn build' returned a non-zero code: 1

I have researched this error and it seems to be quite common when compiling nodejs projects (webpack/webpack#14532). So I tried putting the "--openssl-legacy-provider" into the package.json react script build reference, and it actually worked - only to be stopped when installing Mopidy:


`Step 4/18 : RUN apt-get update     && apt-get install -y     dumb-init     graphviz-dev     gstreamer1.0-plugins-bad     gstreamer1.0-plugins-good     gstreamer1.0-plugins-ugly     gstreamer1.0-pulseaudio     libasound2-dev     python-dev     python-gst-1.0     python3-gst-1.0     && rm -rf /var/lib/apt/lists/*
 ---> Running in 3d184dc0d078
Get:1 http://deb.debian.org/debian buster InRelease [122 kB]
Get:2 http://security.debian.org/debian-security buster/updates InRelease [65.4 kB]
Get:3 http://deb.debian.org/debian buster-updates InRelease [51.9 kB]
Reading package lists...
E: Repository 'http://security.debian.org/debian-security buster/updates InRelease' changed its 'Suite' value from 'stable' to 'oldstable'
E: Repository 'http://deb.debian.org/debian buster InRelease' changed its 'Suite' value from 'stable' to 'oldstable'
E: Repository 'http://deb.debian.org/debian buster-updates InRelease' changed its 'Suite' value from 'stable-updates' to 'oldstable-updates'
ERROR: Service 'mopidy' failed to build: The command '/bin/sh -c apt-get update     && apt-get install -y     dumb-init     graphviz-dev     gstreamer1.0-plugins-bad     gstreamer1.0-plugins-good     gstreamer1.0-plugins-ugly     gstreamer1.0-pulseaudio     libasound2-dev     python-dev     python-gst-1.0     python3-gst-1.0     && rm -rf /var/lib/apt/lists/*' returned a non-zero code: 100
`

So yeah, it seems to be pretty broken atm. Or I am missing something. Please help me out!

Is there a missing section between the end of installation and getting started?

Describe the bug
Docs go from installation to "visit spotify.your.doman/" however this fails with a 404.
The docs dont mention set up of SSL anywhere and even when going insecure it's still a 404

To Reproduce
Steps to reproduce the behavior:

  1. Install
  2. Try to visit https://spotify.your.domain
  3. SSL warning page
  4. Click through "unsafe" and you get a 404

Expected behavior
I expected the set up page to load

Screenshots
ssl fail no site to load

Desktop (please complete the following information):

  • OS: Win 10
  • Browser Chrome
  • Version latest

[Mopidy: Failed to add some tracks]

I have installed the mopidy Container alone
and i inserted all Variables from Spotify.
Added my own Icecast Server for Playout.

When i click on a song or Playlist, i get the Error:
Mopidy: Failed to add some tracks

Any Help for this Issue?

Is there available a backend management demo?

i.e. AzuraCast has web-based panel, from where people manages everything (station, account, settings..), and its demo is available.
Is anything similar available for bottleratio, so we could see how backend management panel looks like?

Mopify-Spotify not running

Running Ubuntu 21.10

Mopify logs in but I am unable to browse spotify through the web interface
image
It also appears to not want to connect to a server
image

Ive redo authentication with the plugin but and restarted the docker container but no luck. Just running locally with no SSL cert

Local Files

Hi there,

Just wondering if bottle radio would be able to play local files? Basically the same thing as it does now just with local files instead of using Spotify.

Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.