Попытка построить Hello, world! активность медиаплеера с использованием нового низкоуровневого мультимедийного API Jelly Beans

Я пытаюсь протестировать новые низкоуровневые функции API мультимедиа, MediaExtractor и MediaCodec. Я следую этому руководству:

http://dpsm.wordpress.com/2012/07/28/android-mediacodec-decoded/

Я собрал эту функцию, где songsList.get(songIndex).get("songPath") — это путь к mp3-файлу, заданный другой функцией.

    /**
 * Attempts at API level 16 implementation
 * 
 * MediaExtractor, MediaCodec and AudioTrack to play audiofiles
 * 
 * */

public void JBPlay(int songIndex) {
    String LOG_TAG="JB";

    //AssetFileDescriptor sampleFD = getResources().openRawResourceFd(R.raw.sample);
    //AssetFileDescriptor sampleFD = getAssets().openFd(songsList.get(songIndex).get("songPath"));
    // getResources().openRawResourceFD(songsList.get(songIndex).get("songPath"));

    //Log.d("FD: ", sampleFD.toString());

    MediaExtractor extractor;
    MediaCodec codec;
    ByteBuffer[] codecInputBuffers;
    ByteBuffer[] codecOutputBuffers;

    extractor = new MediaExtractor();
    extractor.setDataSource(songsList.get(songIndex).get("songPath"));
    //extractor.setDataSource(sampleFD.getFileDescriptor(),
        //  sampleFD.getStartOffset(), sampleFD.getLength());


    Log.d(LOG_TAG, String.format("TRACKS #: %d", extractor.getTrackCount()));
    MediaFormat format = extractor.getTrackFormat(0);
    String mime = format.getString(MediaFormat.KEY_MIME);
    Log.d(LOG_TAG, String.format("MIME TYPE: %s", mime));


    codec = MediaCodec.createDecoderByType(mime);
    codec.configure(format, null /* surface */, null /* crypto */, 0 /* flags */);
    codec.start();
    codecInputBuffers = codec.getInputBuffers();
    codecOutputBuffers = codec.getOutputBuffers();

    extractor.selectTrack(0); // <= You must select a track. You will read samples from the media from this track!


    boolean sawInputEOS=false;
    int inputBufIndex = codec.dequeueInputBuffer(1000);//1 second timeout ???
    if (inputBufIndex >= 0) {
        ByteBuffer dstBuf = codecInputBuffers[inputBufIndex];

        int sampleSize = extractor.readSampleData(dstBuf, 0);
        long presentationTimeUs = 0;
        if (sampleSize < 0) {
            sawInputEOS = true;
            sampleSize = 0;
        } else {
            presentationTimeUs = extractor.getSampleTime();
        }


        codec.queueInputBuffer(inputBufIndex,
                               0, //offset
                               sampleSize,
                               presentationTimeUs,0);
                               //sawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0);
        if (!sawInputEOS) {
            extractor.advance();
        }
     }

    AudioTrack audioTrack = null;
    BufferInfo info = null;
    Boolean sawOutputEOS=false;
    final int res = codec.dequeueOutputBuffer(info, 1000);
    if (res >= 0) {
     int outputBufIndex = res;
     ByteBuffer buf = codecOutputBuffers[outputBufIndex];

     final 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) {
     audioTrack.write(chunk, 0, chunk.length);
     }
     codec.releaseOutputBuffer(outputBufIndex, false /* render */);

     if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
     sawOutputEOS = true;
     }
    } else if (res == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
     codecOutputBuffers = codec.getOutputBuffers();
    } else if (res == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
     final MediaFormat oformat = codec.getOutputFormat();
     Log.d(LOG_TAG, "Output format has changed to " + oformat);
     audioTrack.setPlaybackRate(oformat.getInteger(MediaFormat.KEY_SAMPLE_RATE));
    }
           // EDIT nov. 16: addition of play() causes crash!
           //audioTrack.play()

}

Вроде серьезных ошибок не выдает, но звука нет, а в логе есть сообщение "libwvm.so не найден" и "Ошибка OMX_getExtensionIndex". Может быть, у кого-то есть какие-то идеи, прежде чем я попытаюсь флудить код с логами. Я использую AVD с Jelly Bean версии 4.1.2 и не могу выполнять отладку из Eclipse, поэтому я использую журналы только для обнаружения ошибок.

РЕДАКТИРОВАТЬ нояб. 16: Я забыл очевидную функцию audioTrack.play(), но она вызывает сбой, поэтому она снова закомментирована.


person NMKloster    schedule 14.11.2012    source источник


Ответы (1)


В моем коде у меня есть audioTrack.play() сразу после создания AudioTrack, и он работает. Убедились ли вы, что громкость на вашем устройстве включена? Сначала я сделал эту ошибку и, очевидно, ничего не слышал. Вы также можете увеличить громкость с помощью AudioManager.

person Ratna Beresford    schedule 14.02.2014
comment
Где именно построен AudioTrack? я не вижу конструктора, только a = null. - person Juan Carlos Ospina Gonzalez; 10.03.2014
comment
Не могли бы вы поделиться своим кодом или фрагментом для руководства? - person NMKloster; 24.03.2014