android - MediaExtractor.advance() - 比预期更早发出流结束信号

标签 android mp3 android-mediacodec mediaextractor

MediaExtractor 类的 advance() 方法比预期更早(在文件结束之前)发出流结束信号,我遇到了问题。根据谷歌引用 advance()使用本地文件时方法可能会出错(这是我的情况 - filePath 指向本地文件):

When extracting a local file, the behaviors of advance() and readSampleData(ByteBuffer, int) are undefined in presence of concurrent writes to the same local file:

不幸的是,没有关于在没有 advance() 方法的情况下使用 MediaExtractor 的单字。如何移动到下一个样本?如果没有办法做到这一点,那么我想知道如何在不使用 MediaExtractor 的情况下提供 inputBuffer

我的代码 fragment 如下:

 if(Build.VERSION.SDK_INT >= 21 ) {

        try {
            codec = MediaCodec.createByCodecName("OMX.google.mp3.decoder");

        } catch (IOException e) {
            e.printStackTrace();
        }

        final MediaExtractor extractor = new MediaExtractor();
        try {
            extractor.setDataSource(filePath);     //local file
            Log.i("filePath", String.valueOf(filePath));
            extractor.selectTrack(0);
        } catch (IOException e) {
            e.printStackTrace();
        }


        codec.setCallback(new MediaCodec.Callback() {

            @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
            @Override
            public void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {

                ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
                // fill inputBuffer with valid data
                int sampleSize = extractor.readSampleData(inputBuffer,0);

                if(extractor.advance) {

                    codec.queueInputBuffer(inputBufferId, 0, sampleSize, 0, 0);


                } else {
                        // EOS
                    codec.queueInputBuffer(inputBufferId, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                    codec.stop();
                    codec.release();
                }


            }
// more callbacks

};


}

最佳答案

在我的示例中,当我使用另一种语句构造时,MediaExtractor 工作正常。我没有像你一样用 extractor.advance() 检查 EOS。尝试其他示例如何提供:

   int chunkSize = extractor.readSampleData(inputBuffer, 0);
   if (chunkSize < 0) {
        // End of stream -- send empty frame with EOS flag set.
        codec.queueInputBuffer(inputBufferId, 0, 0, 0L,
                MediaCodec.BUFFER_FLAG_END_OF_STREAM);
    } else {
        // No EOS -- continue
        long presentationTimeUs = extractor.getSampleTime();
        codec.queueInputBuffer(inputBufferId, 0, chunkSize,
                presentationTimeUs, 0 /*flags*/);
        extractor.advance();
    }

顺便说一下,MediaExtractor 的指南讲述了这样的用法。 Fadden 在 Grafika 中有 MoviePlayer与 MediaExtractor。但它在没有 MediaCodec.Callback 的情况下提供解码器。

关于android - MediaExtractor.advance() - 比预期更早发出流结束信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46301410/

相关文章:

Android - 在解码视频的同时对其进行编码

android - RTMP自适应码率算法

Android 提取解码编码 MUX 音频

android - 地理位置点 android 和准确性

android - File.createTempFile() VS 新文件()

javascript - 寻找 Wii 兼容的 Javascript Flash mp3 播放器

express - 为什么node-lame模块保存的mp3文件音调高/播放速度快?

android - AIDL包裹使用

java - 从 Firebase 检索数据时出错

Swift 如何在 macOS 中编辑 .mp3 文件的元数据 (ID3)