Обрезка видео с помощью медиа-экстрактора - PullRequest
0 голосов
/ 04 января 2019

У меня есть видео, и мне нужно обрезать его, используя 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 раз, без учета предоставленного времени

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...