Создайте видео из захватов экрана в андроиде

Я хотел бы сделать запись взаимодействия с пользователем в видео, которое люди могут тогда загрузить на их социальные сети.

Например, у приложения для Android Кота Разговора есть немного символа видеокамеры. Пользователь может нажать символ видеокамеры, затем взаимодействовать с приложением, нажать символ, чтобы остановить запись, и затем видео обрабатывается/преобразовывается готовое к закачке.

Я думаю, что могу использовать setDrawingCacheEnabled (верный), чтобы сохранить образы, но не знаю, как добавить аудио или сделать видео.

Update: After further reading I think I will need to use the NDK and ffmpeg. I prefer not to do this, but, if there are no other options, does anyone know how to do this?

Кто-либо знает, как сделать это в Android?

Необходимые ссылки...

завоевание Экрана Android или делают видео из изображений

, как сделать запись видео экрана так же как применение Кота Разговора, делает в iPhone?

3
добавлено отредактировано
Просмотры: 1
de

1 ответы

Используйте MediaCodec API с CONFIGURE_FLAG_ENCODE , чтобы настроить его как кодирующее устройство. Никакой ffmpeg не потребовал:)

Вы уже нашли, как захватить экран в другом вопросе, с которым вы связались, теперь просто необходимо накормить каждую захваченную структуру, чтобы MediaCodec , установив соответствующие флаги формата, метку времени, и т.д.

EDIT: Sample code for this was hard to find, but here it is, hat tip to Martin Storsjö. Quick API walkthrough:

MediaFormat inputFormat = MediaFormat.createVideoFormat("video/avc", width, height);
inputFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
inputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, frameRate);
inputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, colorFormat);
inputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 75);
inputFormat.setInteger("stride", stride);
inputFormat.setInteger("slice-height", sliceHeight);

encoder = MediaCodec.createByCodecName("OMX.TI.DUCATI1.VIDEO.H264E");//need to find name in media codec list, it is chipset-specific

encoder.configure(inputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
encoder.start();
encoderInputBuffers = encoder.getInputBuffers();
encoderOutputBuffers = encoder.getOutputBuffers();

byte[] inputFrame = new byte[frameSize];

while ( ... have data ... ) {
    int inputBufIndex = encoder.dequeueInputBuffer(timeout);

    if (inputBufIndex >= 0) {
        ByteBuffer inputBuf = encoderInputBuffers[inputBufIndex];
        inputBuf.clear();

       //HERE: fill in input frame in correct color format, taking strides into account
       //This is an example for I420
        for (int i = 0; i < width; i++) {
            for (int j = 0; j < height; j++) {
                inputFrame[ i * stride + j ] = ...;//Y[i][j]
                inputFrame[ i * stride/2 + j/2 + stride * sliceHeight ] = ...;//U[i][j]
                inputFrame[ i * stride/2 + j/2 + stride * sliceHeight * 5/4 ] = ...;//V[i][j]
            }
        }

        inputBuf.put(inputFrame);

        encoder.queueInputBuffer(
            inputBufIndex,
            0 /* offset */,
            sampleSize,
            presentationTimeUs,
            0);
    }

    int outputBufIndex = encoder.dequeueOutputBuffer(info, timeout);

    if (outputBufIndex >= 0) {
        ByteBuffer outputBuf = encoderOutputBuffers[outputBufIndex];

       //HERE: read get the encoded data

        encoder.releaseOutputBuffer(
            outputBufIndex, 
            false);
    }
    else {
       //Handle change of buffers, format, etc
    }
}

Есть также некоторые нерешенные вопросы.

EDIT: You'd feed the data in as a byte buffer in one of the supported pixel formats, for example I420 or NV12. There is unfortunately no perfect way of determining which formats would work on a particular device; however it is typical for the same formats you can get from the camera to work with the encoder.

8
добавлено
@Mel: Да, но изображения должны быть преобразованы во множество пикселей в правильном цветовом пространстве, вы can' t просто назначают им на inputFrame без преобразования. Я показал выше, как упаковать множества пикселей в Y, U, V цветовых пространствах в inputFrame; чтобы пойти от png, вы должны к (a) расшифровать png ко множеству пикселей RGB, и (b) преобразовывают каждый пиксель от RGB до YUV; тогда упакуйте вещи как показано выше.
добавлено автор Alex I, источник
Спасибо, проверит его.
добавлено автор Mel, источник
Привет исследование немного, но есть not' примеры tmany там.. как я на самом деле подал бы каждую захваченную структуру в MediaCodec?
добавлено автор Mel, источник
Привет Алекс, спасибо за весь код. Скажите, что у меня была серия изображений, скажем image01.png, image02.png... и т.д., каждый из них был бы назначен на переменную "inputFrame" и затем в конечном счете помещен в переменную ByteBuffer "inputBuf"?
добавлено автор Mel, источник
Там какой-либо путь состоит в том, чтобы сделать то же самое на андроиде?
добавлено автор Umesh Sharma, источник