Untitled

mail@pastecode.io avatar
unknown
plain_text
a month ago
4.8 kB
2
Indexable
Never
public static void mergeVideos(String filePath1, String filePath2, String outputFile) throws IOException {
    MediaMuxer mediaMuxer = null;
    MediaExtractor videoExtractor1 = new MediaExtractor();
    MediaExtractor videoExtractor2 = new MediaExtractor();
    try {
        mediaMuxer = new MediaMuxer(outputFile, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);

        // Trích xuất và ghi track video từ video đầu tiên
        videoExtractor1.setDataSource(filePath1);
        int videoTrackIndex1 = selectTrack(videoExtractor1, "video/");
        MediaFormat videoFormat1 = videoExtractor1.getTrackFormat(videoTrackIndex1);
        videoExtractor1.selectTrack(videoTrackIndex1);
        int muxerVideoTrackIndex1 = mediaMuxer.addTrack(videoFormat1);

        // Trích xuất và ghi track audio từ video đầu tiên (nếu có)
        int audioTrackIndex1 = selectTrack(videoExtractor1, "audio/");
        int muxerAudioTrackIndex1 = -1;
        if (audioTrackIndex1 >= 0) {
            MediaFormat audioFormat1 = videoExtractor1.getTrackFormat(audioTrackIndex1);
            videoExtractor1.selectTrack(audioTrackIndex1);
            muxerAudioTrackIndex1 = mediaMuxer.addTrack(audioFormat1);
        }

        // Trích xuất và ghi track video từ video thứ hai
        videoExtractor2.setDataSource(filePath2);
        int videoTrackIndex2 = selectTrack(videoExtractor2, "video/");
        MediaFormat videoFormat2 = videoExtractor2.getTrackFormat(videoTrackIndex2);
        videoExtractor2.selectTrack(videoTrackIndex2);
        int muxerVideoTrackIndex2 = mediaMuxer.addTrack(videoFormat2);

        // Trích xuất và ghi track audio từ video thứ hai (nếu có)
        int audioTrackIndex2 = selectTrack(videoExtractor2, "audio/");
        int muxerAudioTrackIndex2 = -1;
        if (audioTrackIndex2 >= 0) {
            MediaFormat audioFormat2 = videoExtractor2.getTrackFormat(audioTrackIndex2);
            videoExtractor2.selectTrack(audioTrackIndex2);
            muxerAudioTrackIndex2 = mediaMuxer.addTrack(audioFormat2);
        }

        mediaMuxer.start();

        // Ghi dữ liệu video và audio từ video đầu tiên
        long lastVideoPresentationTimeUs = writeSampleData(videoExtractor1, mediaMuxer, muxerVideoTrackIndex1, muxerAudioTrackIndex1, 0);
        
        // Nếu video đầu tiên không có âm thanh, ghi lại thời gian cuối cùng của track video
        long lastAudioPresentationTimeUs = (muxerAudioTrackIndex1 >= 0) ? lastVideoPresentationTimeUs : 0;
        if (muxerAudioTrackIndex1 >= 0) {
            lastAudioPresentationTimeUs = writeSampleData(videoExtractor1, mediaMuxer, muxerVideoTrackIndex1, muxerAudioTrackIndex1, 0);
        }

        // Ghi dữ liệu video và audio từ video thứ hai
        writeSampleData(videoExtractor2, mediaMuxer, muxerVideoTrackIndex2, muxerAudioTrackIndex2, lastVideoPresentationTimeUs);

    } finally {
        if (mediaMuxer != null) {
            try {
                mediaMuxer.stop();
                mediaMuxer.release();
            } catch (Exception e) {
                logger.severe(e.toString());
            }
        }
        videoExtractor1.release();
        videoExtractor2.release();
    }
}

private static long writeSampleData(MediaExtractor extractor, MediaMuxer muxer, int videoTrackIndex, int audioTrackIndex, long startPresentationTimeUs) {
    Log.d(TAG, "writeSampleData: check videoindex " + videoTrackIndex);
    Log.d(TAG, "writeSampleData: check audioindex " + audioTrackIndex);
    int bufferSize = determineBufferSize(extractor, videoTrackIndex);
    ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
    MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
    long lastPresentationTimeUs = startPresentationTimeUs;

    while (true) {
        bufferInfo.offset = 0;
        bufferInfo.size = extractor.readSampleData(buffer, 0);
        if (bufferInfo.size < 0) {
            Log.d(TAG, "No more samples to read");
            bufferInfo.size = 0;
            break;
        }
        bufferInfo.presentationTimeUs = extractor.getSampleTime() + startPresentationTimeUs;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            bufferInfo.flags = mapExtractorFlagsToCodecFlags(extractor.getSampleFlags());
        }
        int trackIndex = extractor.getSampleTrackIndex();
        if (trackIndex == videoTrackIndex) {
            muxer.writeSampleData(videoTrackIndex, buffer, bufferInfo);
        } else if (trackIndex == audioTrackIndex) {
            muxer.writeSampleData(audioTrackIndex, buffer, bufferInfo);
        }
        lastPresentationTimeUs = bufferInfo.presentationTimeUs;
        extractor.advance();
    }
    return lastPresentationTimeUs;
}
Leave a Comment