Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
416 views
in Technique[技术] by (71.8m points)

opencv - Android video encoding with fr and resolution manipulation

I want to be able to take a video recorded with an Android device and encode it to a new Resolution and Frame Rate using my app. The purpose is to upload a much smaller version of the original video (in size), since this will be videos 30 min long or more.

So far, I've read of people saying FFmpeg is they way to go. However, the documentation seems to be lacking.

I have also considered using http opencv http://opencv.org/platforms/android.html

Considering I need to manipulate the video resolution and frame rate, which tool do you think can do such things better? Are there any other technologies to consider?

An important question is, since this will be long videos, is it reasonable to do the encoding in an android device (Consider power resources, time, etc.)

Thanks in advance!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I decided to use ffmpeg to tackle this project. After much researching and trials, I was not able to build ffmpeg for library (using Ubuntu 14.04 LTS.)

However, I used this excellent library https://github.com/guardianproject/android-ffmpeg-java I just created a project and added that library and it works like a charm. No need to build your own files or mess with the Android NDK. Of course you would still need to build the library yourself if you want to customize it. But it has everything I need.

Here is an example of how I used to lower a video resolution and change the frame rate:

                    @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // input source
            final Clip clip_in = new Clip("/storage/emulated/0/Developer/test.mp4"); 

            Activity activity = (Activity) MainActivity.this;
            File fileTmp = activity.getCacheDir(); 
            File fileAppRoot = new File(activity.getApplicationInfo().dataDir);

            final Clip clip_out = new Clip("/storage/emulated/0/Developer/result2.mp4");
            //put flags in clip
            clip_out.videoFps = "30";
            clip_out.width = 480;
            clip_out.height = 320;
            clip_out.videoCodec = "libx264";
            clip_out.audioCodec = "copy";

            try {
                FfmpegController fc = new FfmpegController(fileTmp, fileAppRoot);
                fc.processVideo(clip_in, clip_out, false, new ShellUtils.ShellCallback() {

                    @Override
                    public void shellOut(String shellLine) {
                        System.out.println("MIX> " + shellLine);
                    }

                    @Override
                    public void processComplete(int exitValue) {

                        if (exitValue != 0) {
                            System.err.println("concat non-zero exit: " + exitValue);
                            Log.d("ffmpeg","Compilation error. FFmpeg failed");
                            Toast.makeText(MainActivity.this, "result: ffmpeg failed", Toast.LENGTH_LONG).show();
                        } else {
                            if(new File( "/storage/emulated/0/Developer/result2.mp4").exists()) {
                                Log.d("ffmpeg","Success file:"+ "/storage/emulated/0/Developer/result2.mp4");
                            }
                        }
                    }
                });
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            // automated try and catch
            setContentView(R.layout.activity_main);
        }
    }

The function processVideo produces a command similar to ffmpeg -i input -s 480X320 -r 30 -vcodec libx264 -acodec copy output

This a very simple example, but it outputted the same kind of conversion done by ffmpeg desktop. This codes needs lots of work! I hope it helps anyone.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...