DEV Community

Cover image for Build a simple Music Player with AWS Amplify and React
Toan Nguyen Truong
Toan Nguyen Truong

Posted on

Build a simple Music Player with AWS Amplify and React

Introduction

Hello everyone, I finally finished my mini project and this is also my first post - a fledgling developer from Vietnam.

In this article, I would like to share the process of learning and building a simple music player using AWS Amplify and ReactJS.

Technology

  • AWS Amplify
  • AWS AppSync
  • AWS S3
  • AWS DynamoDB
  • AWS Cognito
  • React JS
  • GraphQL
  • Material UI

Project initialization

Create React app

Yeah, I'm a backend developer and it's my first time trying it.

npx create-react-app musicplayer
cd musicplayer
npm start
Enter fullscreen mode Exit fullscreen mode

Everything is very good, the whole project structure is instantiated.

Amplify configure

First we need to install amplify-cli to facilitate the setup related to Amplify on our computer. Let's use the command:

npm i -g @aws-amplify/cli
Enter fullscreen mode Exit fullscreen mode

At the project directory (musicplayer), run the command:

amplify configure
Enter fullscreen mode Exit fullscreen mode

Follow the instructions on the command line to set up access to your AWS account, these include:

  • Choose region
  • Set username for the new IAM user
  • Redirect to AWS console to check and set permissions, get Access key ID and secret access key

And after creating a new IAM user, you will use that account to develop applications with different defaults from Amplify when you run the amplify init command. At this point, you should be able to view your application when accessing the AWS Amplify service as shown below:

AWS Amplify init

Add create account, sign in, sign out

Execute the command below to add authentication functions to the application:

amplify add auth
Enter fullscreen mode Exit fullscreen mode

At this step, I choose email as the way for users to register for an account. Other ways can be selected and easily changed by updating them on your AWS console. After every Amplify-related change or update, you need to run the command amplify push to save them in the cloud.

AWS Amplify automatically generates the amplify directory and the aws-exports.js file containing the config information that the application needs to use.

Install the necessary packages:

npm i aws-amplify @aws-amplify/ui-react
Enter fullscreen mode Exit fullscreen mode

In file App.js:

import { Amplify, API, graphqlOperation, Storage } from 'aws-amplify';
import { withAuthenticator } from '@aws-amplify/ui-react';
import configure from "./aws-exports";
Amplify.configure(configure);
function App({ signOut, user }) {
//...
return (
    //...
    )
}
//...
export default withAuthenticator(App);
Enter fullscreen mode Exit fullscreen mode

With the help of AWS Amplify, adding authentication capabilities to your application is really fast.

Create account screen

Sign in screen

Use DynamoDB and GraphQL for API

Run the command:

amplify add api
Enter fullscreen mode Exit fullscreen mode

In this step, I choose to use the GraphQL API with the schema template being a single object with fields and the default authorization type for the API is Amazon Anonymous User Pools. And below is the schema sample generated by Amplify:

type Todo @model {
  id: ID!
  name: String!
  description: String
}
Enter fullscreen mode Exit fullscreen mode

With my needs for this application, I want the schema to save the information for a song, so I modified the model as follows:

type Song @model {
  id: ID!
  name: String!
  description: String!
  filePath: String!
  heart: Int!
  author: String!
}
Enter fullscreen mode Exit fullscreen mode

After finishing editing the model, I pushed my changes to AWS and accepted when asked if I wanted to generate code for the newly created GraphQL API. That way, AWS Amplify creates for me a graphql directory in the src folder containing mutations, queries, and subscriptions. I can use these APIs right away without any modification.

Function to get a list of songs:

import { API, graphqlOperation } from 'aws-amplify';
import { listSongs } from "./graphql/queries";
//...
const [songs, setSongs] = useState([]);
const getSongs = async () => {
    try {
      const songData = await API.graphql(graphqlOperation(listSongs));
      setSongs(songData.data.listSongs.items)
    } catch (error) {
      console.error('error on get songs: ', error);
    }
  }
Enter fullscreen mode Exit fullscreen mode

Increase the number of favorites when the user clicks on the heart icons:

import { updateSong } from "./graphql/mutations";
//...
const increaseHeart = async index => {
    try {
      const song = songs[index];
      song.heart += 1;
      delete song.createdAt;
      delete song.updatedAt;

      const songData = await API.graphql(graphqlOperation(updateSong, { input: song }));

      const songList = [...songs];
      songList[index] = songData.data.updateSong;
      setSongs([...songs]);
    } catch (error) {
      console.error('error on increase heart: ', error);
    }
  }
Enter fullscreen mode Exit fullscreen mode

Try adding some records to DynamoDB and start the application to see the results of the functions.

Add data to DynamoDB

I use Material UI for faster front-end development. The image source I get is random from Unsplash with the category being music with the id of each song to limit getting duplicate images.

const image = `https://source.unsplash.com/random/200x200/?music&id=${song.id}`
Enter fullscreen mode Exit fullscreen mode

My application at the moment:

Music player UI

Storage audio on S3

To use S3 for storing the application's audio, we run the command:

amplify add storage
Enter fullscreen mode Exit fullscreen mode

then choose the content type to store, set the bucket name, who can access it, the permissions of the auth users, and whether to use a lambda trigger... finally run amplify push to finish set up.

Implement music play/pause functionality, using AWS Amplify's Storage class to get access URLs of songs.

import { Storage } from 'aws-amplify';
//...
const [songPlaying, setSongPlaying] = useState('');
const [audioURL, setAudioURL] = useState('');

const toggleSong = async index => {
    if (songPlaying === index) {
      setSongPlaying('')
      return
    }

    const songFilePath = songs[index].filePath;
    try {
      const fileAccessURL = await Storage.get(songFilePath, { expires: 60 })
      setSongPlaying(index);
      setAudioURL(fileAccessURL);
      return;
    } catch (error) {
      console.error('error accessing the file from S3: ', error);
      setAudioURL('');
      setSongPlaying('');
    }
}
Enter fullscreen mode Exit fullscreen mode

Upload audio files to S3 and update filePath fields in records in DynamoDB.

Upload file to S3

Update data in DynamoDB

The product is complete, now we can play and stop the tracks, and drop the heart for our favourite music.

Music player completed

Deploy and host app

You may eventually want to deploy and host your application. You can follow the instructions in the link below:

https://aws.amazon.com/getting-started/guides/deploy-webapp-amplify/module-three/

Here are 2 access links to my deployed app:
https://master.d2knwrz36tm5yc.amplifyapp.com/
https://d2wvly4638hbyf.cloudfront.net/

Link GitHub repository:
https://github.com/nguyentruongtoan1309/musicplayer

This is my first post, I hope to receive your support and suggestions.

Yes, it's done. This is just a simple demo application for applying AWS Amplify to building a web application with ReactJS, all the work is done very quickly and easily. You can improve based on my app, some of the things that can be thought of are allowing users to share songs they like with others, adding comments, chatting... Of course, the knowledge in this article is very limited, and AWS Amplify does much more than that.

Resources

See original post here

If the article is interesting and useful to you, you can give me a cup of coffee. Thanks for reading.

Buy Me A Coffee

Top comments (0)