Skip to main content

AlxndrJhn

DLF-Nova Play My Own Music

The DLF nova playlist is just a few hours long, leading to a lot of repetitions if you listen long enough. This is kind of annoying, because the news-bits are quite interesting. So I programmed a script that detects music/news and switches to spotify during the music parts on the radio.

This project is work in progress, I want to make it easier to use.

Requirements

Get started

  1. To use the Spotify API a client id and client secret are needed, it can be created here
    1. Save SPOTIPY_CLIENT_ID in your environment (example 1a2ef9787cc1638261545d6dadb2315)
    2. Save SPOTIPY_CLIENT_SECRET in your environment (example 2c12e5161ace0476c8f2abc70a924ac76)
  2. Find your spotify username and insert it in spotify_username in online_prototype.py
  3. Install with pip install DLF-Nova-Play-My-Own-Music
  4. dlfnova -su my.spotifyusername to start

After some setup messages it should generate logs like this

19:20:34: Class:  music, prob.:  96%, filtered signal:   0%, AI performance:  3.3Hz
19:20:36: Class:  music, prob.:  66%, filtered signal:   0%, AI performance:  3.5Hz
19:20:39: Class:   news, prob.:  84%, filtered signal:  70%, AI performance:  3.3Hz
19:20:42: Class:   news, prob.:  99%, filtered signal:  91%, AI performance:  3.3Hz switch to radio
[00000282eb2c49d0] prefetch stream error: unimplemented query (264) in control
19:20:44: Class:   news, prob.: 100%, filtered signal:  97%, AI performance:  2.8Hz
19:20:47: Class:   news, prob.: 100%, filtered signal:  99%, AI performance:  3.4Hz
19:20:49: Class:   news, prob.: 100%, filtered signal:  100%, AI performance:  3.3Hz

Technical details

I trained a simple deep learning model to classify an audio single as "music" or "news", using this classifications, I switch between my spotify device and the online radio stream.

Dataset

The dataset consists of:

To split training (80%) and test (20%) datasets, the files are separated randomly before splitting into chunks. The mp3 files are split into 10s chunks (no overlapping) at 44100Hz. Each chunk is converted to the feature vector, making the dataset files relatively small.

Input vector/features

Based on this this medium article and this article I chose three features: MFCC (related to speech/music separation, from librosa), GFCC (typical used for speaker recognition, from spafe) and onset_strength (related to beat detection in music, from librosa). It results in a 256 dimensional vector.

# feature vector
mfccs = librosa.feature.mfcc(y=audio, sr=sample_rate, n_mfcc=20)
mfccs_scaled = np.mean(mfccs.T, axis=0)

try:
    gfccs = gfcc(audio, num_ceps=20)
    gfccs_scaled = np.mean(gfccs, axis=0)
except Exception:
    gfccs_scaled = np.zeros(20)

hop_length = 2048
oenv = librosa.onset.onset_strength(y=audio, sr=sample_rate, hop_length=hop_length)

return np.hstack((mfccs_scaled, gfccs_scaled, oenv))

Where audio is always a 10 second audio chunk at 44100Hz sample rate.

Deep learning model

I used the Keras model from this medium article

model = Sequential()

model.add(Dense(256, input_shape=(input_size,)))
model.add(Activation("relu"))
model.add(Dropout(0.5))

model.add(Dense(256))
model.add(Activation("relu"))
model.add(Dropout(0.5))

model.add(Dense(num_labels))
model.add(Activation("softmax"))

model.compile(loss="categorical_crossentropy", metrics=["accuracy"], optimizer="adam")

where input_size is 256.

It trained for 100 epochs, default learning rate, batch size 256 and saved the weights with the lowest validation loss.

Performance

It achieved 99.8% accuracy during training and 98% for the validation set.

Switching

The script online_prototype.py registers through the spotify API and requests with OAUTH permission to see the devices and modify the player state. It downloads the DLF stream in 40kB chunks and outputs an classification every 2 to 3 seconds. This signal is smoothed and it triggers switching events. The radio is streamed via VLC.

Known issues

  • Some songs are classified as news sometimes, due to the simple model. Happens with rap especially. The news sometimes have a beat in the background as well.
  • [00000282eb2c49d0] prefetch stream error: ... logs, they come from VLC

TODO

  1. Train better model for fewer switching errors
  2. Fading the sound during the switch event

Metadata

Release files for dlf-nova-play-my-own-music 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dlf-nova-play-my-own-music 0.1.3
File Size Uploaded Provenance Actions
DLF-Nova-Play-My-Own-Music-0.1.3.tar.gz 7.6 MB Without provenance Details for DLF-Nova-Play-My-Own-Music-0.1.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for dlf-nova-play-my-own-music 0.1.3
File Interpreter ABI Platform Actions
DLF_Nova_Play_My_Own_Music-0.1.3-py3-none-any.whl Python 3 none any Details for DLF_Nova_Play_My_Own_Music-0.1.3-py3-none-any.whl

Total release size: 15.4 MB

Release files / DLF-Nova-Play-My-Own-Music-0.1.3.tar.gz

Download URL DLF-Nova-Play-My-Own-Music-0.1.3.tar.gz
Size 7.6 MB
Tags Source
SHA-256 checksum
How to use checksums
33e1baba762d8490b30c3398ab267d7906c423668a1c64c428cee65727dbcd72
BLAKE2b-256 checksum
How to use checksums
a901eb25e224268ab22c3c0f9c77ec9ad8269f74a4c7300db6be6358368ffb72
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.6.0 requests-toolbelt/0.8.0 tqdm/4.46.0 CPython/3.7.5

Release files / DLF_Nova_Play_My_Own_Music-0.1.3-py3-none-any.whl

Download URL DLF_Nova_Play_My_Own_Music-0.1.3-py3-none-any.whl
Size 7.7 MB
Tags Python 3
SHA-256 checksum
How to use checksums
8771e81a665a68c776244cf2f85364e7c49cb984e9e13fc888508de947090162
BLAKE2b-256 checksum
How to use checksums
2a61a7c216e4d1fa1fd33803d2dff4658938d5f6c71daf28ad09e89b304075fa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/3.1.1 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.6.0 requests-toolbelt/0.8.0 tqdm/4.46.0 CPython/3.7.5

Security for dlf-nova-play-my-own-music 0.1.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.3 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page