使用媒体提取器整理视频

时间:2019-01-04 13:39:48

标签: android trim mediaextractor

我有一个视频,我需要使用MediaExtractor.seekTo对其进行修剪,然后从提供的时间开始阅读,但这在大多数情况下都不起作用,这是该实现的代码段

    // Set up MediaExtractor to read from the source.
    MediaExtractor extractor = new MediaExtractor();
    extractor.setDataSource(srcPath);
    int trackCount = extractor.getTrackCount();
    // 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);
            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;
            }
        }
    }
    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);
        }
    }
    retrieverSrc.release();

    if (startMs > 0) {
        extractor.seekTo(startMs * 1000, MediaExtractor.SEEK_TO_CLOSEST_SYNC);
    }

    // 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;
    boolean isMuxerHasWrittenFrames = false;
    ByteBuffer dstBuf = ByteBuffer.allocate(bufferSize);
    MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
    try {
        muxer.start();
        while (true) {
            bufferInfo.offset = offset;
            bufferInfo.size = extractor.readSampleData(dstBuf, offset);
            if (bufferInfo.size < 0) {
                bufferInfo.size = 0;
                break;
            } else {
                bufferInfo.presentationTimeUs = extractor.getSampleTime();
                if (endMs > 0 && bufferInfo.presentationTimeUs > (endMs * 1000)) {

                    break;
                } else {
                    bufferInfo.flags = extractor.getSampleFlags();
                    trackIndex = extractor.getSampleTrackIndex();
                    muxer.writeSampleData(indexMap.get(trackIndex), dstBuf, bufferInfo);
                    extractor.advance();
                }
            }
        }
        muxer.stop();

    } catch (IllegalStateException e) {
    }

我试图解决此问题,我尝试从视频中读取示例并检查其演示时间,并对照开始时间进行检查,并检查此示例是否是开始编写的关键框架,这是此实现的一个摘要,

int size = extractor.readSampleData(dstBuf, 0);
    long presentationTime = extractor.getSampleTime();
    while (true) {
        size = extractor.readSampleData(dstBuf, 0);
        if (size <= 0 || (presentationTime >= startTime &&
                extractor.getSampleFlags() == MediaExtractor.SAMPLE_FLAG_SYNC)) {
            break;
        }
        extractor.advance();
    }

预期结果是从提供的时间开始,但实际情况是从0开始而不考虑提供的时间

0 个答案:

没有答案