I have been trying to do it in different ways, but all the "lists" want int or string and I have Assetfiledescriptor stuff to work with.
How can I create a list of certain mp3 files, which are located in the activity expansionfile, that I can use for oncompletionlisteners, etc?
They all work fine individually, but I want to play them after each other.
Here are a few files that I would use:
AssetFileDescriptor dfFn01, dfFn02, dfFn03 = null;
dfFn01 = expansionFile.getAssetFileDescriptor("l1r_df_l6.mp3");
dfFn02 = expansionFile.getAssetFileDescriptor("l1r_df_l7.mp3");
dfFn03 = expansionFile.getAssetFileDescriptor("df_jp_l1r03.mp3");
Here is the player that starts from a buttonclick:
public void setWholeEngAudio(AssetFileDescriptor fd) throws IllegalStateException {
try {
stopPlayers();
wholeTextPlayer = new MediaPlayer();
wholeTextPlayer.reset();
wholeTextPlayer.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
try {
wholeTextPlayer.prepare();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
wholeTextPlayer.start();
seekBar.setProgress(0);
seekBar.setMax(100);
updateSeekBar();
setThumbState();
} catch (Exception e) {
e.printStackTrace();
}
}
Thanks
i am creating an application that in it i need to play some sounds with low bit rates such as 16kbps.
I use MediaPlayer with below code. but it cannot play and i get Error(100, 0) in logcat. when i replace audio with 48kbps OGG file or 128kbps MP3 file all thing is ok. How i can play audio with 16kbps bit rate?
I have this problem only on Kitkat
player = new MediaPlayer();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
try {
Class<?> cMediaTimeProvider = Class.forName("android.media.MediaTimeProvider");
Class<?> cSubtitleController = Class.forName("android.media.SubtitleController");
Class<?> iSubtitleControllerAnchor = Class.forName("android.media.SubtitleController$Anchor");
Class<?> iSubtitleControllerListener = Class.forName("android.media.SubtitleController$Listener");
Constructor constructor = cSubtitleController.getConstructor(new Class[]{Context.class, cMediaTimeProvider, iSubtitleControllerListener});
Object subtitleInstance = constructor.newInstance(activity, null, null);
Field f = cSubtitleController.getDeclaredField("mHandler");
f.setAccessible(true);
try {
f.set(subtitleInstance, new Handler());
} catch (IllegalAccessException ignored) {
} finally {
f.setAccessible(false);
}
Method setsubtitleanchor = player.getClass().getMethod("setSubtitleAnchor", cSubtitleController, iSubtitleControllerAnchor);
setsubtitleanchor.invoke(player, subtitleInstance, null);
//Log.e("", "subtitle is setted :p");
} catch (Exception e) {
}
}
player.setWakeMode(activity,
PowerManager.PARTIAL_WAKE_LOCK);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
this.seekbar = seekbar;
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
finalTime = player.getDuration();
timeElapsed = mediaPlayer.getCurrentPosition();
seekbar.setMax(finalTime);
init();
remaining.setText(miliToTime(finalTime));
elapsed.setText("0:00:00");
durationHandler.postDelayed(updateSeekBarTime, 100);
}
});
player.setOnErrorListener(this);
player.setDataSource(musicPath);
player.prepareAsync();
i'm developing a little quizz app and i would like to play sound depending on if the user answers the question correctly or not.
I've got many sound files in "assets/".
What I would like to do is to play just one of these sounds.
I've been able to play the sound, but not only one, both sound (correct and incorrect) are played one after the other.
How can i play just one?
Here's my source:
public void audioPlayer(){
//set up MediaPlayer
mp = new MediaPlayer();
try {
String mp3File = "correct.mp3";
AssetManager assetMan = getAssets();
FileInputStream mp3Stream = assetMan.openFd(mp3File).createInputStream();
mp.setDataSource(mp3Stream.getFD());
mp.prepare();
mp.start();
} catch (Exception e) {
e.printStackTrace();
}
}
Put your sound files i.e fail and applause in raw folder and use the following code :
private AssetFileDescriptor sPlaySoundDescriptor = null;
private AssetFileDescriptor sFailSoundDescriptor = null;
private MediaPlayer mp = null;
public static final int FAIL_SOUND = 1;
public static final int APPLAUSE_SOUND = 2;
public void audioPlayer(int soundType){
//set up MediaPlayer
mp = new MediaPlayer();
AssetFileDescriptor soundFileDescriptor = null;
try {
if (sFailSoundDescriptor == null) {
sFailSoundDescriptor = context.getResources().
openRawResourceFd(R.raw.fail);
}
if (sApplauseSoundDescriptor == null) {
sApplauseSoundDescriptor = context.getResources().
openRawResourceFd(R.raw.applause);
}
switch (soundType) {
case FAIL_SOUND:
soundFileDescriptor = sFailSoundDescriptor;
break;
case APPLAUSE_SOUND:
soundFileDescriptor = sApplauseSoundDescriptor;
break;
}
mp.reset();
mp.setDataSource(soundFileDescriptor.getFileDescriptor(),
soundFileDescriptor.getStartOffset(),
soundFileDescriptor.getDeclaredLength());
mp.prepare();
mp.setOnPreparedListener(new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer player) {
player.seekTo(0);
player.start();
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
I need to play random sound out of 300 sounds placed in assets folder.
While implementing the problem I am getting is that its always playing the first sound from assets on button click.
MediaPlayer player;
AssetFileDescriptor descriptor;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.machine);
player = new MediaPlayer();
playSound = (ImageButton)findViewById(R.id.button_play);
AssetManager aMan = this.getAssets();
try
{
filelist = aMan.list("");
} catch (IOException e1) {
e1.printStackTrace();
}
playSound.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
Random randomGenerator = new Random();
int randomInt = randomGenerator.nextInt(filelist.length);
try
{
String mediaFile = filelist[randomInt];
descriptor = getAssets().openFd(mediaFile);
player.setDataSource(descriptor.getFileDescriptor(),descriptor.getStartOffset(),descriptor.getLength());
descriptor.close();
player.prepare();
player.start();
}
catch (Exception e) {
e.printStackTrace();
}
}
}
}
Try changing this line:
filelist = aMan.list("");
to this:
filelist = aMan.list("/assets");
I have the following code:
AssetFileDescriptor afd = getAssets().openFd("AudioFile.mp3");
player = new MediaPlayer();
player.setDataSource(afd.getFileDescriptor());
player.prepare();
player.start();
The problem is that, when I run this code, it starts playing all the audio files in the assets directory, in alphabetical order instead of just playing the audio file I requested. What am I doing wrong? Is there a better way to play audio files from the assets directory?
Follow-up question:
Is there a difference between keeping audio files in the assets directory and keeping them in the res/raw directory? Besides the fact that they don't get ids if they are in the assets directory. If I move the audio files to the res/raw folder then I have a problem with reusing MediaPlayers because there is no id parameter for setDataSource(). I can't find a good guideline for handling this kind of problem.
player.setDataSource(afd.getFileDescriptor(),afd.getStartOffset(),afd.getLength());
Your version would work if you had only one file in the assets
directory. The asset directory contents are not actually 'real files'
on disk. All of them 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 (that is, will keep playing all the files in assets
directory)
This function will work properly :)
// MediaPlayer m; /*assume, somewhere in the global scope...*/
public void playBeep() {
try {
if (m.isPlaying()) {
m.stop();
m.release();
m = new MediaPlayer();
}
AssetFileDescriptor descriptor = getAssets().openFd("beepbeep.mp3");
m.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
descriptor.close();
m.prepare();
m.setVolume(1f, 1f);
m.setLooping(true);
m.start();
} catch (Exception e) {
e.printStackTrace();
}
}
Here my static version:
public static void playAssetSound(Context context, String soundFileName) {
try {
MediaPlayer mediaPlayer = new MediaPlayer();
AssetFileDescriptor descriptor = context.getAssets().openFd(soundFileName);
mediaPlayer.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());
descriptor.close();
mediaPlayer.prepare();
mediaPlayer.setVolume(1f, 1f);
mediaPlayer.setLooping(false);
mediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
}
}
start sound
startSound("mp3/ba.mp3");
method
private void startSound(String filename) {
AssetFileDescriptor afd = null;
try {
afd = getResources().getAssets().openFd(filename);
} catch (IOException e) {
e.printStackTrace();
}
MediaPlayer player = new MediaPlayer();
try {
assert afd != null;
player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
} catch (IOException e) {
e.printStackTrace();
}
try {
player.prepare();
} catch (IOException e) {
e.printStackTrace();
}
player.start();
}
Fix of above function for play and pause
public void playBeep ( String word )
{
try
{
if ( ( m == null ) )
{
m = new MediaPlayer ();
}
else if( m != null&&lastPlayed.equalsIgnoreCase (word)){
m.stop();
m.release ();
m=null;
lastPlayed="";
return;
}else if(m != null){
m.release ();
m = new MediaPlayer ();
}
lastPlayed=word;
AssetFileDescriptor descriptor = context.getAssets ().openFd ( "rings/" + word + ".mp3" );
long start = descriptor.getStartOffset ();
long end = descriptor.getLength ();
// get title
// songTitle=songsList.get(songIndex).get("songTitle");
// set the data source
try
{
m.setDataSource ( descriptor.getFileDescriptor (), start, end );
}
catch ( Exception e )
{
Log.e ( "MUSIC SERVICE", "Error setting data source", e );
}
m.prepare ();
m.setVolume ( 1f, 1f );
// m.setLooping(true);
m.start ();
}
catch ( Exception e )
{
e.printStackTrace ();
}
}
this works for me:
public static class eSound_Def
{
private static Android.Media.MediaPlayer mpBeep;
public static void InitSounds( Android.Content.Res.AssetManager Assets )
{
mpBeep = new Android.Media.MediaPlayer();
InitSound_Beep( Assets );
}
private static void InitSound_Beep( Android.Content.Res.AssetManager Assets )
{
Android.Content.Res.AssetFileDescriptor AFD;
AFD = Assets.OpenFd( "Sounds/beep-06.mp3" );
mpBeep.SetDataSource( AFD.FileDescriptor, AFD.StartOffset, AFD.Length );
AFD.Close();
mpBeep.Prepare();
mpBeep.SetVolume( 1f, 1f );
mpBeep.Looping = false;
}
public static void PlaySound_Beep()
{
if (mpBeep.IsPlaying == true)
{
mpBeep.Stop();
mpBeep.Reset();
InitSound_Beep();
}
mpBeep.Start();
}
}
In main activity, on create:
protected override void OnCreate( Bundle savedInstanceState )
{
base.OnCreate( savedInstanceState );
SetContentView( Resource.Layout.lmain_activity );
...
eSound_Def.InitSounds( Assets );
...
}
how to use in code (on button click):
private void bButton_Click( object sender, EventArgs e )
{
eSound_Def.PlaySound_Beep();
}