Get $500+ of the best After Effects files, video templates and music for only $20!
Corona SDK: Creating a Music Player App – Final Steps

Corona SDK: Creating a Music Player App – Final Steps

Tutorial Details
  • Technology: Corona SDK
  • Difficulty: Intermediate
  • Completion Time: 45 Minutes

Welcome to the second part of our Corona SDK music player tutorial. In this part we’ll place the interface in stage, handle the app logic, button controls and the steps to build the final app.


Where We Left Off. . .

Please be sure to check part 1 of the series to fully understand this tutorial.

Step 1: Variables

These are the variables we’ll use. Read the comments in the code to know more about them, some of their names are self explaining so there will be no comment there.

-- Variables

local currentSong = 1
local playing
local timerSource
local min = 0
local sec = 0

Step 2: Functions

Declare all functions as local at the start.

-- Functions

local Main = {}
local buildGUI = {}
local playCurrentSong = {}
local stopSong = {}
local nextSong = {}
local prevSong = {}
local updateInfo = {}
local updateProgress = {}

Step 3: Main Function

Next we’ll create the function that will initialize all the app logic:

-- Main Function

function Main()
	buildGUI()
end

Step 4: Build the GUI

The following function places all of the GUI on the stage. It is built in the same order that we declared the variables, so you will easily identify each part by the variable names.

  function buildGUI()
  bg = display.newImage('background.png')
  infoBar = display.newImage('infoBar.png', 20, 168)
  imageMarker = display.newImage('imageMarker.png', 30, 178)
  cdCover = display.newImage('s1.png', 30, 178)

  titleText = display.newText('1. Here Without You', 117, 176, native.systemFontBold, 14)
  titleText:setTextColor(246, 237, 240)
  byText = display.newText('By', 121, 197, native.systemFont, 10)
  byText:setTextColor(191, 182, 183)
  artistText = display.newText('3 Doors Down', 137, 197, native.systemFontBold, 10)
  artistText:setTextColor(244, 204, 106)

  buttonBar = display.newImage('buttonBar.png', 20, 278)
  playBtn = display.newImage('playBtn.png', 25, 279)
  stopBtn = display.newImage('stopBtn.png', 27, 282)
  stopBtn.isVisible = false
  prevBtn = display.newImage('prevBtn.png', 55, 279)
  nextBtn = display.newImage('nextBtn.png', 85, 279)

  progressBar = display.newImage('progressBar.png', 126, 290)
  progress = display.newRoundedRect(0, 0, 100, 10, 3)
  progress:setFillColor(244, 204, 106)
  progress:setReferencePoint(display.TopLeftReferencePoint)
  progress.x = 126
  progress.y = 290
  progress.isVisible = false

  current = display.newText('00:00', 235, 288, native.systemFont, 9)
  current:setTextColor(246, 237, 240)
  total = display.newText('/00:00', 259, 288, native.systemFont, 9)
  total:setTextColor(191, 182, 183)

  playBtn:addEventListener('tap', playCurrentSong)
  stopBtn:addEventListener('tap', stopSong)
  nextBtn:addEventListener('tap', nextSong)
  prevBtn:addEventListener('tap', prevSong)
  end
  

We add the tap listeners of the buttons in the last lines and this will make the buttons perform the corresponding function when tapped.


Step 5: Play Current Song

This code runs when the play button is pressed.

It resets the song and time counters (in case it’s not the first time the button is pressed) and plays the song specified by the currentSong variable. After that, the playing variable is set to true, this will play the next or previous song automatically when the next or back buttons are pressed.

function playCurrentSong:tap(e)
	audio.rewind(songs[currentSong])
	sec = 0
	min = 0
	audio.play(songs[currentSong])
	playing = true
	updateInfo()
	timerSource = timer.performWithDelay(1000, updateProgress, 0)

	playBtn.isVisible = false
	stopBtn.isVisible = true
end

It also starts the timer to begin the song duration counter and hides the play button to reveal the stop button.


Step 6: Stop Song

When the stop button is pressed, the current song stops playing and the timer is cancelled. Buttons are returned to normal and playing is set to false.

function stopSong:tap(e)
	audio.stop()
	timer.cancel(timerSource)
	playBtn.isVisible = true
	stopBtn.isVisible = false
	playing = false
end

Step 7: Next Song

This function stops the current song and changes to the next in the Table, if the playing variable is set to
true it will play it automatically. It also checks if the next song is the last one, if that is the case it goes back to the first in the line.

function nextSong:tap(e)
	audio.stop()
	currentSong = currentSong + 1

	if(currentSong > #songs) then
		currentSong = 1
	end

	if(playing) then
		audio.rewind(songs[currentSong])
		sec = 0
		min = 0
		audio.play(songs[currentSong])
	end

	updateInfo()
end

Step 8: Previous Song

As you may imagine this function behaves in the same way as the previous one, just backwards.

function prevSong:tap(e)
	audio.stop()
	currentSong = currentSong - 1

	if(currentSong < 1) then
		currentSong = #songs
	end

	if(playing) then
		audio.rewind(songs[currentSong])
		sec = 0
		min = 0
		audio.play(songs[currentSong])
	end

	updateInfo()
end

Step 9: Update Information

This code (called in the past three functions) handles the information displayed in both bars.

It updates the album art, title, artist and times of the songs.

function updateInfo()
	titleText.text = tostring(currentSong) .. '. ' .. songsInfo[currentSong][2]
	titleText:setReferencePoint(display.TopLeftReferencePoint)
	titleText.x = 117
	artistText.text = songsInfo[currentSong][3]
	artistText:setReferencePoint(display.TopLeftReferencePoint)
	artistText.x = 137

	display.remove(cdCover)
	cdCover = nil
	local cdCover = display.newImage(songsInfo[currentSong][4], 30, 178)

	local totalMin = math.floor(audio.getDuration(songs[currentSong]) / 1000 / 60)--
	local totalSec = math.floor(audio.getDuration(songs[currentSong]) / 1000 % 60)--

	total.text = '/' .. totalMin .. ':' .. totalSec
	total:setReferencePoint(display.topLeftReferencePoint)
	total.x = 275
end

Step 10: Update Progress

Executed every second, this function updates the progress bar of the song based on the current position and the total duration of it.

Note that the methods used by the Corona API may return different results depending on the format of the audio files.

  function updateProgress:timer(e)
  sec = sec + 1

  if(sec == 60) then
  sec = 0
  min = min + 1
  end

  local secS = tostring(sec)

  if(#secS < 2) then
  sec = '0' .. sec
  end

  current.text = min .. ':' .. sec
  current:setReferencePoint(display.topLeftReferencePoint)
  current.x = 250

  -- Progress Bar

  local position = min .. sec
  position = position * 1000

  local duration = audio.getDuration(songs[currentSong])
  local percent = (position / duration)
  print(position, duration, percent)

  progress.isVisible = true
  progress.xScale = percent
  end

Step 11: Call the Main Function

In order to initially start the app, the Main function needs to be called. With the above code in place, we’ll do that here:

Main()

Step 12: Loading Screen

The Default.png file is an image that will be displayed right when you start the application while the iOS loads the basic data to show the Main Screen. Add this image to your project source folder, it will be automatically added by the Corona compliler.


Step 13: Icon

Using the graphics you created before you can now create a nice and good looking icon. The icon size for the non-retina iPhone icon is 57x57px, but the retina version is 114x114px and the iTunes store requires a 512x512px version. I suggest creating the 512×512 version first and then scaling down for the other sizes.

It doesn’t need to have the rounded corners or the transparent glare, iTunes and the iPhone will do that for you.


Step 14: Testing in the Simulator

It’s time to do the final test. Open the Corona Simulator, browse to your project folder, and then click open. If everything works as expected, you are ready for the final step!


Step 15: Build

In the Corona Simulator go to File > Build and select your target device. Fill the required data and click

build. Wait a few seconds and your app will be ready for device testing and/or submission for distribution!


Conclusion

Experiment with the final result and try to make your custom version of the app!

I hope you liked this tutorial series and find it helpful. Thank you for reading!

Add Comment

Discussion 6 Comments

  1. Han says:

    Hi Yanez ,

    Great tutorial. I would like to know is it possible to read remote mp3 from server?

    Thanks,
    Han

  2. Tommy says:

    When can we get new articles on Titanium?

  3. Han says:

    Hi Yanez ,
    Great tutorial. I would like to know is it possible to read remote mp3 from server?
    Thanks,
    Han

  4. Michael says:

    Hi There!

    Great little music player and I’m having fun building a UI for the Android platform. One problem I noticed is that the progress bar does not stop, both in the demo and my build.

    I’m not much of a programmer. How would I have the progress bar stop at 100%?

    Thanks in advance!

    Michael

  5. ron says:

    Hi Yanez,

    Great tutorial…BiG Thanks!!! just what I’ve been looking for… a newbie here, this would really be cool addition to my planned app.

    Quick question:

    I tried adding this to a scene in the storyboard and notice that the ” buildGUI ” (play, forward, rewind & etc buttons) carry over to the next scene. I tried inserting it to the group but gives an error. I also tried inserting it individually but still the same… any suggestion to go about this? I’m starting to pull my hair already :(

    Once again, many thanks!!!

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.