【问题标题】:media extractor show "failed to instantiate extractor"媒体提取器显示“无法实例化提取器”
【发布时间】:2015-01-21 09:18:21
【问题描述】:

我正在尝试在 android 上开发用于 OGG 文件格式音频流的媒体提取器。 我在谷歌文档的帮助下编写了一些代码。但它根本不起作用。 可能是我写了错误的代码或语法,因为我是学生。 它显示我无法实例化提取器

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource("http://examplelink.com/ogg");// I cant put real link so sorry for that
int numTracks = extractor.getTrackCount();
for (int i = 0; i < numTracks; ++i) {
    MediaFormat format = extractor.getTrackFormat(i);
    String mime = format.getString(MediaFormat.KEY_MIME);
    extractor.selectTrack(i);

    ByteBuffer inputBuffer = ByteBuffer.allocate(1024);
    while (extractor.readSampleData(inputBuffer,0) >= 0) {
            int trackIndex = (int) extractor.getSampleTime();
            long presentationTimeUs = extractor.getSampleTime();
    }

    MediaCodec codec = MediaCodec.createDecoderByType(mime);
    codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
    codec.start();
    ByteBuffer[] inputBuffers = codec.getInputBuffers();
    ByteBuffer[] outputBuffers = codec.getOutputBuffers();
    format = codec.getOutputFormat();
    Long timeoutUs=(long) 1;
    for (;;) {
        int inputBufferIndex = codec.dequeueInputBuffer(timeoutUs);
        if (inputBufferIndex >= 0) {
            // fill inputBuffers[inputBufferIndex] with valid data
            codec.queueInputBuffer(inputBufferIndex, 0, 128, 0,0);
        }
        MediaCodec.BufferInfo info = new BufferInfo();
        int outputBufferIndex = codec.dequeueOutputBuffer(info, timeoutUs);
        if (outputBufferIndex >= 0) {
            // outputBuffer is ready to be processed or rendered.
            codec.releaseOutputBuffer(outputBufferIndex, false);
        } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
            outputBuffers = codec.getOutputBuffers();
        } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
            // Subsequent data will conform to new format.
            format = codec.getOutputFormat();
            AudioTrack mAudioTrack = null;
            mAudioTrack.setPlaybackRate(format.getInteger(MediaFormat.KEY_SAMPLE_RATE));
        }
        codec.stop();
        codec.release();
        codec = null;
    }
}

}

【问题讨论】:

  • 在“SetDataSource”行上显示相同的消息对我来说崩溃。尝试使用 sdcard 和内部存储...尝试过 FilePath 和 FileDescriptor.. 不起作用。你有没有弄清楚哪里出了问题?
  • @badbadboy 还没有我目前在我的应用程序中使用 mp3 流.. 但我正在等待新版本的 android 版本,所以在那之后我可以有更多关于媒体提取器和代码的文档。跨度>

标签: android android-layout android-intent


【解决方案1】:

我假设您的问题是“为什么它根本不起作用?” 通常,这是一个太大的问题,但在这种情况下,在我看来,您似乎根本不了解 MediaExtractor 和 MediaCodec 是如何工作的。

不过,不全是你的错。说得好听点,文档很神秘。 但是我已经成功地以这种方式播放音频文件。

我的方案假设 MediaCodec 实现了一个异步缓冲区队列。这个队列中似乎有大约 4 个缓冲区。

所以我使用了 2 个线程:一个线程将来自 MediaExtractor 的数据放入队列,另一个线程从队列中取出解码后的音频并将其写入 AudioTrack。

然后需要非常小心以避免在查找过程中出现死锁,例如。最后我得到的代码比你的多得多。我不知道如何避免这种情况!

我正在考虑尝试视频。任何有用的参考资料将不胜感激!

【讨论】:

  • 您的回答并不能真正帮助 SwapAndroid 解决他的问题。是吗?
  • @SebastianAnnies 和@Don ..是的,你们都是对的,我不完全理解..所以你能和我分享你的工作代码,这样我就可以研究它并改进 OGG 流的代码??
  • 我也有同样的问题。 MediaExtractor 在“SetDataSource”上崩溃。你做了什么让它发挥作用?
【解决方案2】:

代码将在下面,这对我来说非常适合 JB 平台中的本地音频文件。

try{
  Extractor lExt = new MediaExtractor();
  lExt.setDataSource(file path); //I have tried with local file
  lExt.setTrack(0); //For local file only one track will be present
  MediaFormat format = lExt.getTrackFormat(0); //0 is the track ID
  String mime = format.getString(MediaFormat.KEY_MIME);
  MediaCodec codec = MediaCodec.createDecoderByType(mime);
  codec.configure(
       format,//format of input data ::decoder OR desired format of the output data:encoder
       null,//Specify a surface on which to render the output of this decoder
       null,//Specify a crypto object to facilitate secure decryption
       0 //For Decoding, encoding use: CONFIGURE_FLAG_ENCODE 
       );
  codec.start();
  codec.flush();

  //Get Input and Output buffers from codec
  inputBuffers = codec.getInputBuffers();
  outputBuffers = codec.getOutputBuffers(); 

  While(condition)
  {
      //Get Audio data from extractor
      int inputBufIndex = codec.dequeueInputBuffer(50);//Timeout set of 50 microsec
      if (inputBufIndex >= 0) 
      {
           ByteBuffer dstBuf = inputBuffers[inputBufIndex]; 
           int sampleSize = extractor.readSampleData(dstBuf, 0);
           long presentationTimeUs = extractor.getSampleTime();

           codec.queueInputBuffer(inputBufIndex,
                           0, //offset
                           sampleSize,
                           presentationTimeUs,
                           0); //Use appropriate flag value
           extractor.advance();
        }

      //Use codec to decode the data -- handle end of stream properly
        MediaCodec.BufferInfo info = new  MediaCodec.BufferInfo();
        info.set(0,0,0,0);
        final int res = codec.dequeueOutputBuffer(info, 20000);
        if (res >= 0) 
        {
            int outputBufIndex = res;
            ByteBuffer buf = outputBuffers[outputBufIndex];

            byte[] chunk = new byte[info.size];
            buf.get(chunk); // Read the buffer all at once
            buf.clear(); // ** MUST DO!!! OTHERWISE THE NEXT TIME YOU GET THIS SAME BUFFER BAD THINGS WILL HAPPEN

            if (chunk.length > 0) 
               //Use this chunk as it contains decoded audio dat            
            codec.releaseOutputBuffer(outputBufIndex, false /* render */); 
        } 
        else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) 
            outputBuffers = codec.getOutputBuffers();
  }
  codec.stop();
  codec.release();
  lExt.release();
}
catch(Exception ex)...

【讨论】:

    【解决方案3】:

    将数据源设置为远程 URL 需要在 AndroidManifest.xml 中声明 android.permission.INTERNET 权限

    <uses-permission android:name="android.permission.INTERNET" />
    

    【讨论】:

      【解决方案4】:

      尝试将已打开文件的文件描述符传递给它,而不是文件路径。当我遇到这个问题时,它对我有用。我不知道为什么。

      【讨论】:

      • 你能告诉我如何从打开的文件中获取文件描述符吗?
      猜你喜欢
      • 2018-10-10
      • 2014-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多