Untitled

 avatar
unknown
plain_text
5 months ago
11 kB
3
Indexable
public boolean convertVideo(final String sourcePath, String destinationPath, int width, int height, int duration, SlimProgressListener listener) {

        this.path = sourcePath;
        this.outputPath = destinationPath;

        mWidth = width;
        mHeight = height;
        long endTime = -1;

        boolean error = false;
        long videoStartTime = -1;

        long time = System.currentTimeMillis();

        File cacheFile = new File(destinationPath);
        File inputFile = new File(path);
        if (!inputFile.canRead()) {
            return false;
        }

        MediaExtractor mVideoExtractor = null;
        MediaExtractor mAudioExtractor = null;
        try {
            // video MediaExtractor
            mVideoExtractor = new MediaExtractor();
            mVideoExtractor.setDataSource(inputFile.toString());

            // audio MediaExtractor
            mAudioExtractor = new MediaExtractor();
            mAudioExtractor.setDataSource(inputFile.toString());
            try {
                mMuxer = new MediaMuxer(outputPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
            } catch (IOException ioe) {
                throw new RuntimeException("MediaMuxer creation failed", ioe);
            }

            int muxerAudioTrackIndex = 0;


            int audioIndex = selectTrack(mAudioExtractor, true);
            if (audioIndex >= 0) {
                mAudioExtractor.selectTrack(audioIndex);
                mAudioExtractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
                MediaFormat trackFormat = mAudioExtractor.getTrackFormat(audioIndex);
                muxerAudioTrackIndex = mMuxer.addTrack(trackFormat);
            }

            /**
             * mediacodec + surface + opengl
             * */

            int videoIndex = selectTrack(mVideoExtractor, false);
            if (videoIndex >= 0) {
                boolean outputDone = false;
                boolean inputDone = false;
                int videoTrackIndex = MEDIATYPE_NOT_AUDIO_VIDEO;


                mVideoExtractor.selectTrack(videoIndex);
                mVideoExtractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC);
                MediaFormat inputFormat = mVideoExtractor.getTrackFormat(videoIndex);

                /**
                 ** init mediacodec  / encoder and decoder
                 **/
                prepareEncoder(inputFormat);

                while (!outputDone) {
                    if (!inputDone) {
                        boolean eof = false;
                        int index = mVideoExtractor.getSampleTrackIndex();
                        if (index == videoIndex) {
                            int inputBufIndex = mDecoder.dequeueInputBuffer(TIMEOUT_USEC);
                            if (inputBufIndex >= 0) {
                                ByteBuffer inputBuf;
                                inputBuf = mDecoder.getInputBuffer(inputBufIndex);
                                int chunkSize = mVideoExtractor.readSampleData(inputBuf, 0);
                                if (chunkSize < 0) {
                                    mDecoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                                    inputDone = true;
                                } else {
                                    mDecoder.queueInputBuffer(inputBufIndex, 0, chunkSize, mVideoExtractor.getSampleTime(), 0);
                                    mVideoExtractor.advance();
                                }
                            }
                        } else if (index == -1) {
                            eof = true;
                        }
                        if (eof) {
                            int inputBufIndex = mDecoder.dequeueInputBuffer(TIMEOUT_USEC);
                            if (inputBufIndex >= 0) {
                                mDecoder.queueInputBuffer(inputBufIndex, 0, 0, 0L, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
                                inputDone = true;
                            }
                        }
                    }

                    boolean decoderOutputAvailable = true;
                    while (decoderOutputAvailable) {

                        int encoderStatus = mEncoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
                        if (encoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {

                        } else if (encoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                            MediaFormat newFormat = mEncoder.getOutputFormat();
                            if (videoTrackIndex == MEDIATYPE_NOT_AUDIO_VIDEO) {
                                videoTrackIndex = mMuxer.addTrack(newFormat);
                                mTrackIndex = videoTrackIndex;
                                mMuxer.start();
                            }
                        } else if (encoderStatus < 0) {
                            throw new RuntimeException("unexpected result from mEncoder.dequeueOutputBuffer: " + encoderStatus);
                        } else {
                            ByteBuffer encodedData;
                            encodedData = mEncoder.getOutputBuffer(encoderStatus);
                            if (encodedData == null) {
                                throw new RuntimeException("encoderOutputBuffer " + encoderStatus + " was null");
                            }
                            if (mBufferInfo.size > 1) {
                                if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) == 0) {
                                    mMuxer.writeSampleData(videoTrackIndex, encodedData, mBufferInfo);
                                } else if (videoTrackIndex == MEDIATYPE_NOT_AUDIO_VIDEO) {
                                    byte[] csd = new byte[mBufferInfo.size];
                                    encodedData.limit(mBufferInfo.offset + mBufferInfo.size);
                                    encodedData.position(mBufferInfo.offset);
                                    encodedData.get(csd);
                                    ByteBuffer sps = null;
                                    ByteBuffer pps = null;
                                    for (int a = mBufferInfo.size - 1; a >= 0; a--) {
                                        if (a > 3) {
                                            if (csd[a] == 1 && csd[a - 1] == 0 && csd[a - 2] == 0 && csd[a - 3] == 0) {
                                                sps = ByteBuffer.allocate(a - 3);
                                                pps = ByteBuffer.allocate(mBufferInfo.size - (a - 3));
                                                sps.put(csd, 0, a - 3).position(0);
                                                pps.put(csd, a - 3, mBufferInfo.size - (a - 3)).position(0);
                                                break;
                                            }
                                        } else {
                                            break;
                                        }
                                    }

                                    MediaFormat newFormat = MediaFormat.createVideoFormat(MIME_TYPE, mWidth, mHeight);
                                    if (sps != null) {
                                        newFormat.setByteBuffer("csd-0", sps);
                                        newFormat.setByteBuffer("csd-1", pps);
                                    }
                                    videoTrackIndex = mMuxer.addTrack(newFormat);
                                    mMuxer.start();
                                }
                            }
                            outputDone = (mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0;
                            mEncoder.releaseOutputBuffer(encoderStatus, false);
                        }
                        if (encoderStatus != MediaCodec.INFO_TRY_AGAIN_LATER) {
                            continue;
                        }

                        int decoderStatus = mDecoder.dequeueOutputBuffer(mBufferInfo, TIMEOUT_USEC);
                        if (decoderStatus == MediaCodec.INFO_TRY_AGAIN_LATER) {
                            decoderOutputAvailable = false;
                        } else if (decoderStatus == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {

                        } else if (decoderStatus == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                            MediaFormat newFormat = mDecoder.getOutputFormat();
                            Log.e(TAG, "newFormat = " + newFormat);
                        } else if (decoderStatus < 0) {
                            throw new RuntimeException("unexpected result from mDecoder.dequeueOutputBuffer: " + decoderStatus);
                        } else {
                            boolean doRender = mBufferInfo.size != 0;
                            mDecoder.releaseOutputBuffer(decoderStatus, doRender);
                            if (doRender) {
                                boolean errorWait = false;
                                try {
                                    mInputSurface.awaitNewImage();
                                } catch (Exception e) {
                                    errorWait = true;
                                    Log.e(TAG, e.getMessage());
                                }
                                if (!errorWait) {

                                    mInputSurface.drawImage();
                                    mInputSurface.setPresentationTime(mBufferInfo.presentationTimeUs * 1000);

                                    if (listener != null) {
                                        listener.onProgress((float) mBufferInfo.presentationTimeUs / (float) duration * 100);
                                    }

                                    mInputSurface.swapBuffers();

                                }
                            }
                            if ((mBufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
                                decoderOutputAvailable = false;
                                Log.e(TAG, "decoder stream end");
                                mEncoder.signalEndOfInputStream();
                            }
                        }
                    }
                }
            }
            writeAudioTrack(mAudioExtractor, mMuxer, mBufferInfo, videoStartTime, endTime, cacheFile, muxerAudioTrackIndex);

        } catch (Exception e) {
            error = true;
            Log.e(TAG, e.getMessage());
        } finally {
            if (mVideoExtractor != null) {
                mVideoExtractor.release();
            }

            if (mAudioExtractor != null) {
                mAudioExtractor.release();
            }
            Log.e(TAG, "time = " + (System.currentTimeMillis() - time));
        }
        Log.e("ViratPath", path + "");
        Log.e("ViratPath", cacheFile.getPath() + "");
        Log.e("ViratPath", inputFile.getPath() + "");

        releaseCoder();
        return !error;
    }
Editor is loading...
Leave a Comment