As I understand it, Android will only play AAC format audio if it's encoded as MPEG-4 or 3GPP.
I'm able to play AAC audio encoded as M4A when it's local to the app, but it fails when obtaining it from a server.
The following works, as the m4a file is held locally in the res/raw directory.
MediaPlayer mp = MediaPlayer.create(this, R.raw.*file*);
mp.start();
The following doesn't work. (But does with MP3's).
Uri uri = Uri.parse("http://*example.com*/blah.m4a");
MediaPlayer mp = MediaPlayer.create(this, uri);
mp.start();
Can anyone shed any light on why it fails when the m4a audio file is not local?
Here's (some of) the error...
ERROR/PlayerDriver(542): Command PLAYER_INIT completed with an error or info UNKNOWN PVMFStatus
ERROR/MediaPlayer(769): error (200, -32)
WARN/PlayerDriver(542): PVMFInfoErrorHandlingComplete
DEBUG/MediaPlayer(769): create failed:
DEBUG/MediaPlayer(769): java.io.IOException: Prepare failed.: status=0xC8
DEBUG/MediaPlayer(769): at android.media.MediaPlayer.prepare(Native Method)
DEBUG/MediaPlayer(769): at android.media.MediaPlayer.create(MediaPlayer.java:530)
DEBUG/MediaPlayer(769): at android.media.MediaPlayer.create(MediaPlayer.java:507)
...
I'm targeting SDK 1.6.
This work-around allows you to play M4A files from the net (and AAC files in other containers such as MP4 & 3GP). It simply downloads the file and plays from the cache.
private File mediaFile;
private void playAudio(String mediaUrl) {
try {
URLConnection cn = new URL(mediaUrl).openConnection();
InputStream is = cn.getInputStream();
// create file to store audio
mediaFile = new File(this.getCacheDir(),"mediafile");
FileOutputStream fos = new FileOutputStream(mediaFile);
byte buf[] = new byte[16 * 1024];
Log.i("FileOutputStream", "Download");
// write to file until complete
do {
int numread = is.read(buf);
if (numread <= 0)
break;
fos.write(buf, 0, numread);
} while (true);
fos.flush();
fos.close();
Log.i("FileOutputStream", "Saved");
MediaPlayer mp = new MediaPlayer();
// create listener to tidy up after playback complete
MediaPlayer.OnCompletionListener listener = new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
// free up media player
mp.release();
Log.i("MediaPlayer.OnCompletionListener", "MediaPlayer Released");
}
};
mp.setOnCompletionListener(listener);
FileInputStream fis = new FileInputStream(mediaFile);
// set mediaplayer data source to file descriptor of input stream
mp.setDataSource(fis.getFD());
mp.prepare();
Log.i("MediaPlayer", "Start Player");
mp.start();
} catch (Exception e) {
e.printStackTrace();
}
}
I tried it too but I could not find out the solution!
At the last Google I/O I saw something that helped me a lot. It is Extending from MediaPlayer and improve a lot of things! Take a look.
EXOPLAYER CAN HELP YOU A LOT
Check this part of the example:
private static final int BUFFER_SEGMENT_SIZE = 64 * 1024;
private static final int BUFFER_SEGMENT_COUNT = 256;
...
// String with the url of the radio you want to play
String url = getRadioUrl();
Uri radioUri = Uri.parse(url);
// Settings for exoPlayer
Allocator allocator = new DefaultAllocator(BUFFER_SEGMENT_SIZE);
String userAgent = Util.getUserAgent(context, "ExoPlayerDemo");
DataSource dataSource = new DefaultUriDataSource(context, null, userAgent);
ExtractorSampleSource sampleSource = new ExtractorSampleSource(
radioUri, dataSource, allocator, BUFFER_SEGMENT_SIZE * BUFFER_SEGMENT_COUNT);
audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);
// Prepare ExoPlayer
exoPlayer.prepare(audioRenderer);
EXOPLAYER- I can play anything from streamings (video and audio)!
LET ME KNOW IF YOU NEED HELP TO IMPLEMENT IT! :)
This is a wild shot in the dark, but I have seen similar behavior with the flash player where it actually ignores the file name and only relies on the MIME type sent by the server. Any idea what headers are being sent down from example.com? You might want to try wrapping your blah.m4a in a page that can set the headers and then stream the binary data. Give these types a shot and the community would appreciate a confirmation of what works:
audio/mpeg
audio/mp4a
audio/mp4a-latm
audio/aac
audio/x-aac
I found that if you record the audio file on Android with the following properties, you are then able to play it on your server. It also plays well in the HTML Audio Element, however only on Firefox at the moment. This may change in the future.
Android (JAVA):
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC);
mediaRecorder.setAudioSamplingRate(44100);
mediaRecorder.setAudioChannels(1);
mediaRecorder.setOutputFile(filePath);
HTML:
<audio id="audioMediaControl" controls src="yourfile.m4a"> Your browser does not support the audio element. </audio>
try --
1) MP.prepareAsync()
2) onPrepared() { mp.start() }
Related
I want to create a media player with multiple sounds and play one at random when a button is clicked.
I tried using the MediaPlayer.create() function but I can only set one audio source.
I also tried using the setDataSource() function but this only seems to work for resources that are stored outside the application (as far as I know).
String meowsounds[] = new String[]{
"R.raw.meowcat1",
"R.raw.meowcat2",
"R.raw.meowcat3",
"R.raw.meowcat4",
"R.raw.meowcat5",
};
MediaPlayer mp = new MediaPlayer();
meow.setOnClickListener((view) ->{
Random random = new Random();
int r = random.nextInt(6-1) + 1;
try{
mp.setDataSource(meowsounds[r]);
mp.prepare();
mp.start();
}catch(Exception e){e.printStackTrace();}
});
This code doesn't give any error while running but doesn't play anything on click
EDIT: Updated code which works on first click but not on subsequent clicks:
meow.setOnClickListener((view) ->{
Random random = new Random();
int r = random.nextInt(6-1) + 1;
Toast.makeText(MainActivity.this,Integer.valueOf(r).toString(),Toast.LENGTH_SHORT).show();
try{
if(r==1)
fileDescriptor = MainActivity.this.getResources().openRawResourceFd(R.raw.meowcat1);
else if (r==2)
fileDescriptor = MainActivity.this.getResources().openRawResourceFd(R.raw.meowcat2);
else if (r==3)
fileDescriptor = MainActivity.this.getResources().openRawResourceFd(R.raw.meowcat3);
else if (r==4)
fileDescriptor = MainActivity.this.getResources().openRawResourceFd(R.raw.meowcat4);
else
fileDescriptor = MainActivity.this.getResources().openRawResourceFd(R.raw.meowcat5);
mp.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(), fileDescriptor.getLength());
mp.prepare();
mp.start();
}catch(Exception e){e.printStackTrace();}
});
R - is the class with constants. "R.raw.meowcat1" - is the simple string and it is not constant which consider link to file.
First, you need to create int array of raw constants, but not string array of simple strings.
Second, If you want to play file from raw, you need to create AssetFileDescriptor for this raw file and use in setDataSource method. For example:
AssetFileDescriptor fileDescriptor = getContext().getResources().openRawResourceFd(R.raw.meowcat1);
mediaPlayer.setDataSource(fileDescriptor.getFileDescriptor(), fileDescriptor.getStartOffset(), fileDescriptor.getLength());
And don't forget please release codec in onDestroy method.
I want to create a microphone app on Android that will receive sound through the microphone and play through the speakerphone but I don't know exactly what classes and services I should use.
The core of your answer is to:
A) record and store, as stated here.
MediaRecorder recorder = new MediaRecorder();
String status = Environment.getExternalStorageState();
if(status.equals("mounted")){
String path = Environment.getExternalStorageDirectory().toString()+"/YOURFOLDER"; // your custom path
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); // notice that this is the audio format, and you might want to change it to [other available audio formats][2]
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(path);
recorder.prepare();
// To start recording
recorder.start();
// To stop recording
recorder.stop();
recorder.release();
} else {
// Handle the situation
}
[Other available audio formats | 2]
B) Get recordings, as stated partially here. You should then show them.
try {
String path = Environment.getExternalStorageDirectory().toString()+"/YOURFOLDER"; // your custom path
File directory = new File(path);
File[] files = directory.listFiles();
} catch {
// Handle errors (or maybe no files in the directory)
}
C) Play recordings, as stated partially here.
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(Environment.getExternalStorageDirectory().toString()+"/YOURFOLDER"+"/yourfilename.formatextension"; // your custom pathare to use the file format and directory you used when saving
mp.prepare();
mp.start();
Hope this answer helps!
As the title, how can I stream an m3u8 audio on Android without vitamio? (on Android 2.3+). I've seen that some app can stream my my link http://4metest1-view.4me.it/api/xpublisher/resources/weebopublisher/getContentDescriptor.m3u8?clientId=4metest1&contentId=b55f7d74-cd81-48ce-9390-d9ffd5c49281&channelType=STREAMHTTPIOS&v=4
like VLC or aqua Player, but i cannot setup mMediaPlayer to reproduce it.
Use a VideoView to play your audio with relaxing music :)
myVideoView = (VideoView)this.findViewById(R.id.myVideoView);
MediaController mc = new MediaController(this);
myVideoView.setMediaController(mc);
urlStream = "http://4metest1-view.4me.it/api/xpublisher/resources/weebopublisher/getContentDescriptor.m3u8?clientId=4metest1&contentId=b55f7d74-cd81-48ce-9390-d9ffd5c49281&channelType=STREAMHTTPIOS&v=4";
runOnUiThread(new Runnable() {
#Override
public void run() {
myVideoView.setVideoURI(Uri.parse(urlStream));
}
});
Your m3u8 is not a true HLS file. It is just a playlist pointer to a single MP3
http://4metest1-4me.weebo.it/ios/Dance_of_the_Yao_People_3_JIDMQ7.mp3
You can either use media player to stream from the source directly or parse the file m3u8 file in your code to pull out the idividual URL's
url url = new URL(" http://4metest1-view.4me.it/api/xpublisher/resources/weebopublisher/getContentDescriptor.m3u8?clientId=4metest1&contentId=b55f7d74-cd81-48ce-9390-d9ffd5c49281&channelType=STREAMHTTPIOS&v=4");
InputStream m3u8 = (InputStream) url.getContent();
BufferedReader br = new BufferedReader(new InputStreamReader(M3U8));
for(int i = 0; i < 2; ++i)
{
br.readLine();
}|
readLine(); //this parses the third line of the playlist
br.close();
url = new URL(baseURL.concat(target));
I am accessing the videos directly from content provider without storing it in my database. But it is giving me 3gp audio file along with other video and 3gp videos. how could i filter only the video files.I am working for API 8
Try this since you are working on API 8, otherwise METADATA_KEY_HAS_VIDEO could have done the job if API level >= 10.
A work around using MediaPlayer. If media has height it means it is a video.
public boolean isVideoFile(File file) {
int height = 0;
try {
MediaPlayer mp = new MediaPlayer();
FileInputStream fs;
FileDescriptor fd;
fs = new FileInputStream(file);
fd = fs.getFD();
mp.setDataSource(fd);
mp.prepare();
height = mp.getVideoHeight();
mp.release();
} catch (Exception e) {
Log.e(TAG, "Exception trying to determine if 3gp file is video.", e);
}
return height > 0;
}
Source
My favorite Radio station plays a radio audio stream in mp3 format. In my android application I can receive and play it without any problem.
How can I implement a recording function? I want to record the mp3 radio stream to my Android phones SD-Card.
I tried the MediaRecorder Class without any result...
Android Developer: MediaRecorder
...
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
...
Unfortunately I cannot choose something like:
mRecorder.setAudioSource(MediaRecorder.AudioSource.MP3_STREAM); ... ;-)
How can I record a mp3 radio stream? Thanks for any help or code snippets...
Perfect! Reading the audio stream "byte by byte" is the solution. Thank you!!
Here my code snippets:
URL url = new URL("http://myradio,com/stream.mp3");
inputStream = url.openStream();
Log.d(LOG_TAG, "url.openStream()");
fileOutputStream = new FileOutputStream(outputSource);
Log.d(LOG_TAG, "FileOutputStream: " + outputSource);
int c;
while ((c = inputStream.read()) != -1) {
Log.d(LOG_TAG, "bytesRead=" + bytesRead);
fileOutputStream.write(c);
bytesRead++;
}
Maybe you should read audio stream "byte by byte" and then place it into new file? Like a simple file copy operation, using inputstream-outputstream.