i am trying to convert audio file to byte[] and it works well. my problem is that it works on UI thread but i want to do it on other Thread; this is my code:
private class DecodeMusic extends Thread {
@RequiresApi(api = Build.VERSION_CODES.M)
public void run() {
playing = true;
sample = musics.get(current_music).getSample();
channel = musics.get(current_music).getChannel();
duration = musics.get(current_music).getDuration();
try {
if (mediaCodec != null) {
mediaCodec.stop();
mediaCodec.release();
mediaCodec = null;
}
if (mediaExtractor != null)
mediaExtractor.release();
musicQueue = new ArrayList<>();
StereoFile stereoFile = musics.get(current_music);
mediaExtractor = new MediaExtractor();
mediaExtractor.setDataSource(stereoFile.getPath());
MediaFormat format = mediaExtractor.getTrackFormat(0);
mediaExtractor.selectTrack(0);
MediaCodecList mediaCodecList = new MediaCodecList(MediaCodecList.ALL_CODECS);
mediaCodec = MediaCodec.createByCodecName(mediaCodecList.findDecoderForFormat(format));
musicQueue = new ArrayList<>(duration * sample);
try {
Looper.prepare();
Handler handler = new Handler();
mediaCodec.setCallback(new MediaCodec.Callback() {
@Override
public void onInputBufferAvailable(@NonNull MediaCodec codec, int index) {
ByteBuffer decoderInputBuffer = codec.getInputBuffer(index);
int size = mediaExtractor.readSampleData(decoderInputBuffer, 0);
if (size < 0) {
codec.queueInputBuffer(index, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
} else {
codec.queueInputBuffer(index, 0, size, mediaExtractor.getSampleTime(), 0);
mediaExtractor.advance();
}
}
@Override
public void onOutputBufferAvailable(@NonNull MediaCodec codec, int index, @NonNull MediaCodec.BufferInfo info) {
byte[] data = new byte[info.size - info.offset];
mediaCodec.getOutputBuffer(index).get(data);
musicQueue.add(data);
mediaCodec.releaseOutputBuffer(index, true);
}
@Override
public void onError(@NonNull MediaCodec codec, @NonNull MediaCodec.CodecException e) {
}
@Override
public void onOutputFormatChanged(@NonNull MediaCodec codec, @NonNull MediaFormat format) {
}
}, handler);
} catch (Exception e) {
e.printStackTrace();
}
mediaCodec.configure(format, null, null, 0);
mediaCodec.start();
} catch (IOException ignored) {
}
}
}
The doc says that if you start mediacodec on other thread than main, it should works in that thread but this doesn't happen(i test it). another solution is using hanlder but i don't know how!
Please, see MediaCodec.setCallback method. You need to create and start HandlerThread to process data in other thread.
Then, create
Handleron backgroundHandlerThread.looperand pass it as a second argument toMediaCodec.setCallbackmethod: