My hack idea is for a novel music app intended to help address centralization in the music industry by directly connecting listeners and artists.
The premise is an endless, tailored stream of music created by smaller artists in the community, which listeners can interact with in various ways in order to promote it within the platform. These interactions consist of those traditional to both music and social media apps, such as saving to a library, adding to playlists, liking, commenting, sharing, and more.
Listeners are played music based on selected genres, their own previous interactions, and interactions of other users (community popularity). They get to hear new and interesting music that they won't be exposed to in any other way, as existing music discovery tools and services are designed to maximize streams, generate ad revenue, or drive traffic to specific artists and genres, rather than provide the best possible recommendations.
Unestablished and smaller artists see even greater benefits, as they are given an effective way to promote their songs without huge advertising budgets, bypassing big labels or streaming services who take significant shares of revenue, and bringing attention and money back to the artists.
I was inspired for this project on two separate fronts, which came together into one problem, sparking the idea for this app.
The first problem I faced was personal music discovery: I was always looking for new music, but have always had trouble finding an effective solution. As I committed myself more towards finding an existing solution, I realized that I was unable to find a music recommendation service that was consistently effective. At first I had luck using Spotify's recommendation playlists such as "Daily Mix" and "Discover Weekly," however after a few weeks all I was hearing was repeated songs from those playlists that had skipped or decided I didn't want to keep listening to. Eventually, not only did they fail to provide new music, but Spotify actively made me 'custom' playlists composed exclusively of songs I did not like.
I found similar problems with other platforms, which either recommended me the same songs—exclusively because they had a lot of streams—or were buggy and full of crashes, enough for me to leave the platform, even if they were able to provide fresh music.
After this search, I realized that the most effective way I had actually been finding new music was through social media—whether it was friends sending me clips and videos, or seeing them myself on social platforms, the best recommendations had been coming from other people, rather than big companies within the industry.
On the other hand, I had already known a bit about many of the problems artists face within the music industry, however began to do more research as I thought about solutions to the first problem. I learned about the difficulties artists had gaining a following without the advertising budgets of labels, and learned about the extreme financial issues many artists face as a result of the significant majority of profits from their work going to labels and streaming services. Additionally, artists have to be involved significantly on the business side of their work in order to promote it and profit off of it. Both of these factors mean that artists are paying significant time and money to even have a chance of success in the current industry.
Therefore I see two significant problems in the music industry, one on the listener side, and one on the production side, but both created by corporate dominance over the industry. I therefore hoped to build an app to help decentralize it, and bring control back to listeners and artists, by connecting them directly through music within a social framework.
Features Needed for MVP
-UI (scalable across devices)
-Account & Auth system
-Music Player & Track Controls
-Queue and History Pages (To see what you are about to hear, and what you already have)
-Uploading and Retrieving Songs (From shared database, so that all users across devices have access to tracks)
-Social Interaction Features (liking, commenting, sharing, following artists)
-Playlists & Personal Song Libraries
-Recommendation Engine and Search Tools
Features Achieved during PennApps
-Built system with multiple navigation flows to navigate between pages (There are currently 7 views in the app)
✓UI (scalable across devices)
-Built a scalable, custom UI with two theme options (dark, and light)
✓Account & Auth system
-Built a user account and authentication system, powered by MongoDB Atlas and MongoDB Realm webhooks
✓Music Player & Track Controls
-Built a track player with a pause/play button, skip buttons, gesture controls, track information elements (retrieved from MongoDB Atlas), and a draggable, circular, progress slider
~Queue and History Pages (To see what you are about to hear, and what you already have)
-Built UI elements to represent the intended page layouts
-TODO: Connect pages to track player and database to complete functionality
~Uploading and Retrieving Songs (From shared database, so that all users across devices have access to tracks)
-Built a track upload system to send track titles and details to MongoDB Atlas database, using MongoDB Realm webhooks
-Built a track information retrieval system that pulls track titles and details from MongoDB (in the same way as above) into the music player
-TODO: Upload sound files (the music player currently plays local sound files as a placeholder)
-Built a system to retrieve the signed in user's name (MongoDB Realm Webhooks)
-TODO: Retrieve other user details in the same way the user's name is
~Social Interaction Features (liking, commenting, sharing, following artists)
-Built UI elements to represent the intended page layouts
-TODO: Link social interaction details to database; allow users to follow other users
✗Playlists & Personal Song Libraries
✗Recommendation Engine and Search Tools
How I built it
Expo is another open source framework which helps abstract away native elements, so that apps can be built for multiple platforms from the same code base. Since platform-specific elements will not be needed in this project, Expo was chosen to simplify some of the development process.
Another reason for choosing Expo was its online platform for running React Native in the browser, called 'Expo Snack'. This was needed for me as my laptop is under repair, and I have no permissions to install a proper development environment on my library loaner. Therefore, having a development environment entirely within the browser was significant in my decision to use React Native and Expo.
For a database for this project, I chose MongoDB, a popular noSQL database. I chose MongoDB due to its quality of documentation, free tier for implementing small projects, cloud features, and a JSON-based document style so that I could quickly customize data structures throughout development. MongoDB Atlas is a cloud database built upon MongoDB, that allows me to share information between users. MongoDB Realm is a development platform designed to interface MongoDB Atlas with data-driven applications, including those built upon React Native. Unfortunately, while there is React Native support, there is not Expo support, and so I had to connect to Realm using a series of HTTP webhooks, rather than a native library.
There were three significant imports I used to make my development process quicker. The first is react-navigation/bottom-tabs (https://reactnavigation.org/docs/bottom-tab-navigator/), which is essentially a prebuilt bottom tab navigator, and was used to create my lower tab navigator (however my upper navigator and login navigation is custom). The other is react-native-rapi-ui (https://rapi-ui.kikiding.space/docs/themeColors), which is a UI library, used almost entirely for buttons and colors. I came across it while doing some project research, and liked the button style enough to use it a few times. Finally, I updated and adapted the code in https://github.com/steveliles/react-native-circular-slider-example for use in the circular slider in the music player.
As described, my development process took place entirely within the browser, and as such progressed fairly slowly, especially due to reasons detailed later. To view and test my app, I compiled it onto either an Android emulator, or my personal phone (Samsung S8).
Challenges I ran into
A significant challenge I faced the entire time was my limited browser development environment. In addition to the obvious inconveniences (small programming windows, limited testing tools, slow simulators, etc), the update on type/save feature of React Native was completely broken in my project. In a normal React Native project, development moves quickly, especially when styling elements and designing views, as the app refreshes your changes in real-time, so a recompile between every edit is not usually needed unless there are significant changes to cached resources that need to be reloaded. However in my dev environment, this feature was completely broken, and unfortunately recompiling wouldn't update changes either—I could only view my changes after refreshing the emulator entirely, waiting in a queue for others to stop using the shared Expo emulators, and compile the app on that new emulator.
A few development challenges I faced along the way included custom fonts not working, handling MongoDB auth and http header parsing, and creating context elements for sharing user details across app views.
I struggled for a while trying to implement custom fonts, as anything I tried would be overridden by the default platform font. I solved it when I noticed that the Text elements were importing from the wrong source: react-native-rapi-ui, instead of react-native. I didn't realize at the time, but that UI library doesn't support custom fonts, so switching the import source fixed this.
Another challenge I spent significant time facing was interfacing the app with MongoDB Realm, especially figuring out permissions problems. All of my HTTP requests returned empty objects until I discovered how to properly configure the application secret, email and password credentials, Atlas permissions, Realm permissions, and webhook permissions to work together to read and write to the database from the app.
A third development challenge was figuring out how to properly use Context elements. Normally, to pass data between screens, data props must be sent between each screen, making it complicated to send parameters between navigation flows as they get more complex. Context elements solve this, distributing parameters directly to individual screens. However they were difficult for me to understand at first, and I spent a while trying to learn how to properly use them.
Accomplishments that I'm proud of
I am particularly proud of figuring out how to interface with MongoDB Realm, especially after I was initially discouraged by the lack of support for Expo.
I am also proud of the general UI and feel of the app, as I feel I succeeded in designing a clean, well put-together UI and UX (for the completed parts of the app)
What I learned
While I learned a lot about development with React Native, I think I learned the most about MongoDB and interfacing with cloud databases, as well as this explanation side of hacks. I have participated in high school hackathons in the past, however have usually spent the entire time on my hack, and leave little time at the end to think about questions like these. However this time I dedicated much more time to thinking about the progress of my project, and I think that brought more meaning to it overall.
What's next for this app
For the next steps to finish an MVP for this app, I will finish the TODOs outlined in the earlier section, and from there try to work on more advanced features, such as improving the auth system, adding new views, and making quality-of-life changes so that it can reach a production-ready form.