Note that there are some explanatory texts on larger screens.

plurals
  1. POTrying to build "Hello, world!" media player activity using Jelly Beans new low-level media API
    text
    copied!<p>I'm trying to test the new low-level media API feautures, MediaExtractor and MediaCodec. I am following this guide:</p> <p><a href="http://dpsm.wordpress.com/2012/07/28/android-mediacodec-decoded/" rel="nofollow">http://dpsm.wordpress.com/2012/07/28/android-mediacodec-decoded/</a></p> <p>I put together this function, where <code>songsList.get(songIndex).get("songPath")</code> is a path to an mp3 file given by another function. </p> <pre><code> /** * 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); // &lt;= 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 &gt;= 0) { ByteBuffer dstBuf = codecInputBuffers[inputBufIndex]; int sampleSize = extractor.readSampleData(dstBuf, 0); long presentationTimeUs = 0; if (sampleSize &lt; 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 &gt;= 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 &gt; 0) { audioTrack.write(chunk, 0, chunk.length); } codec.releaseOutputBuffer(outputBufIndex, false /* render */); if ((info.flags &amp; 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() } </code></pre> <p>It doesn't seem to throw off any major errors, but there's no sound and in the log there is a message for "libwvm.so not found" and "OMX_getExtensionIndex failed". Maybe someone has some ideas before I try to flod to code with logs. I'm running AVD with Jelly Bean version 4.1.2 and I can't debug from Eclipse, so I'm only using the logs to catch errors.</p> <p>EDIT nov. 16: I forgot the obvious audioTrack.play() function but this causes a crash, so it is commented out again.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload