Skip to content

Instantly share code, notes, and snippets.

@Erk-
Last active September 16, 2023 23:23
Show Gist options
  • Save Erk-/54ba341e7fa84bfc701a4f2547cef798 to your computer and use it in GitHub Desktop.
Save Erk-/54ba341e7fa84bfc701a4f2547cef798 to your computer and use it in GitHub Desktop.
Play directly from spotify (or other mopidy sources)

Play directly from spotify

Intro

This guide helps you setup a configuration like: mopidy -> icecast -> listner (bot) Where you can use mopidy to play from a wide selection of sources for example Spotify. At the moment I know of no Discord bots capable of controlling an mpd/mopidy server so the adding of playlists have to go through a webinterface or similar. In this guide I will focus on setting up Spotify. The full config files will also be in the gist.

Mopidy

Installation

The oficcial documentation have guides for installing Mopidy: https://docs.mopidy.com/en/latest/installation/

You will also need to install mopidy-spotify and a interface, I am using Iris, but other interfaces should work.

Config

You can get your ID and SECRET using this tool: https://www.mopidy.com/authenticate/#spotify (NOTE: You have to have Spotify Premium for this to work)

~/.config/mopidy/mopidy.conf

[core]
max_tracklist_length = 10000

[logging]
color = true
console_format = %(levelname)-8s %(message)s
debug_format = %(levelname)-8s %(asctime)s [%(process)d:%(threadName)s] %(name)s\n  %(message)s
debug_file = mopidy.log

[audio]
mixer = software
mixer_volume = # Default if no value set is 100.
output = lamemp3enc ! shout2send mount=mopidy ip=127.0.0.1 port=8000 password=hackme

[file]
enabled = false

[http]
enabled = true
hostname = 0.0.0.0 # Will have to be this to take request from outside of localhost.
port = 6680
static_dir =
zeroconf = Mopidy HTTP server on $hostname

[iris]
country = gb   # Can be changed to match your local country and locale.
locale = en_GB

[spotify]
username = USERNAME
password = PASSWORD
client_id = ID
client_secret = SECRET

Icecast2

Installation

You can either get Icecast though you distros pacakge repo (NOTE: It may be called Icecast2 (Ubuntu)) or get it from the official site

Config

Because mopidy does not work properly with streams of audio you will need to setup a fallback stream. (mopidy#1306) This can be done by adding the following to your icecast config file, add it where the commented mounts are as well:

/etc/icecast.xml

<mount>
  <mount-name>/mopidy</mount-name>
  <fallback-mount>/silence.mp3</fallback-mount>
  <fallback-override>1</fallback-override>
</mount>

You will also need to add a mp3 file containing silence in the folder specified by <webroot>...</webroot> in /etc/icecast.xml I am using the 500 ms of silence from anars/blank-audio (NOTE: I am not sure this is optimal, I have to test more.)

Conclusion

Startup

The best way to start is;

  1. Start the Icecast2 server # systemctl start icecast.service
  2. Start the mopidy server $ mopidy (NOTE: Can also be run as an service)
  3. Add music to the playlist.
  4. Connect the bot ;;play http://example.com/mopidy

Known Erros

  • The stream may become unresponsive if you skip a lot of songs or have it is paused for an extended amount of time. (This may have something to do with the length of silence.mp3)
  • You have to use a webinterface (This could be solved by having a secondary bot to connect to the mpd/mopidy server)
<icecast>
<!-- location and admin are two arbitrary strings that are e.g. visible
on the server info page of the icecast web interface
(server_version.xsl). -->
<location>Earth</location>
<admin>icemaster@localhost</admin>
<!-- IMPORTANT!
Especially for inexperienced users:
Start out by ONLY changing all passwords and restarting Icecast.
For detailed setup instructions please refer to the documentation.
It's also available here: http://icecast.org/docs/
-->
<limits>
<clients>100</clients>
<sources>2</sources>
<queue-size>524288</queue-size>
<client-timeout>30</client-timeout>
<header-timeout>15</header-timeout>
<source-timeout>10</source-timeout>
<!-- If enabled, this will provide a burst of data when a client
first connects, thereby significantly reducing the startup
time for listeners that do substantial buffering. However,
it also significantly increases latency between the source
client and listening client. For low-latency setups, you
might want to disable this. -->
<burst-on-connect>1</burst-on-connect>
<!-- same as burst-on-connect, but this allows for being more
specific on how much to burst. Most people won't need to
change from the default 64k. Applies to all mountpoints -->
<burst-size>65535</burst-size>
</limits>
<authentication>
<!-- Sources log in with username 'source' -->
<source-password>hackme</source-password>
<!-- Relays log in with username 'relay' -->
<relay-password>hackme</relay-password>
<!-- Admin logs in with the username given below -->
<admin-user>admin</admin-user>
<admin-password>hackme</admin-password>
</authentication>
<!-- This is the hostname other people will use to connect to your server.
It affects mainly the urls generated by Icecast for playlists and yp
listings. You MUST configure it properly for YP listings to work!
-->
<hostname>localhost</hostname>
<!-- You may have multiple <listener> elements -->
<listen-socket>
<port>8000</port>
<!-- <bind-address>127.0.0.1</bind-address> -->
<!-- <shoutcast-mount>/stream</shoutcast-mount> -->
</listen-socket>
<http-headers>
<header name="Access-Control-Allow-Origin" value="*" />
</http-headers>
<mount>
<mount-name>/mopidy</mount-name>
<fallback-mount>/silence.mp3</fallback-mount>
<fallback-override>1</fallback-override> <fileserve>1</fileserve>
</mount>
<paths>
<!-- basedir is only used if chroot is enabled -->
<basedir>/usr/share/icecast</basedir>
<!-- Note that if <chroot> is turned on below, these paths must both
be relative to the new root, not the original root -->
<logdir>/var/log/icecast</logdir>
<webroot>/usr/share/icecast/web</webroot>
<adminroot>/usr/share/icecast/admin</adminroot>
<!-- <pidfile>/usr/share/icecast/icecast.pid</pidfile> -->
<!-- Aliases: treat requests for 'source' path as being for 'dest' path
May be made specific to a port or bound address using the "port"
and "bind-address" attributes.
-->
<!--
<alias source="/foo" destination="/bar"/>
-->
<!-- Aliases: can also be used for simple redirections as well,
this example will redirect all requests for http://server:port/ to
the status page
-->
<alias source="/" destination="/status.xsl"/>
<!-- The certificate file needs to contain both public and private part.
Both should be PEM encoded.
<ssl-certificate>/usr/share/icecast/icecast.pem</ssl-certificate>
-->
</paths>
<logging>
<accesslog>access.log</accesslog>
<errorlog>error.log</errorlog>
<!-- <playlistlog>playlist.log</playlistlog> -->
<loglevel>3</loglevel> <!-- 4 Debug, 3 Info, 2 Warn, 1 Error -->
<logsize>10000</logsize> <!-- Max size of a logfile -->
<!-- If logarchive is enabled (1), then when logsize is reached
the logfile will be moved to [error|access|playlist].log.DATESTAMP,
otherwise it will be moved to [error|access|playlist].log.old.
Default is non-archive mode (i.e. overwrite)
-->
<!-- <logarchive>1</logarchive> -->
</logging>
<security>
<chroot>0</chroot>
<changeowner>
<user>nobody</user>
<group>nobody</group>
</changeowner>
</security>
</icecast>
[core]
max_tracklist_length = 10000
[logging]
color = true
console_format = %(levelname)-8s %(message)s
debug_format = %(levelname)-8s %(asctime)s [%(process)d:%(threadName)s] %(name)s\n %(message)s
debug_file = mopidy.log
[audio]
mixer = software
mixer_volume = # Default if no value set is 100.
output = lamemp3enc ! shout2send mount=mopidy ip=127.0.0.1 port=8000 password=hackme
[file]
enabled = false
[http]
enabled = true
hostname = 0.0.0.0 # Will have to be this to take request from outside of localhost.
port = 6680
static_dir =
zeroconf = Mopidy HTTP server on $hostname
[iris]
country = gb # Can be changed to match your local contry and locale.
locale = en_GB
[spotify]
username = USERNAME
password = PASSWORD
client_id = ID
client_secret = SECRET
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment