【问题标题】:MediaExtractor.setDataSource throws IOException "failed to instantiate extractor"MediaExtractor.setDataSource 抛出 IOException “无法实例化提取器”
【发布时间】:2014-06-30 00:08:03
【问题描述】:

我使用的是 Android 4.2 并调用 MediaExtractor.setDataSource,它有时会引发“无法实例化提取器”的 IOException。我发现这是从 C++ 实现中抛出的,但它没有帮助。

遇到同样问题但没有答案或对我没有帮助的其他人是:

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

为了解决这个问题,我拼命尝试编写了最小的小应用程序来演示它:

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();
  }
}

此应用的 Activity 有一个按钮,称为“doStuff”。输出如下所示:

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]

这在某些方面令人困惑。

  • 有时有效,有时无效
  • 第一次尝试就失败了。

现在,我相当确定其他人正在使用此界面并且它对他们有效,这要么意味着我正在使用的设备 (MK808s) 的固件损坏,要么我缺少一个技巧它可靠。有人有什么想法吗?

除了 GC 启动时,logcat 非常清晰,并且 GC 时间与问题无关。

编辑

我更改了我的按钮,以便它启动一个线程,该线程在所有三个文件上循环 1000 次。一路狂奔,一点问题都没有。很挠头。我发现如果我在该线程运行时摆动鼠标,它会开始失败,但只要我一松手,它就会再次开始工作。运行另一个线程,只是在一段时间内搞砸了数学并没有导致它。在现实世界的应用程序中,移除鼠标并不能解决问题,但它是一个很大的应用程序,还可以做很多其他事情。

【问题讨论】:

  • logcat 输出中是否有系统媒体代码中的任何内容?
  • 没有。除非 GC 启动,而且 GC 时间与问题无关,否则它非常清楚。
  • 嗯,我想我知道为什么我的应用在 Android 4.2 上的评分最低了。是的,坏东西。

标签: java android video android-mediacodec


【解决方案1】:

我有同样的问题。在我将文件直接移动到资产文件夹中后,它对我有用,而不是将其保存在子文件夹中。

【讨论】:

    【解决方案2】:

    正如安迪在this 中所写,示例代码如下:

    MediaExtractor extractor = new MediaExtractor();
    File file = new File(pathToFile);
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(file);
        FileDescriptor fd = fis.getFD();
        extractor.setDataSource(fd);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        //Release stuff
        extractor.release();
        try {
            if(fis != null) {
                fis.close();
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }
    

    【讨论】:

      【解决方案3】:

      对我来说,我也有同样的问题。 这是因为我忘记了清单中声明的​​许可。

      也许你可以检查一下。

      【讨论】:

      • 如果缺少权限只会导致偶尔无法读取文件,我们会遇到更大的问题:p
      【解决方案4】:

      对我来说,接受的答案不起作用。我必须指定起始偏移量和长度:

      // 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();
      }
      

      【讨论】:

        【解决方案5】:

        看起来,如果我不是要求它从文件中提取,而是自己打开文件,获取输入流,从输入流中获取 FileDescriptor,然后要求它从文件描述符中提取,它每次都有效。即使我摆动鼠标!

        我会将其归结为 android 中的一个错误,然后通过复制粘贴来回答其他人的一些问题。不确定在这种情况下这是否是正确的协议?

        【讨论】:

        • 您愿意发布实现此策略的代码吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-10-10
        • 1970-01-01
        • 1970-01-01
        • 2015-11-09
        • 1970-01-01
        • 2012-09-12
        • 1970-01-01
        相关资源
        最近更新 更多