Problem playing audio on android - java

Amendment: This appears to be a problem with the particular audio file I was using. Other applications on the droid such as the Astro file manager also fail to play it, and if I replace it in the package with an AAC file, it plays it without error. I encoded the problematic audio file to MP3 format from a WAV file, using LAME on ubuntu. It would be good to know the limitations of the android media player. mplayer seems to have no problem playing the file on ubuntu. I suppose I should submit a bug report.
Original question: The following code crashes when I try to play it on my droid. The error message given in the log is "Command PLAYER_INIT completed with an error or info PVMFErrNoResources." Then an IOException is raised on the mp.prepare() line. There is a file res/raw/bell.mp3 in my project directory, which I assume corresponds to R.raw.bell in the code below. I am building with "ant debug". In case it's relevant, when I created the project directory with "android create", I set the target number to 4, corresponding in my system to "android 2.0."
What am I doing wrong, here?
import java.io.IOException;
import android.app.Activity;
import android.os.Bundle;
import android.media.MediaPlayer;
import android.util.Log;
public class testapp extends Activity
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
try {
MediaPlayer mp = MediaPlayer.create(this, R.raw.bell);
mp.prepare();
mp.start();
} catch (IOException e) {
Log.v(getString(R.string.app_name), e.getMessage());
}
}
}

You do not need to call prepare() if you use the static create() method to get the MediaPlayer. It does the prepare() step for you. You only need to call prepare() if you either use the regular MediaPlayer constructor or if you are trying to reset the clip back to the beginning to play back from the existing MediaPlayer object.
Here is a sample project for playing back sounds (in my case, an Ogg clip).

Related

Java, Javafx MediaPlayer, doesn't seem to release mp3 file, even when using .dispose() method

So, I've searched around quite a bit, and haven't found anything that resolves this. (found someone asking in 2016, with no answers and did it somewhat differently, also I've found some that didn't care if the file was deleted on exit, or on next start up, which I do)
I have an application where I have one button for letting a user pick an mp3 file on the computer, and one button that let's the user play that sound back, when the user is done, he/she can click a save button that is supposed to delete the mp3 file that is stored in the user's folder, and then replace it with the new one the user picked, they are supposed to do this continuously, so deleting the previous file on exit isn't very good, as it could lead to a big heap of temp files that needs to be deleted on exit, and checked for on launch.
so, from what I can gather it seems to be a Windows-centric problem where a file opened in mediaplayer isn't released properly(or something like that, was a bit hard to follow..), so I was wondering if there is a way to force the MediaPlayer object to release the Media object/file, or maybe a way to find out and have a listener for when the dispose() method is done doing it's thing, so that I can delete the file while the java program continues to run afterwards?
here is a code snippet to illustrate the problem.
import javafx.application.Application;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.stage.Stage;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class Main extends Application {
public static void main(String[] args){launch(args);}
#Override
public void start(Stage primaryStage) throws Exception {
Path path = Paths.get("some/file/path.mp3"); //making a path for the Media object and for deleting later
Media media = new Media(path.toUri().toString()); //Making a Media object for the Mediaplayer
MediaPlayer mediaPlayer = new MediaPlayer(media); //Making a MediaPlayer
mediaPlayer.play(); //playing just to make sure it has been used
mediaPlayer.stop(); //stopping the player
mediaPlayer.dispose(); //disposing of the MediaPlayer
//checking to see that the MediaPlayer has been disposed of at least
try {
if (mediaPlayer.getStatus().equals(MediaPlayer.Status.DISPOSED)) {
Files.delete(path); //trying to delete, and subsequently crashing..
}
} catch (Exception e) {
e.printStackTrace();
}
System.exit(0); //terminating program
}
}
edit(added the exception thrown(replacing my actual path with the dummy one)):
java.nio.file.FileSystemException: some/file/path.mp3: The process cannot access the file because it is being used by another process.
my current thought on a solution is to have a file where I mark files for deletion when the program starts next, and keeping track of what files should be copied over to the user folder then.
or maybe even not actually saving the files in the users folder, and rather keeping a reference to the users files in a text file or something or other, while I just have a general "sounds folder" that I can get things from..
or something like that, but I thought I'd at least ask you people if you had any ideas on how to solve it as I initially wanted to do it.
Really sorry if this should end up as a duplicate, I haven't really found any answers that have helped when searching for this, but if you do, then please send me on my way over to wherever that is :)
Thank you for any Ideas you might have, and hope the English is understandable, also, if you want any more info or anything, please let me know :)
Edit 2:
So, I've found a "bad" workaround, where I use the AudioInputStream to play a sound with a Clip, as here I can control the stream, and close it before deleting the file, this seems to work quite well, only problem with this is that I am now limited to wav files(afaik), but I can work with that for now at least, but not leaving it as an answer, as a MediaPlayer solution would be far better imo.
Edit 3(forgot to add the code)(got the audio part from here: https://stackoverflow.com/a/11025384/10044355):
Path path = Paths.get("some/file/path.wav");
File yourFile = new File(path.toString());
AudioInputStream stream = null;
AudioFormat format;
DataLine.Info info;
Clip clip;
try {
stream = AudioSystem.getAudioInputStream(yourFile);
}catch (Exception e){
e.printStackTrace();
}
format = stream.getFormat();
info = new DataLine.Info(Clip.class, format);
clip = (Clip) AudioSystem.getLine(info);
clip.open(stream);
clip.start();
clip.stop();
stream.close();
Files.delete(path);

Cordova app - Use ringer volume instead of media in Android

I'm using Cordova v4.1.2. The app uses media volume by default, and I want it to use the ringer volume for the sounds it plays. (Like in WhatsApp)
I used setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);in the onCreate() function. But it gives an error.
This is my CordovaApp.java. (in platforms\android\src\com\XX\XX)
import android.os.Bundle;
import org.apache.cordova.*;
public class CordovaApp extends CordovaActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
super.init();
// Set by <content src="index.html" /> in config.xml
loadUrl(launchUrl);
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
}
}
It shows the following error on running:
There is no error when I remove the line setVolumeControlStream(AudioManager.STREAM_VOICE_CALL); from the java file, and the app runs perfectly. Any views on how to fix this?
Fixed it myself. Really easy if you were an Android geek, but anyways such a question was never asked before so I'll post the answer for others running into this same trouble.
I was right in changing the audio stream, but I was changing that in the wrong file! Doh!
This is where you should change it..
\platforms\android\CordovaLib\src\org\apache\cordova\CordovaActivity.java
at line 351 change it to setVolumeControlStream(AudioManager.STREAM_RING);
If you want to use the ringer volume though.
If you build and press the hardware volume keys, it will change and appear to use the ringer volume of course. But my case was a bit different.
I was using the cordova Media plugin org.apache.cordova.media. So when I play an audio using this plugin, it re-wires the stream back to media stream (STREAM_MUSIC). I was back to ground zero. The idea is to re-wire the plugin itself to use the audio stream of your choice. No rocket science, just change 2 lines in 2 files.
File:
\platforms\android\src\org\apache\cordova\media\AndroidHandler.java
Line 383:
setVolumeControlStream(AudioManager.STREAM_RING);
File:
\platforms\android\src\org\apache\cordova\media\AudioPlayer.java
Line 526:
setVolumeControlStream(AudioManager.STREAM_RING);
And you're good to go. Remember to replace STREAM_RING with your desired audio stream.

Android Mediaplayer

i want to play an audio on my android app using the Mediaplayer class.
my problem is on the R.java part.
to better understand my problem, i'll have to show a part of my code
audioControl = MediaPlayer.create(context, R.raw.forward_100hz);
audioControl.start();
so, the problem is on the forward_100hz, which is my wav file which is stated that it cannot be resolved or it is not a field.
how can i resolve this problem?
I think the problem is with your imports. Probably you've already imported the android.R class, but not the R class of your project.
Make sure the file is stored in the folder res/raw
Try deleting the R file generated by eclipse if the file is in place
Make sure the file forward_100hz is in res/raw folder
Check your imports and remove import android.R;
If on Eclipse press Ctrl + Shift + O to auto suggest import and you should import
import your.package.name.R;
If 3 does not work check your manifest file and then res directory for error which might be causing the problem by not generating R.java
As the second parameter of the create method put the following path:
Uri path = Uri.parse("android.resource://<package-name>/"+ R.raw.forward_100hz);
First sure that folder/raw exists and create the Mediaplayer before of on create
MediaPlayer player;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
player=MediaPlayer.create(MainActivity.this,R.raw.forward_100hz);
player.start();
}
}

Android developer newbie unable to launch code in the emulator

Background:
I have started Android recently. I want to make an application for Android that fetches data from a server and customizes it , displays it and then use Twitter to tweet the results. I am thinking to use (twitter4j API for this.).
Initially i have a PERL file on server that i need to call from my application's interface. (I have modified code of HelloWorld.java available at (dev.android..). The PERL file which i have stored on the server has the output in form of print "" I would be using the collective print output and decode them in my application.
Now my code is as follows :
package com.example.helloandroid;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class HelloWorldAndroidActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv=new TextView(this);
/* tv.setText("Hello, World !! This is my First Android App .. Cheers");
setContentView(tv);*/
try {
InputStream is = new URL("http://myserver.com:1941/cgi-bin/myperl.pl").openStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String str = in.readLine();
in.close();
tv.setText(str);
setContentView("phew");
} catch (MalformedURLException e) {
//FAIL
} catch (IOException e) {
//FAIL
}
}
}
However i am not able to use the code to get the data from the server file as Eclipse emulator shows up but does not displays anything except the "shinny android logo".
Is there any way i can read that file? Also i would like you seniors to suggest me some startup/dummies book fro Android development.
How long do you want for the emulator to boot up? It can take upwards of two minutes to boot up. It's kind of slow in that respect. Try giving it a little time to actually get to the home screen. Also, is your logcat saying anything interesting?
Also, you're doing a network operation on the main UI thread. NEVER do this. You need to move your network operations on to a different thread. For more details, read Painless Threading.

how to view youtube video

I am finding great difficulties to view YouTube videos in my app.
here is my code:
package com.example.webvideo;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.widget.MediaController;
import android.widget.VideoView;
public class WebVideo extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
VideoView vv = (VideoView) findViewById(R.id.videoView);
MediaController mc = new MediaController(this);
mc.setAnchorView(vv);
vv.setMediaController(mc);
vv.setVideoURI(Uri.parse("http://youtu.be/2OIOOb-0t44"));
vv.start();
}
}
The emulator is showing an error that the video cannot be played.
What am I doing wrong? Am I giving the URL in a wrong format?
I would expect that the URI you need to give is to the actual media file to be played. I wouldn't count on redirects working either... and anyway that redirect you give seems to point to a YouTube web page, which I sure wouldn't expect the video player to be able to render.
http://youtu.be/2OIOOb-0t44 is certainly an invalid URL. Maybe you meant http://youtube.com/watch?v=2OIOOb-0t44?
The URL you are using is for the webpage where you can view it, not for the video itself. The embedding URL appears to be http://www.youtube.com/embed/2OIOOb-0t44, but I think it's HTML5, not flash... you may have to go old school and track down an AVI or MPEG file.

Categories

Resources