使用MediaCodec,Media Extractor和Media Muxer在Android上进行视频修剪

时间:2019-11-18 22:05:33

标签: android video mediacodec mediamuxer

在我的Android应用中,当用户可以从内部存储中修剪视频时,我需要一个解决方案。我试图在不使用任何第三方库的情况下实现这一目标。我正在引用此Google的Gallery App源代码here。但是我收到以下错误:

timestampUs 66733 <用于视频轨道的lastTimestampUs 133467

很少有关于这个时间戳记问题的问题,但是我真的不是想弄清楚,因为我是使用MediaCodecs,MediaMuxers等的新手。如果可以的话,会很棒

这是我的代码:

 // Set up MediaExtractor to read from the source.
    MediaExtractor extractor = new MediaExtractor();
    extractor.setDataSource(srcPath);
    int trackCount = extractor.getTrackCount();
    System.out.println("tracl" + trackCount);
    // Set up MediaMuxer for the destination.
    MediaMuxer muxer;
    muxer = new MediaMuxer(dstPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);



    // Set up the tracks and retrieve the max buffer size for selected
    // tracks.
    HashMap<Integer, Integer> indexMap = new HashMap<>(trackCount);
    int bufferSize = -1;
    for (int i = 0; i < trackCount; i++) {
        MediaFormat format = extractor.getTrackFormat(i);


        String mime = format.getString(MediaFormat.KEY_MIME);
        boolean selectCurrentTrack = false;
        if (mime.startsWith("audio/") && useAudio) {
            selectCurrentTrack = true;
        } else if (mime.startsWith("video/") && useVideo) {
            selectCurrentTrack = true;
        }
        if (selectCurrentTrack) {
            extractor.selectTrack(i);
            int dstIndex = muxer.addTrack(format);
            System.out.println(format);
            System.out.println("dstIndex" + dstIndex);

            indexMap.put(i, dstIndex);
            if (format.containsKey(MediaFormat.KEY_MAX_INPUT_SIZE)) {
                int newSize = format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);
                bufferSize = newSize > bufferSize ? newSize : bufferSize;
            }
        }
    }

    System.out.println(indexMap);

    if (bufferSize < 0) {
        bufferSize = DEFAULT_BUFFER_SIZE;
    }
    // Set up the orientation and starting time for extractor.
    MediaMetadataRetriever retrieverSrc = new MediaMetadataRetriever();
    retrieverSrc.setDataSource(srcPath);
    String degreesString = retrieverSrc.extractMetadata(
            MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
    if (degreesString != null) {
        int degrees = Integer.parseInt(degreesString);
        if (degrees >= 0) {
            muxer.setOrientationHint(degrees);
        }
    }
    if (startMs > 0) {
        extractor.seekTo(startMs * 1000, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
    }


  //  System.out.println(extractor.);
    // Copy the samples from MediaExtractor to MediaMuxer. We will loop
    // for copying each sample and stop when we get to the end of the source
    // file or exceed the end time of the trimming.
    int offset = 0;
    int trackIndex = -1;
    ByteBuffer dstBuf = ByteBuffer.allocate(bufferSize);
    MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();


    try {
        muxer.start();
        while (true) {

            System.out.println("copying");
            bufferInfo.offset = offset;


            bufferInfo.size = extractor.readSampleData(dstBuf, offset);



            if (bufferInfo.size < 0 ) {
               // InstabugSDKLogger.d(TAG, "Saw input EOS.");
                System.out.println("Saw input EOS.");
                bufferInfo.size = 0;
                break;
            } else {

                /**
                 * The presentation timestamp in microseconds for the buffer.
                 * This is derived from the presentation timestamp passed in
                 * with the corresponding input buffer.  This should be ignored for
                 * a 0-sized buffer.
                 */

                /**
                 * Returns the current sample's presentation time in microseconds.
                 * or -1 if no more samples are available.
                 */
                bufferInfo.presentationTimeUs = extractor.getSampleTime();

                //1 sec = 1000000 micco sec


                if (endMs > 0 && bufferInfo.presentationTimeUs > (endMs * 1000)) {


                    break;
                } else {
                    bufferInfo.flags = extractor.getSampleFlags();
                    trackIndex = extractor.getSampleTrackIndex();


                    muxer.writeSampleData(indexMap.get(trackIndex), dstBuf, bufferInfo);

                    //System.out.println(muxer);
                    extractor.advance();
                }
            }
        }

        muxer.stop();




        File file = new File(srcPath);
        file.delete();
    } catch (IllegalStateException e) {



        System.out.println("The source video file is malformed");


    } finally {


        muxer.release();

    }

0 个答案:

没有答案