Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MediaPlayer error -2147483648 when playing file on internal storage

Tags:

I'm using the Audio Capture sample on android.com to record and play back audio on actual devices. (Motorola touch pad, and Samsung Galaxy S).

When I define the audio file path as

mFile = Environment.getExternalStorageDirectory().getAbsolutePath(); 

record and playback works.

But if I set the audio file as

mFile = getFilesDir().getAbsolutePath(); 

OR

mFile = getDir("media", Context.MODE_PRIVATE).getAbsolutePath(); 

OR

mFile = getDir("media", Context.MODE_WORLD_READABLE).getAbsolutePath(); 

record seems to work, but playback fails with

ERROR/MediaPlayer(4559): error (1, -2147483648)

What function will return the correct internal storage directory to save audio files for playback only within my app?

The code in question is in my onCreate function. (In the example, they have it in the Constructor, but I moved it to onCreate because otherwise getFilesDir() and getDir() have no context to work.)

public void onCreate(Bundle icicle) {     super.onCreate(icicle);  //  mFile = Environment.getExternalStorageDirectory().getAbsolutePath();     // OK //  mFile = getFilesDir().getAbsolutePath();                                 // BAD //  mFile = getDir("media", Context.MODE_PRIVATE).getAbsolutePath();         // BAD     mFile = getDir("media", Context.MODE_WORLD_READABLE).getAbsolutePath();  // BAD     mFile += "/audiorecordtest.3gp";     Log.e(LOG_TAG,mFile); //  ... } 

When I record to external storage (and playback works properly), the log looks like this:

06-17 10:07:30.890: DEBUG/AudioHardwareTegra(85): getInputBufferSize: returns 320 for rate 8000 06-17 10:07:30.900: INFO/MPEG4Writer(85): limits: 2147483647/0 bytes/us, bit rate: 12200 bps and the estimated moov size 3072 bytes 06-17 10:07:30.960: DEBUG/AudioHardwareTegra(85): setDriver_l: Analog mic? yes. Bluetooth? no. 06-17 10:07:31.100: WARN/AudioFlinger(85): RecordThread: buffer overflow 06-17 10:07:31.100: INFO/MPEG4Writer(85): setStartTimestampUs: 86380 06-17 10:07:31.100: INFO/MPEG4Writer(85): Earliest track starting time: 86380 06-17 10:07:34.350: DEBUG/MPEG4Writer(85): Stopping Audio track 06-17 10:07:34.450: INFO/MPEG4Writer(85): Received total/0-length (167/0) buffers and encoded 167 frames. - audio 06-17 10:07:34.450: INFO/MPEG4Writer(85): Audio track drift time: -20309 us 06-17 10:07:34.450: DEBUG/MPEG4Writer(85): Stopping Audio track source 06-17 10:07:34.470: DEBUG/MPEG4Writer(85): Audio track stopped 06-17 10:07:34.470: DEBUG/MPEG4Writer(85): Stopping writer thread 06-17 10:07:34.470: DEBUG/MPEG4Writer(85): 0 chunks are written in the last batch 06-17 10:07:34.470: DEBUG/MPEG4Writer(85): Writer thread stopped 06-17 10:07:34.470: DEBUG/MPEG4Writer(85): Stopping Audio track 06-17 10:07:34.470: WARN/MediaRecorder(4472): mediarecorder went away with unhandled events 06-17 10:07:40.310: INFO/StagefrightPlayer(85): setDataSource('/mnt/sdcard/audiorecordtest.3gp') 06-17 10:07:46.590: DEBUG/AudioHardwareTegra(85): AudioStreamOutTegra::flush() 06-17 10:07:46.670: DEBUG/AudioHardwareTegra(85): AudioStreamOutTegra::flush() returns 

When I record to internal storage (and it fails), the log looks like this:

06-17 10:08:28.380: DEBUG/AudioHardwareTegra(85): getInputBufferSize: returns 320 for rate 8000 06-17 10:08:28.380: INFO/MPEG4Writer(85): limits: 2147483647/0 bytes/us, bit rate: 12200 bps and the estimated moov size 3072 bytes 06-17 10:08:28.440: DEBUG/AudioHardwareTegra(85): setDriver_l: Analog mic? yes. Bluetooth? no. 06-17 10:08:28.970: WARN/AudioFlinger(85): RecordThread: buffer overflow 06-17 10:08:28.970: INFO/MPEG4Writer(85): setStartTimestampUs: 83095 06-17 10:08:28.970: INFO/MPEG4Writer(85): Earliest track starting time: 83095 06-17 10:08:34.020: DEBUG/MPEG4Writer(85): Stopping Audio track 06-17 10:08:34.080: WARN/AudioFlinger(85): RecordThread: buffer overflow 06-17 10:08:34.090: INFO/MPEG4Writer(85): Received total/0-length (257/0) buffers and encoded 257 frames. - audio 06-17 10:08:34.090: INFO/MPEG4Writer(85): Audio track drift time: -385311 us 06-17 10:08:34.090: DEBUG/MPEG4Writer(85): Stopping Audio track source 06-17 10:08:34.090: DEBUG/MPEG4Writer(85): Audio track stopped 06-17 10:08:34.090: DEBUG/MPEG4Writer(85): Stopping writer thread 06-17 10:08:34.090: DEBUG/MPEG4Writer(85): 0 chunks are written in the last batch 06-17 10:08:34.090: DEBUG/MPEG4Writer(85): Writer thread stopped 06-17 10:08:34.090: DEBUG/MPEG4Writer(85): Stopping Audio track 06-17 10:08:34.100: WARN/MediaRecorder(4559): mediarecorder went away with unhandled events 06-17 10:08:40.740: INFO/StagefrightPlayer(85): setDataSource('/data/data/my.record.test/files/audiorecordtest.3gp') 06-17 10:08:40.740: ERROR/MediaPlayer(4559): error (1, -2147483648) 06-17 10:08:40.740: ERROR/AudioRecordTest(4559): prepare() failed 

The recording sections of the log look largely the same to me, so I think it's recording, but I don't know how to check the file in any way besides play it. ;-)

The error log is similar when I use getDir().

like image 318
Thunder Rabbit Avatar asked Jun 17 '11 02:06

Thunder Rabbit


People also ask

What is MediaPlayer in android?

android.media.MediaPlayer. MediaPlayer class can be used to control playback of audio/video files and streams. MediaPlayer is not thread-safe. Creation of and all access to player instances should be on the same thread. If registering callbacks, the thread must have a Looper.

What class in android can be used to play an Audio file?

One of the most important components of the media framework is the MediaPlayer class. An object of this class can fetch, decode, and play both audio and video with minimal setup.


2 Answers

Thanks to gtkandroid:

Instead of mPlayer.setDataSource(mFile); I did this:

FileInputStream fileInputStream = new FileInputStream(mFile); mPlayer.setDataSource(fileInputStream.getFD());          fileInputStream.close(); mPlayer.prepare(); 
like image 168
Thunder Rabbit Avatar answered Oct 16 '22 05:10

Thunder Rabbit


Tim Crowley is right. Better practice is to close the stream, like this:

FileInputStream stream = new FileInputStream(path); mediaPlayer.setDataSource(stream.getFD()); stream.close(); 

It is noted in the documentation of the method:

android.media.MediaPlayer.setDataSource(FileDescriptor fd)

Sets the data source (FileDescriptor) to use. It is the caller's responsibility to close the file descriptor. It is safe to do so as soon as this call returns.

like image 44
KitKat Avatar answered Oct 16 '22 06:10

KitKat