While working and walking, I often listen to background music. I used to use an Internet radio called Jango , which was fine with almost everyone, except for the following things:
- inaccessibility during almost daily walks in the forest (i.e. without an Internet connection).
- The need to switch between different channels in order to change the genre of music. In other words, the listener of Jango has little chance of discovering new musical genres.
One day the idea came up with a mobile application for listening to music, which could work most of the time without the Internet (i.e. cache music) with automatic detection of user's musical addictions. I haven’t seen anything like this (maybe I just looked badly?), So I decided to implement it myself. Now, after several months of coding in my spare time from the main work, I published the first, still very raw, but already working version of the Android application .
I wanted to implement an application with a very simple and intuitive interface (in fact, with only two buttons: "pause" and "skip"), but with sufficiently advanced internal logic to analyze musical preferences (based on collecting statistics on the duration of listening to tracks before skipping) and caching tracks. Since I did not want to duplicate the logic for different platforms, it was decided to implement it in C ++ (which is the "common denominator" for iOS and Android).
For storing metadata about tracks, as well as user preferences, I chose SQLite. Album and music cover files are stored in a three-level hash-based directory tree (similar to how it works in Git).
512 MiB chose the cache size (these and any other digits, of course, can be configured). The logic of the rotation of the tracks is as follows: 20 tracks are downloaded per update iteration. After the user has listened to each track at least twice, a new update is initiated. Tracks are deleted for which the average listening time is lower than the specified limit, and the metadata of new tracks is downloaded from the server, after which their download begins.
The playback logic is as follows. The longer the average listening time for a track, the more often it is played.
As an experienced C ++ developer, I did not experience much difficulty in implementing the logic described above (although in reality it is somewhat more complicated). However, having no experience writing applications for Android, I had to spend a lot of time and effort on implementing the corresponding software layer (especially the UI). I am sure that many things are now implemented not in the best way.
I decided to write an Android wrapper in Kotlin. In fact, Java did not promise any advantages, because you would still have to mess with JNI (in iOS, the situation would be different, there Objective-C is much more convenient than Swift in terms of integration with native core logic code).
I used Fuel to download JSON metadata, and Fetch to download files (I was surprised that Fuel is not able to efficiently download files). By the way, to the second library I have complaints about the stability of work.
The server code was written in Golang and uses PostgreSQL through reform . The current metadata database was built by indexing the Free Music Archive , and in the future I plan to index other open sources as well. Tracks on the server are not yet stored to save space (I save on hosting), but directly refer to the source repository.
The server collects statistics of listening to tracks for each of the users. Thus, each musical genre is assigned a preference score that affects the likelihood of choosing the appropriate compositions during rotation.
I will be glad if you try my application. Suddenly you will like it. Surely during use you will encounter bugs (the program is still raw). The speed of their correction will directly depend on the demand for my work.