Android захватывает замедленное видео

Как я могу захватить замедленное видео в моем приложении?

Я пытался с помощью

 mMediaRecorder.setVideoFrameRate(100);

но приложение вылетает, если я установил значение 20 или более с IllegalStateException,

Я много исследовал. Нормальное видео составляет от 24 до 30 кадров в секунду. Чтобы увидеть замедленное видео, нам нужно захватить 100-120 кадров в секунду, но устройство этого не позволяет. Но я вижу, что камера по умолчанию в моем устройстве имеет опцию Slow motion.Также несколько приложений в магазине воспроизведения позволяют создавать видеоролики с замедленным движением. Я также пытался установить более высокое значение. setCaptureRate(), но с этим также захватывается видео в нормальном режиме. В нескольких местах упоминается, что замедленное кино может быть достигнуто через OpenCV/JavaCV библиотеки, но я не смог понять, как использовать эти библиотеки для захвата замедленного видео в Android?

4 ответа

Из предоставленного вами источника (CamcorderProfile) все, что вам нужно сделать, это УВЕЛИЧИТЬ количество снятых изображений в секунду:

mMediaRecorder.setVideoFrameRate(QUALITY_HIGH_SPEED_LOW);

или же

mMediaRecorder.setVideoFrameRate(QUALITY_HIGH_SPEED_HIGH);

Таким образом, если вы берете 100 изображений в секунду и показывает 25 кадров в секунду, эта записанная секунда занимает 4 секунды, чтобы показать

Пожалуйста, прочтите документацию по классу, который вы используете:

public static final int QUALITY_HIGH_SPEED_LOW

Высокоскоростной ( >= 100 к / с) уровень качества, соответствующий наименьшему доступному разрешению.

Для всех высокоскоростных профилей, определенных ниже ((от QUALITY_HIGH_SPEED_LOW до QUALITY_HIGH_SPEED_2160P), они похожи на обычные профили записи, только с более высокой выходной частотой кадров и скоростью передачи данных. Поэтому, устанавливая эти профили с помощью setProfile(CamcorderProfile) без указания каких-либо других параметров кодирования будет производить высокоскоростное видео, а не замедленное видео с различной частотой кадров захвата и вывода (воспроизведения). Чтобы записывать замедленное видео, приложение должно соответствующим образом установить частоту кадров и скорость вывода видео (воспроизведение) с помощью setVideoFrameRate (int) и setVideoEncodingBitRate (int) на основе коэффициента замедленного движения. Если приложение намеревается выполнить запись видео с помощью кодера MediaCodec, оно должно установить каждое отдельное поле MediaFormat аналогично в соответствии с этим CamcorderProfile.

Хотя я не могу захватывать плавное замедленное видео без рывков, но я могу преобразовать захваченное видео в замедленное, используя ffmpeg, который получается очень плавным и равномерным. Для интеграции FFmpeg в Android мы можем использовать предварительно скомпилированные библиотеки, такие как ffmpeg-android,

Согласно рассматриваемому случаю, мы можем захватывать видео с камеры, а затем конвертировать его в замедленное движение с помощью ffmpeg.

Для создания замедленного видео мы можем использовать следующую команду:

String[] complexCommand = {"-y", "-i", inputFileAbsolutePath, "-filter_complex", "[0:v]setpts=2.0*PTS[v];[0:a]atempo=0.5[a]", "-map", "[v]", "-map", "[a]", "-b:v", "2097k", "-r", "60", "-vcodec", "mpeg4", outputFileAbsolutePath};

Вот,

-y

Перезаписать выходные файлы без запроса

ffmpeg читает из произвольного числа входных "файлов", указанных в опции -i

-карта

Ярлыки выходных ссылок указываются с -map.

-b: v

Установите битрейт видео

Установить частоту кадров

-vcodec

Установите видео кодек

-filter_complex filtergraph

Определите сложный фильтрующий граф, то есть один с произвольным количеством входов и / или выходов. Фильтр работает путем изменения метки времени представления (PTS) каждого видеокадра. Чтобы замедлить видео, необходимо использовать множитель больше 1. Например, если в метках времени 1 и 2 показаны два последовательных кадра, и вы Если вы хотите замедлить видео, эти временные метки должны равняться 2 и 4 соответственно. Таким образом, мы должны умножить их на 2,0.

Вы можете ускорить или замедлить звук с помощью аудио фильтра atemto. Фильтр atempo ограничен использованием значений от 0,5 до 2,0 (поэтому он может замедлять его не менее чем до половины первоначальной скорости и увеличивать скорость не более чем в два раза вход). Чтобы замедлить звук до половины его скорости, мы должны использовать значение atempo 0,5 .

Посмотрите это руководство по редактору видео fffmpeg, которое я написал в своем блоге, которое включает создание замедленного видео и полный код для этого руководства здесь.

То, что работало для меня, должно было повысить скорость захвата mMediaRecorder лайк:

mMediaRecorder.setVideoFrameRate(profile.videoFrameRate / 2);
mMediaRecorder.setVideoEncodingBitRate(profile.videoBitRate / 2);
mMediaRecorder.setCaptureRate(profile.videoFrameRate);

куда profile это CamcorderProfileустановить с QUALITY_HIGH (Я не могу иметь больше, так как я использую LG G2, API 19).

Здесь, в моем случае,profile.videoFrameRate равен 30

Подробнее о setCaptureRate в официальной документации:

Установите частоту захвата видеокадров. Это можно использовать для установки частоты захвата видеокадров, отличной от частоты воспроизведения записанного видео. Этот метод также устанавливает режим записи в промежуток времени. При покадровой записи видео записывается только видео. Параметры, связанные со звуком, игнорируются, когда начинается сеанс интервальной записи, если приложение устанавливает их.

Результат записи видео в два раза дольше первоначального захвата. Однако установка скорости захвата отключает звук. В моем случае моя максимальная частота кадров составляет 30 кадров в секунду, а затем она воспроизводится со скоростью 15 кадров в секунду.

Надеюсь, поможет.

Попробуйте этот код. Это поможет...

myCamera = getCameraInstance();
mediaRecorder = new MediaRecorder();
myCamera.unlock();
mediaRecorder.setCamera(myCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
mediaRecorder.setPreviewDisplay(mSurfaceView.getHolder().getSurface());
Другие вопросы по тегам