Media extractor metric "failed to create an extractor instance"

I am trying to work with a media extractor to stream OGG audio files to Android. I wrote the code using google docs. but it does not work at all. Maybe I wrote the wrong code or syntax. Since I am a student. show that I was unable to create an instance of the extractor

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

}

+3
source share
4 answers

I ACCEPT your question is “why doesn't it work at all?” This is usually too big a question, but in this case it seems to me that you did not understand at all how MediaExtractor and MediaCodec work.

Not your fault. The documentation is cryptic to say the least. However, I was able to play audio files in this way.

My design assumes MediaCodec implements an asynchronous buffer queue. There seem to be about 4 buffers in this queue.

So, I use 2 streams: one stream puts data from the MediaExtractor in the queue, and the other stream decodes the audio from the queue and writes it to AudioTrack.

I Then you need to be very careful to avoid a dead end during the search, for example. And I get a lot more code than yours. I do not know how to avoid this!

I am thinking about trying a video. Any useful links would be appreciated!

Don

+2
source

The code will be something below, which works fine for me for a local audio file on the JB platform.

 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)... 
+1
source

Setting the data source to the remote URL will require the android.permission.INTERNET declaration to be declared in AndroidManifest.xml

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

Try passing it the file descriptor of the open file, not the path to the file. This worked for me when I had this problem. I have no idea why.

0
source

Source: https://habr.com/ru/post/948463/


All Articles