Добавление растрового изображения водяного знака поверх видео в android: MediaMuxer 4.3 или ffmpeg
Вот мой сценарий:
- Загрузите avi-фильм из Интернета
- Открыть растровый ресурс
- Наложите это bitmap внизу фильма на все кадры в фоновом режиме
- Сохраните видео на extarnal storage
- Длина видео составляет 15 секунд
Можно ли это использовать с помощью MediaMuxer? Любая информация по этому вопросу с радостью принимается
Я искал http://bigflake.com/mediacodec/#DecodeEditEncodeTest (спасибо @fadden), и там говорится:
- Используйте кодек ffmpeg для объединения файлов * .ts в один mp4
- Как конвертировать WMV в MP4?
- Точно вырезать видео файлы из командной строки
- FFmpeg сплит видео и слияние
- Конвертировать Mp4 в Mp3 с миниатюрой
«Декодирование кадра и копирование его в ByteBuffer с помощью
glReadPixels()
занимает около 8 мс на Nexus 5, достаточно быстро, чтобы идти в ногу с 30fps-входом, но дополнительные шаги, необходимые для сохранения его на диск в виде PNG, дороги (около половины Второй)”
Так что почти 1 сек / фрейм неприемлем. Из того, что я думаю, один из способов заключается в том, чтобы сохранить каждый фрейм как PNG, открыть его, добавить на него наложение растрового изображения и затем сохранить его. Однако для этого потребуется огромное количество времени.
Интересно, есть ли способ сделать что-то вроде этого:
- Открыть видеофайл с внешнего хранилища
- Начните декодировать его
- Каждый декодированный кадр будет изменен с наложением растрового изображения в памяти
- Кадр отправляется кодеру.
На iOS я увидел, что есть способ взять исходное аудио + оригинальное видео + изображение и добавить его в контейнер, а затем просто закодировать все это …
Должен ли я переключиться на ffmpeg? Насколько стабильным и совместимым является ffmpeg? Я рискую проблемы совместимости с устройствами Android 4.0+? Есть ли способ использовать ffmpeg для этого? Я новичок в этой области и все еще занимаюсь исследованиями.
Годы спустя редактирование:
Годы прошли с тех пор, как вопрос и ffmpeg на самом деле нелегко добавить в коммерческое программное обеспечение с точки зрения лицензии. Как это произошло? Более новые версии android более способны на это со стандартным sdk?
- Конвертировать mp4 в mp3
- Есть ли способ мягко вставлять субтитры в файл mp4 без повторного кодирования?
- Могу ли я иметь видео с прозрачным фоном, используя тег HTML5?
- Пост-обработка в ffmpeg для перемещения атома moov в файлах MP4 (qt-faststart)
- Как преобразовать .iso в .mp4 без установки с помощью ffmpeg
- Другое: принудительно Chrome полностью загружать mp4-видео
- Есть ли Java API для файлов mp4?
- FFMPEG разделяет MP4 с тем же качеством
Я не очень много знаю о MediaMuxer, но ffmpeg поддерживает наложенную функциональность. FFMPEG имеет различные фильтры, один из которых – фильтр наложения. Я понимаю, что вы хотите наложить изображение (т.е. png) на видео, ffmpeg наверняка является полезной основой для выполнения этой работы. Вы можете установить формат вывода, который вы можете установить координаты изображения, которое должно быть переигрено.
Например
ffmpeg -i input.avi -i logo.png -filter_complex 'overlay=10:main_h-overlay_h-10' output.avi
Команда выше добавляет overlays logo.png в файл видео входа.avi в левом нижнем углу.
Более подробную информацию об фильтрах можно найти на следующем веб-сайте,
https://www.ffmpeg.org/ffmpeg-filters.html#overlay-1
Если это решение вашей проблемы, вам нужен код C, эквивалентный приведенной выше команде. Вам также нужно увидеть производительность ffmpeg, потому что это чистая программная среда.
Надеюсь, я правильно понял ваш вопрос, и это помогает.
Если вам нужно сделать это без ffmpeg на устройстве Android:
Начать с: https://github.com/google/grafika
Ответ на ваш вопрос между примерами воспроизведения видео (PlayMovieActivity.java) и Record Gl App (RecordFBOActivity.java) .
шаги:
-
Установите mInputWindowSurface как входную поверхность видеокодера.
-
Декодирование кадра из видеоstreamа с использованием MoviePlayer в качестве видео (внешней) текстуры.
-
Нарисуйте эту видео текстуру на поверхности.
-
Нарисуйте водяной знак на той же поверхности поверх видео текстуры.
-
Сообщите MediaCodec, что поверхность готова для кодирования:
mVideoEncoder.frameAvailableSoon(); mInputWindowSurface.setPresentationTime(timeStampNanos);
и затем перейти к этапу 2.
Не забудьте настроить скорость декодирования. Просто удалите SpeedControlCallback
который в примере установлен для декодирования видео 60 FPS.
Преимущества этого способа:
-
Media Codec использует аппаратный декодер / кодировщик для обработки видео.
-
Вы можете изменить скорость передачи видео.
Вы можете попробовать INDE Media Pack – https://software.intel.com/en-us/articles/intel-inde-media-pack-for-android-tutorials
Он имеет функции перекодирования \ ремуксирования как class MediaComposer и несколько примеров таких эффектов, как JpegSubstituteEffect, – показывает, как заменить рамку видео на изображение из файла jpg и TextOverlayEffect, чтобы наложить текст на видеокадр и т. Д. Его можно было бы легко увеличить до эффекта водяного знака
Это то, что сработало для меня:
ffmpeg -i input.avi -i logo.png -filter_complex 'overlay=10:main_h-overlay_h-10' -strict -2 output.avi
ffmpeg рекомендовал использовать -strict -2
для использования экспериментальных кодеков. без включения, принятый ответ выше не работает.