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