MediaPlayer error -2147483648 when playing file on

2019-03-12 02:18发布

问题:

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().

回答1:

Thanks to gtkandroid:

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

FileInputStream fileInputStream = new FileInputStream(mFile);
mPlayer.setDataSource(fileInputStream.getFD());         
fileInputStream.close();
mPlayer.prepare();


回答2:

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.