Skip to content
Muhammad Umair Shafique edited this page Jun 7, 2016 · 9 revisions

Permanent effects to video

The most commonly used technique for video processing is through ffmpeg. Which is a bit hectic but not impossible to integrate in android. However there are many compilable library projects available which have complied ffmpeg libraries. The most commonly used is javacv, which is a wrapper of ffmpeg and opencv. In this project we have used javacv to permanently apply effects over video.

Here is a link to javacv github project.

JavaCV

Add following dependencies to app level build.gradle

`compile group: 'org.bytedeco', name: 'javacv', version: '1.1'`
`compile group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.0.0-1.1', classifier: 'android-arm'`
`compile group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '2.8.1-1.1', classifier: 'android-arm'`

As video processing is a heavy task, we should do it in the background thread.

import android.content.Context; import android.os.AsyncTask; import android.os.Environment; import org.bytedeco.javacv.FFmpegFrameFilter; import org.bytedeco.javacv.FFmpegFrameGrabber; import org.bytedeco.javacv.FFmpegFrameRecorder; import org.bytedeco.javacv.Frame; import org.bytedeco.javacv.FrameFilter; import org.bytedeco.javacv.FrameGrabber; import org.bytedeco.javacv.FrameRecorder; import java.io.File;

/**

  • Created by umair.shafique on 6/2/2016. */ public class VideoProcessing extends AsyncTask {

    private final File myDirectory; private FFmpegFrameGrabber VIDEO_GRABBER; private FFmpegFrameRecorder videoRecorder; private File file; private int totalLength; private Context mContext; private FFmpegFrameFilter filter;

    public VideoProcessing(Context context, String path) { mContext = context; file = new File(path); VIDEO_GRABBER = new FFmpegFrameGrabber(file); myDirectory = new File(Environment.getExternalStorageDirectory() + "/Edited Video/"); if (!myDirectory.exists()) { myDirectory.mkdirs(); } }

    @Override protected void onPreExecute() { super.onPreExecute(); }

    @Override protected Object doInBackground(Object[] params) { Frame tempVideoFrame; try { VIDEO_GRABBER.start(); initVideoRecorder(myDirectory + "/video" + System.currentTimeMillis() + ".mp4"); filter.start(); while (VIDEO_GRABBER.grab() != null) { tempVideoFrame = VIDEO_GRABBER.grabImage(); if (tempVideoFrame != null) { filter.push(tempVideoFrame); tempVideoFrame = filter.pull(); videoRecorder.record(tempVideoFrame); } } filter.stop(); videoRecorder.stop(); videoRecorder.release(); VIDEO_GRABBER.stop(); VIDEO_GRABBER.release(); } catch (FrameGrabber.Exception e) { e.printStackTrace(); } catch (FrameRecorder.Exception e) { e.printStackTrace(); } catch (FrameFilter.Exception e) { e.printStackTrace(); } return null; }

    @Override protected void onPostExecute(Object o) { super.onPostExecute(o); }

    private void initVideoRecorder(String path) { try { // ffmpeg filter for sepia filter = new FFmpegFrameFilter("colorchannelmixer=.393:.769:.189:0:.349:.686:.168:0:.272:.534:.131", VIDEO_GRABBER.getImageWidth(), VIDEO_GRABBER.getImageHeight());

         videoRecorder = FFmpegFrameRecorder.createDefault(path, VIDEO_GRABBER.getImageWidth(), VIDEO_GRABBER.getImageHeight());
    

// Optional if you want to change some parameter

// videoRecorder.setVideoCodec(avcodec.AV_CODEC_ID_H264); // videoRecorder.setVideoCodec(VIDEO_GRABBER.getVideoCodec()); // videoRecorder.setVideoOption("preset", "ultrafast"); // videoRecorder.setFrameRate(30); // videoRecorder.setFormat("mp4"); // videoRecorder.setVideoBitrate(VIDEO_GRABBER.getVideoBitrate()); // videoRecorder.setAudioChannels(VIDEO_GRABBER.getAudioChannels()); videoRecorder.start(); } catch (FrameRecorder.Exception e) { e.printStackTrace(); } } }

Clone this wiki locally