Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MediaExtractor.setDataSource throws IOException "failed to instantiate extractor"

I'm on Android 4.2 and calling MediaExtractor.setDataSource, and it sometimes throws an IOException of "failed to instantiate extractor". I've found where this is thrown from the C++ implementation, but it hasn't helped.

Other people with the same problem and either no answer or an answer which doesn't help me are:

android.media.MediaExtractor. Anyone got this beast to work? "Failed to instantiate extractor" exception

media extractor show "failed to instantiate extractor"

Failed to instantiate mediaextractor when using setDataSource()

In a desperate attempt to figure this out I've written the smallest little app I could which demonstrates it:

public class MainActivity extends Activity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
  }
  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }
  public boolean doStuff(View view) {
    File f = getExternalFilesDir(null);
    File[] files = f.listFiles();
    for (File file : files) {
      if (file.isFile()) {
        Log.e("Andy", "trying file [" + file.getName() + "]");
        startExtractor(file);
      }
    }
    return true;
  }
  private void startExtractor(File f) {
    MediaExtractor extractor = new MediaExtractor();
    try {
      extractor.setDataSource(f.getAbsolutePath());
    } catch (IOException e) {
      Log.e("Andy", "splat " + e.getMessage());
    }
    extractor.release();
  }
}

The activity for this app has a single button, which calls "doStuff". The output looks like this:

05-12 15:27:42.639: E/Andy(18757): trying file [aaitn.mp4]
05-12 15:27:42.689: E/Andy(18757): splat Failed to instantiate extractor.
05-12 15:27:42.689: E/Andy(18757): trying file [unusual aspect.mp4]
05-12 15:27:42.709: E/Andy(18757): trying file [test.mp4]
05-12 15:27:55.039: E/Andy(18757): trying file [aaitn.mp4]
05-12 15:27:55.119: E/Andy(18757): trying file [unusual aspect.mp4]
05-12 15:27:55.149: E/Andy(18757): trying file [test.mp4]
05-12 15:28:03.209: E/Andy(18757): trying file [aaitn.mp4]
05-12 15:28:03.259: E/Andy(18757): splat Failed to instantiate extractor.
05-12 15:28:03.259: E/Andy(18757): trying file [unusual aspect.mp4]
05-12 15:28:03.279: E/Andy(18757): trying file [test.mp4]
05-12 15:28:12.289: E/Andy(18757): trying file [aaitn.mp4]
05-12 15:28:12.379: E/Andy(18757): trying file [unusual aspect.mp4]
05-12 15:28:12.419: E/Andy(18757): trying file [test.mp4]
05-12 15:28:17.879: E/Andy(18757): trying file [aaitn.mp4]
05-12 15:28:17.929: E/Andy(18757): trying file [unusual aspect.mp4]
05-12 15:28:17.949: E/Andy(18757): splat Failed to instantiate extractor.
05-12 15:28:17.949: E/Andy(18757): trying file [test.mp4]

This is confusing on a few counts.

  • It sometimes works and sometimes doesn't
  • It failed on the very first attempt.

Now, I'm fairly sure that other people are using this interface and it is working for them, which either means the devices I'm using (MK808s) have broken firmware, or there's a trick I'm missing to make it reliable. Does anyone have any ideas?

The logcat is amazingly clear except when the GC kicks in, and the GC timing doesn't correlate to the problem.

edit

I changed my button so that it would launch a thread which loops 1000 times over all three files. It ran all the way, no trouble. Much head scratching. I have found that if I wiggle the mouse while that thread is running it starts failing, but it starts working again as soon as I let go. Running yet another thread that just messes around doing maths for a while didn't cause it. In the real world app this came from, removing the mouse doesn't make the problem go away, but it's a big app and does a lot of other stuff too.

like image 392
Andy Newman Avatar asked May 12 '14 14:05

Andy Newman


1 Answers

For me, the accepted answer didn't work. I had to specify the start offset and the length:

// Assuming a raw resource located at "res/raw/test_audio.mp3"
MediaExtractor extractor = new MediaExtractor();
AssetFileDescriptor afd = getResources().openRawResourceFd(R.raw.test_audio);
try {
    extractor.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
} catch (IOException e) {
    e.printStackTrace();
}
like image 58
JellicleCat Avatar answered Oct 04 '22 18:10

JellicleCat