Android Tutorial MediaPlayer tutorial

The MediaPlayer is used to play audio files.
MediaPlayer supports formats like: mp3, midi, wave and ogg. The full list is available here: Android Supported Media Formats | Android Developers

In order to play an audio file we first need to load the file:
B4X:
MediaPlayer1.Load(File.DirAssets, "IsawHerStandingThere.mid")
In this case the file was added with the file manager and therefore File.DirAssets is used.

Now we can start playing the file with:
B4X:
MediaPlayer1.Play
and pause the playback with:
B4X:
MediaPlayer.Pause
Calling Play will resume from the same position.
Note that you can only call Pause while MediaPlayer is playing.

You can call MediaPlayer.Load at any point (after initialization), and load a new file.
MediaPlayer should be declared in Process_Globals otherwise a new instance will be created each time the activity is recreated.

The program attached is a small program that allows the user to see the playback progress and to change the position.

mediaplayer_1.png


This is the code:
B4X:
Sub Process_Globals
    Dim MediaPlayer1 As MediaPlayer
    Dim timer1 As Timer
End Sub

Sub Globals
    Dim barPosition As SeekBar
    Dim barVolume As SeekBar
    Dim lblPosition As Label
    Dim Looping As ToggleButton
End Sub

Sub Activity_Create(FirstTime As Boolean) 
    If FirstTime Then
        MediaPlayer1.Initialize( )
        MediaPlayer1.Load(File.DirAssets, "IsawHerStandingThere.mid")
        Timer1.Initialize("timer1", 1000)
    End If
    Activity.LoadLayout("1")
    Looping_CheckedChange(Looping.Checked) 'set the default value
End Sub

Sub Activity_Resume
    MediaPlayer1.Play
    timer1.Enabled = True
    timer1_Tick 'don't wait one second for the UI to update.
End Sub

Sub Activity_Pause (UserClosed As Boolean)
    If MediaPlayer1.IsPlaying Then MediaPlayer1.Pause
    timer1.Enabled = False
End Sub

Sub timer1_Tick
    If MediaPlayer1.IsPlaying Then
        barPosition.Value = MediaPlayer1.Position / MediaPlayer1.Duration * 100
        lblPosition.Text = "Position: " & ConvertToTimeFormat(MediaPlayer1.Position) & _
            " (" & ConvertToTimeFormat(MediaPlayer1.Duration) & ")"
    End If
End Sub
'converts milliseconds to m:ss format.
Sub ConvertToTimeFormat(ms As Int) As String
    Dim seconds, minutes As Int
    seconds = Round(ms / 1000)
    minutes = Floor(seconds / 60)
    seconds = seconds Mod 60
    Return NumberFormat(minutes, 1, 0) & ":" & NumberFormat(seconds, 2, 0) 'ex: 3:05
End Sub

Sub barVolume_ValueChanged (Value As Int, UserChanged As Boolean)
    MediaPlayer1.SetVolume(barVolume.Value / 100, barVolume.Value / 100)
End Sub

Sub barPosition_ValueChanged (Value As Int, UserChanged As Boolean)
    If UserChanged = False Then Return 'the value was changed programmatically
    MediaPlayer1.Position = Value / 100 * MediaPlayer1.Duration
    If MediaPlayer1.IsPlaying = False Then 'this can happen when the playback reached the end and the user changes the position
        MediaPlayer1.Play
    End If
    timer1_Tick 'immediately update the progress label
End Sub

Sub Looping_CheckedChange(Checked As Boolean)
    MediaPlayer1.Looping = Checked
End Sub
We are initializing MediaPlayer only once when the application starts.
Playing starts when the activity resumes, which happens right after the Create event.

A timer is used to check the playback position every second and update the label and seek bar.
Note that the seekbar ValueChanged position includes a boolean value named UserChanged which you can use to differentiate between changes done by the user (by dragging the thumb) and changes done programmatically.

The Looping property determines whether playback will restart automatically when it reaches the end.
 

Attachments

  • MediaPlayer.zip
    9.5 KB · Views: 6,804

stevel05

Expert
Licensed User
Longtime User
You can change the speed of the playback with both the SoundPool and AudioTrack libraries, although neither allow keeping the pitch the same at present.
 

stevel05

Expert
Licensed User
Longtime User
SoundPool does, but it is limited in the size of file it will handle. AudioTrack uses raw audio files, there is an example of using a wav file in the post with the library.

You would need to implement a decoder to play MP3 Files with AudioTrack.
 

StevieC

Member
Licensed User
Longtime User
I'm planning on working with songs. I expect that they're likely to be too large for Soundpool. Do you know of any example/library code available for decoding mp3 files?
 

stevel05

Expert
Licensed User
Longtime User
Not currently, a quick look on google shows that there are some Java libraries available that could probably be wrapped to work with B4A, although it's difficult to tell how much work it would be without some investigation.
 

thatguy

New Member
Licensed User
Longtime User
Sleep

When the phone goes into sleep mode (turns the screen off), the media player stops. How can I allow the screen to go off and still have the media player running?
 

sally3599

Member
Licensed User
Longtime User
Load a mp3 on the website

I change MediaPlayer1.Load(File.DirAssets, "IsawHerStandingThere.mid") to MediaPlayer1.Load("http://website/my.mp3"), it show when compile:
B4X:
Compiling code.                         Error
Error compiling program.
Error description: Missing parameter.
Occurred on line: 17
MediaPlayer1.Load("http://website/my.mp3")
Word: )
but actually it worked
B4X:
Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("Main")
            ProgressDialogShow("Loading ...")
            If FirstTime Then
               mp.Initialize("mp")
            End If
               mp.Load("http://website/my.mp3")
               mp.looping = True
End Sub

Any suggestion?
 

moster67

Expert
Licensed User
Longtime User
I think you can use GetVolume from PhoneLibrary:

B4X:
'Returns the volume of the specified channel.
'Channel - One of the VOLUME constants.

'GetVolume (Channel As Int) As Int    

p.GetVolume(p.VOLUME_MUSIC) ' p =PhoneLibrary
 

AscySoft

Active Member
Licensed User
Longtime User
I think you can use GetVolume from PhoneLibrary
Thanks for the answer. Is not what I want, but I learned a new thing instead.
The Phone library and the VOLUME_MUSIC constant - like the other ones from this class - refer to device volume, who control: ALARM, RINGER, VOICE_CALL etc (<<Phone object includes information about the device and also other general features.>> quote from documentation)

The volume in my app is set using mediaplayer lib, so is not the same.

B4X:
Sub Process_Globals
Dim MP As MediaPlayer
End Sub
Sub Service_Create
MP.Initialize2 ("SongEnd_DoSomething") 'continue to the next song etc
End Sub

...
'at some point user slide the seek bar, for simplicity we assume is at 50%
MP.SetVolume(0.50, 0.50) ' letf,right 50% from current VOLUME_MUSIC
In this case, the Phone VOLUME_MUSIC stay the same...
So, how could one get Volume of played song?
PS: my code is from a service module, I know
 

AscySoft

Active Member
Licensed User
Longtime User
The native MediaPlayer class doesn't have a getVolume method. However if you are setting the volume then you can also store this value.
I was afraid someone will say this. Of course is possible to store this with a global variable... but... well is a little harder later, because I will try to fade out/in songs, and later on even crossfading. If there is no other way to do it, I will try this way.
 

AscySoft

Active Member
Licensed User
Longtime User
Ok, another quick question regard MediaPlayer Class
On the MediaPlayer | Android Developers) is a method called setNextMediaPlayer for API level 16
Is it possible to call this in any way? It will be?
It sounds like
B4X:
mp.Initialize2("SongEnded_DoSomething")
but from the docs we read <<The next player can be set at any time before completion>>
I guess this could be used in a cross between tracks application?!?
 

AscySoft

Active Member
Licensed User
Longtime User
Are you targeting Android 4.1 only?

No, not really. I create a mp3 app for me (Android 2.5.3) witch work from GUI or from service module.. and now I like to create fade in, fade out effect and to play another file and to create a crossfading effect.

Right now I don't think is possible to create such an app using MediaPlayer from B4A.

Do you have another suggestion for me? Thanks for your time.
 

nad

Active Member
Licensed User
Longtime User
Hello Erel,

Do you know if it is posible to get mp.position for a mediaplayerstream maybe with reflection? I would like to use a seekbar while streaming. Or the only option is download and then play as mediaplayer?

Thanks
 
Top