Untitled

 avatar
unknown
plain_text
a year ago
4.2 kB
3
Indexable
private void resampleAudio(MediaMuxer mediaMuxer, MediaCodec audioDecoder, MediaExtractor audioExtractor, SamplerClip clip, MergeProgressListener listener) throws IOException {

    MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
    int inputChunk = 0;
    int outputCount = 0;
    long endTime = clip.getEndTime() == -1 ? clip.getVideoDuration() : clip.getEndTime();
    boolean outputDone = false;
    boolean inputDone = false;
    boolean decoderDone = false;

    while (!outputDone) {
        if (!inputDone) {
            int inputBufIndex = audioDecoder.dequeueInputBuffer(TIMEOUT_USEC);
            if (inputBufIndex >= 0) {
                ByteBuffer inputBuf = audioDecoder.getInputBuffer(inputBufIndex);
                assert inputBuf != null;
                inputBuf.clear();

                long sampleTime = audioExtractor.getSampleTime();
                if (sampleTime / 1000 >= endTime) {
                    audioDecoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                    inputDone = true;
                } else {
                    int sampleSize = audioExtractor.readSampleData(inputBuf, 0);
                    if (sampleSize < 0) {
                        audioDecoder.queueInputBuffer(inputBufIndex, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                        inputDone = true;
                    } else {
                        audioDecoder.queueInputBuffer(inputBufIndex, 0, sampleSize, sampleTime, 0);
                        audioExtractor.advance();
                    }
                    inputChunk++;
                }
            }
        }

        while (!decoderDone || !outputDone) {
            int encoderStatus = audioEncoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
            if (encoderStatus >= 0) {
                ByteBuffer encodedData = audioEncoder.getOutputBuffer(encoderStatus);
                assert encodedData != null;

                if (info.size != 0) {
                    encodedData.position(info.offset);
                    encodedData.limit(info.offset + info.size);
                    mediaMuxer.writeSampleData(outputAudioTrack, encodedData, info);
                    outputCount++;
                }

                outputDone = (info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
                audioEncoder.releaseOutputBuffer(encoderStatus, false);

                if (outputDone) break;
            }

            int decoderStatus = audioDecoder.dequeueOutputBuffer(info, TIMEOUT_USEC);
            if (decoderStatus >= 0) {
                boolean doRender = (info.size != 0);
                if (doRender) {
                    ByteBuffer outputBuffer = audioDecoder.getOutputBuffer(decoderStatus);
                    assert outputBuffer != null;

                    int inIndexEncode = audioEncoder.dequeueInputBuffer(TIMEOUT_USEC);
                    if (inIndexEncode >= 0) {
                        ByteBuffer inputBuffer = audioEncoder.getInputBuffer(inIndexEncode);
                        assert inputBuffer != null;
                        inputBuffer.clear();
                        inputBuffer.put(outputBuffer);

                        long presentationTimeUs = Math.max(0, info.presentationTimeUs - (clip.getStartTime() != -1 ? clip.getStartTime() : 0));
                        audioEncoder.queueInputBuffer(inIndexEncode, 0, info.size, presentationTimeUs, 0);

                        if (listener != null) {
                            float progress = ((float) (presentationTimeUs / 1000) + (float) mEncoderPresentationTimeUs2) / (2 * clip.getVideoDuration()) / 10;
                            listener.onProgress(progress);
                        }
                    }
                }
                audioDecoder.releaseOutputBuffer(decoderStatus, doRender);

                if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                    decoderDone = true;
                }
            }
        }
    }

    if (inputChunk != outputCount) {
        throw new RuntimeException("Frame lost: " + inputChunk + " in, " + outputCount + " out");
    }
}
Editor is loading...
Leave a Comment