Giter Club home page Giter Club logo

black_candy's Introduction

Black Candy logo

Black Candy

CI Coverage Status Ruby Style Guide Docker Pulls

Black Candy is a self hosted music streaming server built with Rails and Hotwire. The goal of the project is to create a real personal music center.

Screenshot

screenshot theme dark

screenshot theme light

Try The Demo

Please visit https://demo.blackcandy.org and use demo user (email: [email protected], password: foobar) to login. And feel free to try it.

Notice: This demo user does not have administrator privileges. So you cannot experience all the features in Black Candy. And all music in the demo is under non-commercial licences. You can check their licences.

Installation

⚠️ Notice: This installation instruction is for edge version, which means the docker image is build base on master branch. Because upcoming major version of Black Candy is going to have a lot of infrastructure changes. So the installation process will have a lot of difference. If you are looking for installation instruction for latest stable version, please visit here.

Black Candy use docker image to install easily. You can simply run Black Candy like this.

docker run -p 3000:3000 ghcr.io/blackcandy-org/blackcandy:edge 

That's all. Now, you can access either http://localhost:3000 or http://host-ip:3000 in a browser, and use initial admin user to login (email: [email protected], password: foobar).

Mobile App

Black Candy now has an iOS app in beta. You can visit here and join TestFlight to give it a try. Because this iOS app still in beta, you need use the edge version of Black Candy.

Configuration

Port Mapping

Black Candy exports the 3000 port. If you want to be able to access it from the host, you can use the -p option to map the port.

docker run -p 3000:3000 ghcr.io/blackcandy-org/blackcandy:edge

Media Files Mounts

You can mount media files from host to container and use MEDIA_PATH environment variable to set the media path for black candy.

docker run -v /media_data:/media_data -e MEDIA_PATH=/media_data ghcr.io/blackcandy-org/blackcandy:edge   

Use PostgreSQL As Database

Black Candy use SQLite as database by default. Because SQLite can simplify the process of installation, and it's an ideal choice for self hosted small server. If you think SQLite is not enough or you are using some cloud service like heroku to host Black Candy, you can also use PostgreSQL as database.

docker run -e DB_ADAPTER=postgresql -e DB_URL=postgresql://yourdatabaseurl ghcr.io/blackcandy-org/blackcandy:edge 

How to Persist Data

All the data that need to persist in Black Candy are stored in /app/storage, So you can mount this directory to host to persist data.

mkdir storage_data

docker run -v ./storage_data:/app/storage ghcr.io/blackcandy-org/blackcandy:edge 

Nginx To Send File

Black Candy supports use Nginx to delivery audio file to client. It's a more effective way than handle by Black Candy backend. And Black Candy docker image are also ready for nginx-proxy, which means you can setup a Nginx proxy for Black Candy easily. I recommend you use nginx-proxy with Black Candy.

You can use docker-compose to setup those services. The docker-compose.yml file looks like this:

version: '3'

services:
  nginx-proxy:
    image: nginxproxy/nginx-proxy
    ports:
      - "80:80"
    volumes:
      - ./blackcandy.local:/etc/nginx/vhost.d/blackcandy.local:ro
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - /media_data:/media_data # Keep the path of media files in container same as blackcandy container.

  app:
    image: ghcr.io/blackcandy-org/blackcandy:edge 
    volumes:
      - ./storage_data:/app/storage
      - /media_data:/media_data
    environment:
      VIRTUAL_HOST: blackcandy.local
      MEDIA_PATH: /media_data
      NGINX_SENDFILE: "true" # Don't forget to set `NGINX_SENDFILE` environment variable to true to enable nginx sendfile.
# Get the default sendfile config for blackcandy. This file need to mount to nginx proxy container to add custom configuration for nginx.
curl https://raw.githubusercontent.com/blackcandy-org/black_candy/master/config/nginx/sendfile.conf > blackcandy.local 

docker-compose up

Logging

Black Candy logs to STDOUT by default. So if you want to control the log, Docker already supports a lot of options to handle the log in the container. see: https://docs.docker.com/config/containers/logging/configure/.

Environment Variables

Name Default Description
DB_URL The URL of PostgreSQL database. You must set this environment variable if you use PostgreSQL as database.
MEDIA_PATH You can use this environment variable to set media path for Black Candy, otherwise you can set media path in settings page.
DB_ADAPTER "sqlite" There are two adapters are supported, "sqlite" and "postgresql".
NGINX_SENDFILE false Whether enable Nginx sendfile.
SECRET_KEY_BASE When the SECRET_KEY_BASE environment variable is not set, Black candy will generate SECRET_KEY_BASE environment variable every time when service start up. This will cause old sessions invalid, You can set your own SECRET_KEY_BASE environment variable on docker service to avoid it.
FORCE_SSL false Force all access to the app over SSL.
DEMO_MODE false Whether to enable demo mode, when demo mode is on, all users cannot access administrator privileges, even user is admin. And also users cannot change their profile.

Upgrade

Pull new image from remote

$ docker pull ghcr.io/blackcandy-org/blackcandy:edge 

Development

Requirements

  • Ruby 3.2
  • Node.js 20
  • libvips
  • FFmpeg

Make sure you have installed all those dependencies.

Install gem dependencies

bundle install

Install JavaScript dependencies

npm install

Database Configuration

rails db:prepare
rails db:seed

Start all services

After you’ve set up everything, now you can running ./bin/dev to start all service you need to develop. Then visit http://localhost:3000 use initial admin user to login (email: [email protected], password: foobar).

Test

# Running all test
$ rails test:all 

# Running lint
$ rails lint:all

Integrations

Black Candy support get artist and album image from Discogs API. You can create a API token from Discogs and set Discogs token on Setting page to enable it.

Licences Of The Music In Demo

If you like their music, you can buy their albums to support them.

Sponsorship

This project is supported by:

black_candy's People

Contributors

aidewoode avatar dependabot[bot] avatar gemmaro avatar igorpolyakov avatar jaredmoody avatar mastert 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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

black_candy's Issues

Opus support

Thanks for making this excellent music streaming server. Please can I request support for Opus? I had a quick look at the code to see if I could enable Opus support but I get some kind of database rollback error.

app_1        |   Artist Load (0.2ms)  SELECT  "artists".* FROM "artists" WHERE "artists"."name" = $1 LIMIT $2  [["name", "Astrid S"], ["LIMIT", 1]]
app_1        |    (0.1ms)  BEGIN
app_1        |   Artist Create (0.3ms)  INSERT INTO "artists" ("name", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING "id"  [["name", "Astrid S"], ["created_at", "2019-07-21 12:36:18.001705"], ["updated_at", "2019-07-21 12:36:18.001705"]]
app_1        |    (1.4ms)  COMMIT
app_1        |   Album Load (0.2ms)  SELECT  "albums".* FROM "albums" WHERE "albums"."artist_id" = $1 AND "albums"."name" = $2 LIMIT $3  [["artist_id", 251], ["name", "Breathe"], ["LIMIT", 1]]
app_1        |    (0.1ms)  BEGIN
app_1        |   Album Exists (0.4ms)  SELECT  1 AS one FROM "albums" WHERE "albums"."name" = $1 AND "albums"."artist_id" = $2 LIMIT $3  [["name", "Breathe"], ["artist_id", 251], ["LIMIT", 1]]
app_1        |   Album Create (0.3ms)  INSERT INTO "albums" ("name", "artist_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["name", "Breathe"], ["artist_id", 251], ["created_at", "2019-07-21 12:36:18.006816"], ["updated_at", "2019-07-21 12:36:18.006816"]]
app_1        |    (1.2ms)  COMMIT
app_1        |   Song Load (0.2ms)  SELECT  "songs".* FROM "songs" WHERE "songs"."md5_hash" = $1 LIMIT $2  [["md5_hash", "T7MTDA1GZbv2xRoa9uK34w=="], ["LIMIT", 1]]
app_1        |    (0.1ms)  BEGIN
app_1        |    (0.1ms)  ROLLBACK

Artist Cover

Congratulations for the wonderful project, I have one question
How can i set artists image manually?
I'm doing a personal streaming server for some music that me and my friends make, so there is no official image on discogs or similar sites. From your code I understand that artist images can be attached only via discogs.
Thanks for your time.

Audibooks?

Would it be in possible to add audible like audiobook support to the scope of the project?

Songs not playing

Browser: Firefox 69.0b1 (64-bit)

image

In logs, prints this message

app_1       | X-Accel-Mapping header missing                                                                                                                                                                       

Per-user media subdirectory

Hi!
I've been looking around black_candy, and the simplicity of the app is really nice.
I'd love to use this for my family, but we all listen to different music styles. What I would need is a way to specify a subfolder for each user. The music that's in a user's subfolder is not accessible to other users, and music that's outside of user subfolders is available to all.

Thanks!

Playlist ISSUE

When I want to add a song in a playlist, the site gives me an error " the file is already present in the Playlist"
This happens when i listen a music, and i want to add another music in the playlist

Add to library

This looks really great!

But how do you add to the library?

nginx config requires base service name to be app

I have multiple services in one docker-compose file, for easier readability I renamed blackcandy from app to blackcandy.

blackcandy: &blackcandy_base
    image: blackcandy/blackcandy
    container_name: blackcandy_app
    networks:
      - internal
    volumes:
      - /mnt/share/audio/musik:/media_data:ro
      # - production_uploads_data:/app/public/uploads
    environment:
      DB_HOST: blackcandy_postgres
      DB_USER: postgres
      REDIS_CACHE_URL: redis://blackcandy_redis:6379/1
      REDIS_SIDEKIQ_URL: redis://blackcandy_redis:6379/2
      MEDIA_PATH: /media_data
    depends_on:
      - blackcandy_postgres
      - blackcandy_redis

  blackcandy_postgres:
    image: postgres:11.1-alpine
    container_name: blackcandy_postgres
    networks:
      - internal
    volumes:
      - $DOCKERDIR/postgres/blackcandy:/var/lib/postgresql/data

  blackcandy_redis:
    container_name: blackcandy_redis
    networks:
      - internal
    image: redis:4.0-alpine

  blackcandy_worker:
    <<: *blackcandy_base
    container_name: blackcandy_worker
    command: bundle exec sidekiq

  blackcandy_web:
    <<: *blackcandy_base
    container_name: blackcandy_web
    networks:
      - internal
      - proxy
    depends_on:
      - blackcandy
      - blackcandy_worker
    command: nginx -g 'pid /tmp/nginx.pid; daemon off;'
    labels:
      traefik.enable: true
      traefik.http.routers.blackcandy.entrypoints: web-secure
      traefik.http.routers.blackcandy.rule: Host(`blackcandy.$DOMAINNAME`)
      traefik.http.services.blackcandy.loadbalancer.server.port: 80
      traefik.http.services.blackcandy.loadbalancer.server.scheme: http

Here is the error I get:

mb@dockerhost:~$ docker logs blackcandy_web
nginx: [emerg] host not found in upstream "app:3000" in /etc/nginx/nginx.conf:19

Not a huge deal but maybe we can change this via an environment variable?

Add new home page

Can be used to display recently added albums, favorite songs, recently played albums, etc.

[RFC] Closing pull requests while a new build is starting causes failures

Build failures often indicate a fault with the software being built such as compilation or test failures. However, there is a subset of build failures (called environmental or non-verification failures) that are not expected within a standard application development lifecycle, such as build configuration failures, dependency resolution failures, infrastructure failures, and so on.

Problem: One type of environmental failure is due to due to git references being no longer available at the time a build job starts. For example, pull requests are merged shortly before the start of the scheduled build, causing a build failure due to an unfound (because merged) branch. In your project, we detected 4 failures of this type over the May-June timespan. For instance, we found that Build #227 did not pass due to the above issue.

Solution: It is generally recommended to wait for the build results before merging a pull request. If you wish to skip builds you may also use the SKIP CI tag in your commit message. Additionally, it is also possible to skip builds containing non-code changes as shown in this example and below:

+ before_install:
+  - |
+      if ! git diff --name-only $TRAVIS_COMMIT_RANGE | grep -qvE '(.md)|(.png)|(.pdf)|(.html)|^(LICENSE)|^(docs)'
+      then
+        echo "Only doc files were updated, not running the CI."
+        exit
+      fi

Disclaimer: I developed a tool that repairs environmental build failures and I am now evaluating its usefulness for open-source projects.

Please up/downvote the issue to indicate whether you agree/disagree with the report and the proposed fix.

Support lyrics display

Should have the ability to get lyrics from audio metadata. And also need to support upload LRC format file to the song manually.

Enabling open registration

It will be a very useful option, thanks to which each user will be able to create an account for himself.

Upload Functionality?

First of all, awesome work on this project! I've been working on getting a relative digitized after some hardware failures and this is just the thing for the music side of that.

I've now got this running on an Azure VM. It'd be great if there was a way for non-technical users to upload songs to black_candy. For the moment I'm just ripping CDs and rsync'ing them up, but I'd rather not be the sole arbiter of this process going forward :)

Discussions?

How about enabling discussions on this repo to allow people to ask questions, discuss ideas that aren't "issues"? I have a few...

Error while building

Whenever I try to follow your commands, I receive the following error:

Creating black_candy_redis_1    ... done
Creating black_candy_postgres_1 ... done
ERROR: An HTTP request took too long to complete. Retry with --verbose to obtain debug information.
If you encounter this issue regularly because of slow network conditions, consider setting COMPOSE_HTTP_TIMEOUT to a higher value (current value: 60).
make: *** [Makefile:38: production_setup] Error 1

Would it be possible to provide a full docker solution, and also instructions on the hub.docker.com website? Currently, cloning the image and then building is pretty complicated, and I do not reallt know where the error is.

In addition to this, I wonder whether this server provides also transcoding functionality? It is not obvious from the settings... Is it possible to implement it?

Error response from daemon: Conflict. The container name "/blackcandy_app" is already in use by container XXX

Hello,
I used the docker-compose.yml file as indicated but when executing the command $ docker-compose up -d I get the following error. Any idea?

user@BlackCandy:/home/user/blackcandy# docker compose up -d
[+] Running 32/32
⠿ postgres Pulled 23.9s
⠿ 6c40cc604d8e Pull complete 10.0s
⠿ 3ea5fa93d025 Pull complete 10.6s
⠿ 146f5c88cacb Pull complete 11.0s
⠿ 1549d653d730 Pull complete 17.6s
⠿ 1f52f9ddebb6 Pull complete 18.0s
⠿ a4c85e4b61b7 Pull complete 18.2s
⠿ a562b26ea57a Pull complete 18.5s
⠿ 04f1f3b24313 Pull complete 18.9s
⠿ f2684c2bfb4b Pull complete 19.2s
⠿ redis Pulled 15.6s
⠿ cbdbe7a5bc2a Pull complete 6.5s
⠿ dc0373118a0d Pull complete 7.0s
⠿ cfd369fe6256 Pull complete 8.3s
⠿ 152ffd6a3b24 Pull complete 10.0s
⠿ 7c01860f13a3 Pull complete 10.5s
⠿ aa6ecacd3bee Pull complete 10.9s
⠿ worker Pulled 44.2s
⠿ web Pulled 44.2s
⠿ listener Pulled 44.2s
⠿ app Pulled 44.2s
⠿ 2408cc74d12b Pull complete 1.3s
⠿ fdbd9a0f0a99 Pull complete 3.9s
⠿ 4af624e0dc7d Pull complete 4.2s
⠿ c013a669105b Pull complete 12.9s
⠿ 6f2847677b49 Pull complete 13.1s
⠿ d50ad5c2f0c0 Pull complete 33.6s
⠿ c550ed8f4549 Pull complete 33.8s
⠿ cd5789dc6f9d Pull complete 34.1s
⠿ c273974abcb6 Pull complete 39.3s
⠿ fb908f56be38 Pull complete 39.7s
⠿ f8702d6c0b32 Pull complete 39.9s
[+] Running 7/7
⠿ Network blackcandy_default Created 0.2s
⠿ Volume "blackcandy_production_uploads_data" Crea... 0.0s
⠿ Volume "blackcandy_production_db_data" Created 0.0s
⠿ Volume "blackcandy_production_redis_data" Create... 0.0s
⠿ Container blackcandy_postgres Created 2.4s
⠿ Container blackcandy_redis Created 2.4s
⠿ Container blackcandy_app Created 0.1s
Error response from daemon: Conflict. The container name "/blackcandy_app" is already in use by container "5e4af0acded20d7dfce8f4814d5f722a10425fd23e77df561d1f10c7f753dfb9". You have to remove (or rename) that container to be able to reuse that name.

How do I make this run in docker?

So I pulled blackcandy/blackcandy from dockerhub. Then I did docker run with that name and with networking mapped to my host.
When I try to visit the app from the web frontend I get "An unhandled lowlevel error occurred. The application logs may have details."

When I checked the logs with docker I found the following:

Rack app error handling request { GET / }
#<ArgumentError: Missing `secret_key_base` for 'production' environment, set this string with `rails credentials:edit`>
/usr/local/bundle/gems/railties-6.0.1/lib/rails/application.rb:580:in `validate_secret_key_base'
/usr/local/bundle/gems/railties-6.0.1/lib/rails/application.rb:423:in `secret_key_base'
/usr/local/bundle/gems/railties-6.0.1/lib/rails/application.rb:253:in `env_config'
/usr/local/bundle/gems/railties-6.0.1/lib/rails/engine.rb:720:in `build_request'
/usr/local/bundle/gems/railties-6.0.1/lib/rails/application.rb:603:in `build_request'
/usr/local/bundle/gems/railties-6.0.1/lib/rails/engine.rb:525:in `call'
/usr/local/bundle/gems/puma-4.2.1/lib/puma/configuration.rb:228:in `call'
/usr/local/bundle/gems/puma-4.2.1/lib/puma/server.rb:667:in `handle_request'
/usr/local/bundle/gems/puma-4.2.1/lib/puma/server.rb:470:in `process_client'
/usr/local/bundle/gems/puma-4.2.1/lib/puma/server.rb:328:in `block in run'
/usr/local/bundle/gems/puma-4.2.1/lib/puma/thread_pool.rb:134:in `block in spawn_thread'

so I'm guessing I set it up wrong (missing stuff). Namely secret_key_base which I assume should be fed to the app thru an env var. Still, which secret key to begin with? And what else is missing here?

Add to Current playlist

As far as I can tell there isn't a way to add a song to the end of the Current list without stopping what's currently playing, nor a way to add a song to play next in the Current list.

What do you think about adding those features? I'm happy to help with these as I would use them regularly.

mtime rather than file hash for change detection

Currently we hash the first 5MB of the file for uniqueness+to see if it's changed. This means that syncing can take a while and read a lot of data. I'm using Azure blob mounted via fuse, so reading 5MB from every single track ends up taking a lot of time.

Using the mtime to do the comparison would be a desirable option. In this case blobfuse would read the blob metadata, instead of downloading the file, which is pretty instant. Perhaps a way to toggle between using mtime versus a hash would be appropriate if there's scenarios where a hash is more desirable, such as for deduplication.

I'm not much of a rubyist but I'm happy to try to PR this if there's interest. It seems like it should be a pretty easy point fix--we can create the hash in the linked method from a combination of the mtime and the file path rather than the file contents.

Support grouping by "Album Artist"

Most of my albums are compilations grouped under one "Album Artist." A contrived example:

Song Artist Album Artist
The Foo (qux remix) qux The Foo Remix Collective
The Foo (bar remix) bar The Foo Remix Collective
The Foo (bam remix) bam The Foo Remix Collective

Currently Black Candy splits this into 3 albums in the Albums tab, one for each artist. I'd like to view my albums grouped by Album Artist. Some ideas:

  • Add a "Group By..." setting to the Albums tab.
  • Add a "Compilations" tab that's just like the Albums tab, except that it merges albums by Album Artist.

volume control

how can I somehow control the volume of the music being played

thanks for the great software

Drag song into playlist

I think the ability to drag a song from the main list into a playlist would be a nice feature, what do you think?

Can't login: HTTP 422 and errors in blackcandy_app

Hi,
i have set up black candy exactly as mentioned in the readme.md, using your provided docker-compose.
The only difference is it runs behind a reverse proxy, which of course hands the traffic to bc.

Problem: I can't login with the provided default credentials.
Having a look in the browsers network tab shows that the request to /session is answered with an http status code 422.

Having a look in the docker logs of the blackcandy_app containter shows:

Error during failsafe response: Missing template errors/not_found, application/not_found with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :jbuilder]}. Searched in:
  * "/app/app/views"

  /usr/local/bundle/gems/actionview-6.0.2.1/lib/action_view/path_set.rb:48:in `find'
  /usr/local/bundle/gems/actionview-6.0.2.1/lib/action_view/lookup_context.rb:129:in `find'
  /usr/local/bundle/gems/actionview-6.0.2.1/lib/action_view/renderer/template_renderer.rb:47:in `determine_template'
  /usr/local/bundle/gems/actionview-6.0.2.1/lib/action_view/renderer/template_renderer.rb:9:in `render'
  /usr/local/bundle/gems/actionview-6.0.2.1/lib/action_view/renderer/renderer.rb:61:in `render_template_to_object'
  /usr/local/bundle/gems/actionview-6.0.2.1/lib/action_view/renderer/renderer.rb:29:in `render_to_object'
  /usr/local/bundle/gems/actionview-6.0.2.1/lib/action_view/rendering.rb:118:in `block in _render_template'
  /usr/local/bundle/gems/actionview-6.0.2.1/lib/action_view/base.rb:304:in `in_rendering_context'
  /usr/local/bundle/gems/actionview-6.0.2.1/lib/action_view/rendering.rb:117:in `_render_template'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_controller/metal/streaming.rb:219:in `_render_template'
  /usr/local/bundle/gems/actionview-6.0.2.1/lib/action_view/rendering.rb:103:in `render_to_body'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_controller/metal/rendering.rb:52:in `render_to_body'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_controller/metal/renderers.rb:142:in `render_to_body'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/abstract_controller/rendering.rb:25:in `render'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_controller/metal/rendering.rb:36:in `render'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_controller/metal/instrumentation.rb:44:in `block (2 levels) in render'
  /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/core_ext/benchmark.rb:14:in `block in ms'
  /usr/local/lib/ruby/2.6.0/benchmark.rb:308:in `realtime'
  /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/core_ext/benchmark.rb:14:in `ms'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_controller/metal/instrumentation.rb:44:in `block in render'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_controller/metal/instrumentation.rb:85:in `cleanup_view_runtime'
  /usr/local/bundle/gems/activerecord-6.0.2.1/lib/active_record/railties/controller_runtime.rb:34:in `cleanup_view_runtime'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_controller/metal/instrumentation.rb:43:in `render'
  /app/app/controllers/errors_controller.rb:13:in `not_found'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_controller/metal/basic_implicit_render.rb:6:in `send_action'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/abstract_controller/base.rb:196:in `process_action'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_controller/metal/rendering.rb:30:in `process_action'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/abstract_controller/callbacks.rb:42:in `block in process_action'
  /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/callbacks.rb:135:in `run_callbacks'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/abstract_controller/callbacks.rb:41:in `process_action'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_controller/metal/rescue.rb:22:in `process_action'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_controller/metal/instrumentation.rb:33:in `block in process_action'
  /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/notifications.rb:180:in `block in instrument'
  /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/notifications/instrumenter.rb:24:in `instrument'
  /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/notifications.rb:180:in `instrument'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_controller/metal/instrumentation.rb:32:in `process_action'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_controller/metal/params_wrapper.rb:245:in `process_action'
  /usr/local/bundle/gems/activerecord-6.0.2.1/lib/active_record/railties/controller_runtime.rb:27:in `process_action'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/abstract_controller/base.rb:136:in `process'
  /usr/local/bundle/gems/actionview-6.0.2.1/lib/action_view/rendering.rb:39:in `process'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_controller/metal.rb:191:in `dispatch'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_controller/metal.rb:252:in `dispatch'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_dispatch/routing/route_set.rb:51:in `dispatch'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_dispatch/routing/route_set.rb:33:in `serve'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_dispatch/journey/router.rb:49:in `block in serve'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_dispatch/journey/router.rb:32:in `each'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_dispatch/journey/router.rb:32:in `serve'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_dispatch/routing/route_set.rb:837:in `call'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_dispatch/middleware/show_exceptions.rb:51:in `render_exception'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_dispatch/middleware/show_exceptions.rb:36:in `rescue in call'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
  /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/rack/logger.rb:38:in `call_app'
  /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/rack/logger.rb:26:in `block in call'
  /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/tagged_logging.rb:80:in `block in tagged'
  /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/tagged_logging.rb:28:in `tagged'
  /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/tagged_logging.rb:80:in `tagged'
  /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/rack/logger.rb:26:in `call'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_dispatch/middleware/request_id.rb:27:in `call'
  /usr/local/bundle/gems/rack-2.2.2/lib/rack/method_override.rb:24:in `call'
  /usr/local/bundle/gems/rack-2.2.2/lib/rack/runtime.rb:22:in `call'
  /usr/local/bundle/gems/activesupport-6.0.2.1/lib/active_support/cache/strategy/local_cache_middleware.rb:29:in `call'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_dispatch/middleware/executor.rb:14:in `call'
  /usr/local/bundle/gems/rack-2.2.2/lib/rack/sendfile.rb:110:in `call'
  /usr/local/bundle/gems/actionpack-6.0.2.1/lib/action_dispatch/middleware/host_authorization.rb:77:in `call'
  /usr/local/bundle/gems/railties-6.0.2.1/lib/rails/engine.rb:526:in `call'
  /usr/local/bundle/gems/puma-4.3.1/lib/puma/configuration.rb:228:in `call'
  /usr/local/bundle/gems/puma-4.3.1/lib/puma/server.rb:681:in `handle_request'
  /usr/local/bundle/gems/puma-4.3.1/lib/puma/server.rb:472:in `process_client'
  /usr/local/bundle/gems/puma-4.3.1/lib/puma/server.rb:328:in `block in run'
  /usr/local/bundle/gems/puma-4.3.1/lib/puma/thread_pool.rb:134:in `block in spawn_thread'

What am i doing wrong?

High CPU usage when playing audio

While listening today, I noticed a stutter every so often in playback, and traced that to very high CPU usage from black candy when playing in Safari

Activity Monitor 2022-03-18 17-14-35

It is a large file encoded in ALAC, and while I have "Allow transcode lossless" switched on, I'm seeing AAC listed in the safari network pane, so perhaps the transcode is happening on my local machine which is causing the high CPU.

Settings 2022-03-18 17-20-08

I don't have this same issue in Jellyfin, my current primary player which I'd like to switch away from, so seems specific to BlackCandy, and when playing in Jellyfin, it looks like it is transcoding to m4a:

Jellyfin 2022-03-18 17-23-16

No Music Discovered

I'm using docker to give this a go but unfortunately, no music is discovered.

Here's my slightly modified compose file:

version: '3.4'
networks:
        reverse-proxy:
                external: true
        blackcandy:
                external: false
services:
  app: &app_base
    container_name: 'app'
    image: blackcandy/blackcandy
    volumes:
      - ./log:/app/log
      - /datapool/media/music:/media_data
      - /datapool/media/uploads:/app/public/uploads
    environment:
      DB_HOST: postgres
      DB_USER: postgres
      REDIS_DATA_URL: redis://redis:6379/0
      REDIS_CACHE_URL: redis://redis:6379/1
      REDIS_SIDEKIQ_URL: redis://redis:6379/2
      MEDIA_PATH: /media_data
      SECRET_KEY_BASE: redacted
    depends_on:
      - postgres
      - redis
    networks:
      - blackcandy
  postgres:
    container_name: 'blackcandy_postgres'
    image: postgres:11.1-alpine
    volumes:
      - production_db_data:/var/lib/postgresql/data
    networks:
      - blackcandy
  redis:
    container_name: 'blackcandy_redis'
    image: redis:4.0-alpine
    volumes:
      - production_redis_data:/data
    networks:
      - blackcandy
  worker:
    container_name: 'blackcandy_worker'
    <<: *app_base
    command: bundle exec sidekiq
    networks:
      - blackcandy
  web:
    container_name: 'blackcandy_web'
    <<: *app_base
    depends_on:
      - app
      - worker
    command: nginx -g 'pid /tmp/nginx.pid; daemon off;'
    networks:
      - reverse-proxy
      - blackcandy
volumes:
  production_db_data:
  production_redis_data:
  production_uploads_data:

I've connected using docker-exec and all of my music is showing up in /media_data as I would have expected so I'm not sure what's going wrong. There's nothing obvious in the logs either.

Please advise?

Add manifest.json file to public directory

It would be useful to have the following manifest.json in the public folder in order to use as a "standalone" app on the phone ( without attaching to existing chrome tabs).

  • I've left the icons path empty to be customized as per your likings
  • the colors follow app base color and accent
  • I've decided for the "standalone" ui because the phone's back button is sufficient to navigate the app

More info at: https://web.dev/add-manifest/

Thank you for your wonderful work.

manifest.json.zip

Setup Instructions Issues

I'm having some trouble with the setup instructions for development.

Everything went ok until rails db:setup, which fails with:

rails aborted!
ArgumentError: Missing `secret_key_base` for 'production' environment, set this string with `bin/rails credentials:edit`

It looks like RAILS_ENV is set to production when I think it should be development?

However, RAILS_ENV=development rails db:setup also fails for me:

We could not find your database: postgres. Which can be found in the database configuration file located at config/database.yml.

To resolve this issue:

- Did you create the database for this app, or delete it? You may need to create your database.
- Has the database name changed? Check your database.yml config has the correct database name.

To create your database, run:

        bin/rails db:create
Couldn't create 'black_candy_development' database. Please check your configuration.
rails aborted!
ActiveRecord::NoDatabaseError: We could not find your database: postgres. Which can be found in the database configuration file located at config/database.yml
...
Caused by:
PG::ConnectionBad: FATAL:  role "postgres" does not exist

Is the nix config out of date here?

session error

I deployed balck candy with docker-composer and it works well when I visit it via my ip address. However, after binding my domain name and ip address using nginx, I am stuck on the login page with a "422 Unprocessable Entity" error when accessing the website via the domain name, but it works well via my ip address. I think it is a seesion error but I can't get it through. Any help will be appreciated!

First login fails

I installed black candy without any errors on a dedicated debian server, following every step of your guide and making sure the permissions on my media files are right. When I try to access the website, which is hosted behind a reverse proxy (nginx:

server {
	listen 443 ssl;
        listen [::]:443 ssl;

        include snippets/ssl-common.conf;

        server_name candy.mydomain.com;

	location / {
		proxy_set_header        Host            $host;
                proxy_set_header        X-Real-IP       $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
		proxy_pass http://127.0.0.1:8000;
	}
}

). The site access works just fine, but when I try to log in with [email protected] and foobar, I get a 422 (unprocessable entity) response. Is this related to me being too dumb to set up a reverse proxy or is it your program thats to blame?

Media.sync times out

On any library of significant size, clicking "Sync" under settings times out. This should queue a background job.

Settings Page issue with transcode bitrate

I was having trouble saving my discogs_token to the database, and when I dug in, it's because of an issue with the transcode bitrate not validating on subsequent updates:

> Setting.update!(transcode_bitrate: 192)
=>
[#<Setting:0x0000aaaad6d7cd88
  id: 1,
  values: {"media_path"=>"/media/Media/Music", "discogs_token"=>nil, "transcode_bitrate"=>"192", "allow_transcode_lossless"=>"true"},
  singleton_guard: 0>]

> Setting.update!(discogs_token: "SItOwyWsYJLovzLcQIABnzTMDfFwXwciyFHOyIuu")
/var/www/black_candy/shared/bundle/ruby/3.0.0/gems/activerecord-7.0.2.2/lib/active_record/validations.rb:80:in `raise_validation_error': Validation failed: Transcode bitrate is not included in the list (ActiveRecord::RecordInvalid)

I haven't yet spotted why the validation isn't treating the value like an integer after the first write, but wanted to get this reported.

Media should sync on media library changes

It was strange to me to install the software and have to go manually do a sync to show my media.

What do you think about automatically running a sync on boot, optionally perhaps if there are no songs or something?

App

Will there be an android app?

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.