Playing sound files from expansion file - android

I have an expansion file with a series of sound files. The longer ones are .mp3 files while the shorter sound effects are .wav files. I pack them in a .zip file with no compression. I use the Zip File reader and downloader library provided by Google.
I'm opening the sound files like so:
MediaPlayer mPlayer;
...
AssetFileDescript asd = expansionFile.getAssFileDescriptor(fileName);
FileDescriptor soundFile = asd.getFileDescriptor();
mPlayer = new MediaPlayer();
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setDataSource(soundFile);
mPlayer.prepare();
mPlayer.start();
The odd thing is that it plays the same sound file every single time. It seems to be whatever it finds first. The byte size for asd.getDeclaredLength() and asd.getLength() is exactly what it should be. This means the file descriptor is at least finding the file, but for some reason the MediaPlayer plays whatever random file it decides.
What exactly am I missing here? Any help would be greatly appreciated.
Thanks.

The first approximation is correct, except for when the zip file contains more than one file, then you should use:
mPlayer.setDataSource(asd.getFileDescriptor(), asd.getStartOffset(), asd.getLength());
You can get more information from this other question:
Play audio file from the assets directory
Please, also remember to close the AssetFileDescriptor just after setDataSource to media player:
asd.close();
http://developer.android.com/reference/android/media/MediaPlayer.html#setDataSource%28java.io.FileDescriptor,%20long,%20long%29

Related

Prevent MediaPlayer from play all mp3 files in the folder automatically

I'm from Taiwan and my English is pretty basic, thanks for your forgiveness.
I built a iPad app and published to App Store, which is a kind of communicating board (AAC for the person who has difficult on speaking). It has several buttons on main view and when user touch up one, the app will play a mp3 sound corresponding to that button. I've put all mp3 files on a folder and determining which one to play dynamically at run-time.
Recently I'm working on build the Android version of this app, but I meet a problem that is when I touch up one button on the view, the MediaPlayer play not only the corresponding one but keep playing all the rest mp3 files on the folder continuously. It doesn't happen on the development of iPad version. Any one can help me to resolve this problem and set the MediaPlayer up to working appropriately?
PS. I put all MP3 files on some sub-folders and put them on the "assets" folder. It because for some reasons, all mp3 files are using numeric file name (ex. 0123223.mp3), and which MP3 to play is according to which button user touched up, so I can't use R.raw.0123223 not only because the R class can't has a member named in numeric, but also the target mp3 file can only determining at run-time instead of compile-time, so I can't use the res/raw folder.
My code is as following:
private void PlayMP3(String mp3File) throws IOException {
AssetFileDescriptor afd = this.getAssets().openFd(mp3File);
MediaPlayer player = new MediaPlayer();
player.setOnCompletionListener(new OnCompletionListener(){
public void onCompletion(MediaPlayer mp) {
System.out.println(mp.getAudioSessionId() + " finished.");
}
});
player.setDataSource(afd.getFileDescriptor());
player.setLooping(false);
player.prepare();
player.start();
}
the parameter "mp3file" of PlayMP3 is a concatenated string of mp3 file path, according to the button user touched up.
Many thanks!
Your version would work if you had only that one file in the assets directory. The asset directory contents are put together one after another. So, if you do not specify where to start and how many bytes to read, the player will read up to the end as if they are one file.
You can accomplish what you want by using setDataSource with more arguments:
player.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
This will allow you to define the limits of the player and only play the song you specify in your string mp3File.
You did not post some code.
First step is to insert your sound file into the raw folder
Then, you need only a few lines of code:
MediaPlayer mediaPlayer = null;
mediaPlayer = MediaPlayer.create(getBaseContext(), R.raw.mysoundfile);
mediaPlayer.start();
When the application is closing, dont forget to "release" your media player:
mediaPlayer.release();
mediaPlayer = null;

Right place for putting mp3 files in an android project

Is there any folder like res/drawable for mp3 or generally audio files? If yes, what is it and how can I get access to it from the app?
The best place to put such .mp3 or any other files would be in the assets folder.
These files once stored will become a part of your android app itself and can be read easily. This tutorial describes it well.
AssetFileDescriptor afd = getAssets().openFd("AudioFile.mp3");
MediaPlayer player = new MediaPlayer();
player.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
player.prepare();
player.start();
Alternatively you can also store it in the raw folder and read it directly by specifying the path as the raw folder.
this can be played as:
int resID=getResources().getIdentifier(fname, "raw", getPackageName());
MediaPlayer mediaPlayer=MediaPlayer.create(this,resID);
Here are some steps you can easily follow.
Open the android studio with the project in which you want to add-on audio clip/media file.
Create a raw folder in the resources folder.
Add media file to the raw folder by simply copy and paste that to the raw folder.
Here we added a media file “ring.mp3”. Now open the Java File of the desired activity, here we are adding the audio in the MainActivity.
Further add this code.
MediaPlayer ring = MediaPlayer.create(MainActivity.this, R.raw.ring);
ring.start();
Now run the App and your music will play when App starts
You should save the .mp3 into res/raw. AndroidStudio recognizes the raw folder. (By contrast, it does not automatically recognize a res/assets folder).
To play music.mp3:
mediaPlayer = MediaPlayer.create(ctx, R.raw.cat_meow);
mediaPlayer.start();
Note the convenient use of R. syntax.
Place it into your assets folder. Preferably under assets/raw/myfile.mp3
You can access it using:
String mp3File = "raw/music.mp3";
AssetManager assetMan = getAssets();
MediaPlayer media = new MediaPlayer();
FileInputStream mp3Stream = assetMan.openFd(mp3File).createInputStream();
media.setDataSource(mp3Stream.getFD());
media.prepare();
media.start();

VideoView can play mp4 file in application data directory

While save mp4 file to /data/data/mypackage/files/my.mp4, then call VideoView's setVideoPath(); it can not work.
For the same file, if I save the file to /mnt/sdcard/my.mp4, then call the same VideoView's setVideoPath, it plays correctly.
Is there any way I can play mp4 file under /data/data/mypackage/files/?
The MP or VideoView uses a native player which cannot access non-worldreadable files.
So you have to options basically:
1) Make the created files world-readable
2) Open an input stream to the file in your program and just hand over the file descriptor to the media player:
FileInputStream fi = new FileInputStream(file);
MediaPlayer pl = new MediaPlayer();
pl.setDataSource(fi.getFD());
pl.prepare();
pl.start();
Also look at this thread VideoView/MediaPlayer doesn't play video from internal storage And find a Custom VideoView class code from here also look at this SO question Can a videoview play a video stored on internal storage?

Android Assets-Folder: it takes always the first file by alphabetical order

I'm new in Java/Android programming, so please have patience with me.
I try to play a mp3 which is locate und the assets folder. I know there is another way with the /res/raw/ folder, but use the assets-folder because later I'll try to access the file by String.
This code works to play a mp3-file:
try
{
MediaPlayer mp = new MediaPlayer();
FileDescriptor sfd = getAssets().openFd("song.mp3").getFileDescriptor();
mp.setDataSource(sfd);
mp.prepare();
mp.start();
}
catch(Exception e) {}
Now the problem: In the same assets-folder is another mp3 file stored. Though I specify the name of the mp3 to use it take the one which comes first in alphabet. E.g. the other file is named "music.mp3" it plays this one. Renaming it to "worldmusic.mp3" it will play "song.mp3". Rerename "worldmusic.mp3" back to "music.mp3" it will take this mp3 again. Another test: Renaming "song.mp3" to something other so the application can find whats specify by the code above will result that no song is played. So this means the songname have to exist, although it take arbitrary the song first in alphabet.
I'm testing with the AVD emulator of eclipse. But I think the behaviour would be the same on a real device.
Have someone an idea about this problem?
I don't believe using FileDescriptor is the right way to do this. Try using .create() and a Uri instead:
MediaPlayer mp = MediaPlayer.create(getBaseContext(), songUri);
mp.start();
Not sure why, but the URI syntax doesn't seem to work for the assets. Try getting the AssetFileDescriptor instead, as answered in the related question:
Play audio file from the assets directory

Using java with android how can I get the path of my resources files?

I added some audio files to the res file.
first I created a raw dir and then I added the folder with the audio files.
How can I get each file path? (I want to use the path to play this audio files)
I found that I need to use
classLoader.getResource
but I don't understand how. what is the argument for this function?
A reference should be added to your R class that you can get as something like R.raw.sound_file_1. Check out the Audio and Video section of the Android Developer's Guide for more details.
Once you have the reference to your audio clip you can play it by:
MediaPlayer mp = MediaPlayer.create(context, R.raw.sound_file_1);
mp.start();
So you don't really need the path to the resource at all, just use the reference.

Categories

Resources