Closed liuzhen2008 closed 7 years ago
Basically i need to convert this 3gp stuff to PCM samples using MediaExtractor/MediaCodec.
I reckon it's because of the compression. Currently, the code works only with uncompressed data. The snippet that you shared sets the encoder to AMR (Narrowband) audio codec, which should produce some compression on the resulting stream.
@yavor87 Yes thats exactly it. I used mediaCodec to convert the 3gp audio samples into PCM audio samples and the graph worked flawlessly.
@liuzhen2008 Could you share your solution?
try {
MediaExtractor extractor = new MediaExtractor();
extractor.setDataSource(filePath);
extractor.selectTrack(0);
MediaFormat format = extractor.getTrackFormat(0);
MediaCodec decoder = MediaCodec.createDecoderByType(format.getString(MediaFormat.KEY_MIME));
decoder.configure(format, null, null, 0);
decoder.start();
ByteBuffer[] inputBuffers = decoder.getInputBuffers();
ByteBuffer[] outputBuffers = decoder.getOutputBuffers();
MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
ArrayList<byte[]> dataList = new ArrayList<>();
int totalLength = 0;
while (true) {
int inIndex = decoder.dequeueInputBuffer(5000);
if (inIndex >= 0) {
ByteBuffer buffer = inputBuffers[inIndex];
int sampleSize = extractor.readSampleData(buffer, 0);
if (sampleSize < 0) {
decoder.queueInputBuffer(inIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
break;
} else {
decoder.queueInputBuffer(inIndex, 0, sampleSize, extractor.getSampleTime(), 0);
extractor.advance();
}
}
int outIndex = decoder.dequeueOutputBuffer(info, 5000);
switch (outIndex) {
case MediaCodec.INFO_OUTPUT_FORMAT_CHANGED:
case MediaCodec.INFO_TRY_AGAIN_LATER:
// whatever
break;
default:
ByteBuffer buffer = outputBuffers[outIndex];
int length = info.size - info.offset;
totalLength = totalLength + length;
int p = buffer.position();
byte[] tempBuffer = new byte[length];
buffer.get(tempBuffer, 0, length);
dataList.add(tempBuffer);
buffer.position(p);
decoder.releaseOutputBuffer(outIndex, true);
}
}
decoder.stop();
decoder.release();
extractor.release();
byte[] data = new byte[totalLength];
int offset = 0;
for (byte[] tempBuffer : dataList) {
System.arraycopy(tempBuffer, 0, data, offset, tempBuffer.length);
offset += tempBuffer.length;
}
ShortBuffer sb = ByteBuffer.wrap(data, 0, offset)
.order(ByteOrder.nativeOrder())
.asShortBuffer();
short[] samples = new short[sb.limit()];
sb.get(samples);
updateWaveForm(samples);
} catch (Throwable e) {
onRecordingError(e);
}
@irshadshalu This is what I had. the "samples" at the end is what I passed to the waveformView.setSamples(). "filePath" is the uri string of the 3pg file lcoation
You can google around 3gp to PCM samples, there are a few examples.
Thank you!
so just to be clear, does this accept .wav
files or .raw
files as input for the waveform to render and/or play
I try to use the
inputFileStream(new File(filePath))
directly on line https://github.com/newventuresoftware/WaveformControl/blob/master/app/src/main/java/com/newventuresoftware/waveformdemo/MainActivity.java#L125 and convert it to byte array. But the resulting image/play back doesn't seem to work properly.I also used a plain mp3 file as resource. The result is almost a rectangle. Is there any preprocess that needs to be done to the file?
The sound file i am interesting in showing a graph for is created by a MediaRecorder with the following configuration: