ffmpeg-android-java icon indicating copy to clipboard operation
ffmpeg-android-java copied to clipboard

Compress the video in background

Open Vijayadhas opened this issue 9 years ago • 7 comments

Hi, Thanks for the lib. It is very useful to my project. But if I take 2 min video mean it will take more than 5 min to compress. I am trying to run the compress process in background. But I can not do that. It requires UI injection. Is there any way to run the compress in background. So that user no need to wait for the compression. Please let me any idea to run the video compression in background.

Vijayadhas avatar Apr 21 '16 12:04 Vijayadhas

You can use an IntentService for that: http://developer.android.com/training/run-background-service/create-service.html

SebSob avatar Apr 22 '16 16:04 SebSob

It require UI injection. I can not inject the UI from service. Please let me how to do this.

Vijayadhas avatar May 13 '16 11:05 Vijayadhas

You can use LocalBroadcastManager for that.

For example in your IntentService you can sendBroadcast() with an intent containing the data you need to update the UI:

Intent localProgressIntent = new Intent("BROADCAST_CREATEVIDEO_PROCESSING");

// Puts the status into the Intent
localProgressIntent.putExtra("CREATION_CURRENT_PROGRESS", progress);

// Broadcasts the Intent to receivers in this app.     
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(localProgressIntent);

In the Activity where you want UI changes, you first have to listen to those broadcasts:

// The filter's action key is "BROADCAST_CREATEVIDEO_PROCESSING"
IntentFilter mStatusIntentFilter = new IntentFilter("BROADCAST_CREATEVIDEO_PROCESSING");
LocalBroadcastManager.getInstance(this).registerReceiver(mCreateVideoProcessReceiver, mStatusIntentFilter);

Where mCreateVideoProcessReceiver is the function that will be called when this activity receives data, so when you called sendBroadcast() in your IntentService.

private BroadcastReceiver mCreateVideoProcessReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        //Get the intent extras
        Bundle extras = intent.getExtras();

        if (extras != null){
            //Get the progress that was passed
            int currentProgress = extras.getInt("CREATION_CURRENT_PROGRESS");
            mProgressBar.setProgress(currentProgress);
        }

    }
};

More information can be found in the Android docs: http://developer.android.com/training/run-background-service/report-status.html

SebSob avatar May 13 '16 12:05 SebSob

Hi @SebSob @hiteshsondhi88 .. I am trying like this. I attached the code for your review.

public class VideoCompressionService extends Service {

    private static final String TAG = VideoCompressActivity.class.getSimpleName();

    @Inject
    FFmpeg ffmpeg;

    private static final int MY_NOTIFICATION_ID = 1;   
    NotificationManager notificationManager;
    Notification myNotification;

    @Override
    public void onCreate() {
        // TODO Auto-generated method stub
        super.onCreate();
        notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // Let it continue running until it is stopped.
        Toast.makeText(this, "BGService Service Started", Toast.LENGTH_LONG).show();
        Log.e("My Service==> ", "Started..");
        notifyMessage("onStartCommand Start");
        loadFFMpegBinary();
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("My Service==> ", "onDestroy..");
    }

    public void loadFFMpegBinary() {
        try {
            notifyMessage("loadFFMpegBinary Start");
            ffmpeg.loadBinary(new LoadBinaryResponseHandler() {
                @Override
                public void onFailure() {
                    Alerts.getInstance().showUnsupportedExceptionDialog();
                }
            });
            notifyMessage("loadFFMpegBinary Second");
            compressVideo(CustomCameraHandler.getInstance().getVideoPathDetails(), CustomCameraHandler.getInstance().getCCVideoOutPutPath().getAbsolutePath(), ffmpeg);

        } catch (FFmpegNotSupportedException e) {
            Alerts.getInstance().showUnsupportedExceptionDialog();
        }
    }

    public void compressVideo(String source,String desc, FFmpeg ffmpeg){
        notifyMessage("compressVideo Start");
        MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();
        metaRetriever.setDataSource(source);
        String strtime = metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
        int duration = Integer.parseInt(strtime);
        int bitrate = calBitrate(duration / 1000, Integer.parseInt("10"));
        int bufferSize=bitrate*2;
        String cmd=String.format(Constants.FFMPEG_COMPRESS_COMMAND, bitrate, bufferSize);
        cmd = Constants.FFMPEG_COMPRESS_RULES + source + cmd + desc;
        String[] command = cmd.split(" ");
        if (command.length != 0) {
            notifyMessage("==> compressVideo If Start");
            execFFmpegBinary(command,ffmpeg );
        } else {
            Toast.makeText(Application.getInstance().getApplicationContext(), "empty_command_toast", Toast.LENGTH_LONG).show();
        }
    }
    private void execFFmpegBinary(final String[] command,FFmpeg ffmpeg ) {
        try {
            notifyMessage("==> execFFmpegBinary Start");
            ffmpeg.execute(command, new ExecuteBinaryResponseHandler() {
                @Override
                public void onFailure(String s) {
                    notifyMessage("==> onFailure Start");
                    onDestroy();
                    Log.d(TAG, "FAILED with output : " + s);
                }

                @Override
                public void onSuccess(String s) {
                    notifyMessage("==> onSuccess Start");
                    onDestroy();
                    Log.d(TAG, "SUCCESS with output : " + s);
                }

            });
        } catch (FFmpegCommandAlreadyRunningException e) {
            // do nothing for now
        }
    }

    private int calBitrate(int duration, int targetSize){
        targetSize = targetSize*1024*1024;
        int audiosize = (120*1000/8)*duration;
        return (targetSize-audiosize)*8/duration;
    }

    private void notifyMessage(String message){
        String notificationText = message;
        myNotification = new NotificationCompat.Builder(getApplicationContext())
                .setContentTitle("Progress")
                .setContentText(notificationText)
                .setTicker("Notification!")
                .setWhen(System.currentTimeMillis())
                        //.setDefaults(Notification.DEFAULT_SOUND)
                .setAutoCancel(true)
                .setSmallIcon(R.drawable.ic_launcher)
                .build();

        notificationManager.notify(MY_NOTIFICATION_ID, myNotification);
    }

}

But I am getting Nullpointer exception in ffmpeg.loadBinary(new LoadBinaryResponseHandler(). I tried many way. I can not move the compression to background service. Please let me know any other idea to resolve this. Thanks in advance.

Vijayadhas avatar May 17 '16 12:05 Vijayadhas

That's would be ideal to handle this is background, since it takes time. How did you handle it finally @Vijayadhas ? Thanks in advance.

shobhitpuri avatar May 24 '18 19:05 shobhitpuri

Hi @Vijayadhas I am using this command for compressing video file , String[] mcpress={"-i","/storage/emulated/0/ffmpegTest/vtv_status.mp4","-c:v h264 -acodec mp3","/storage/emulated/0/ffmpegTest/mout.mp4"};

but i am getting following error in Onfailure. could you please tell how did you compress the video?

ffmpeg version n3.0.1 Copyright (c) 2000-2016 the FFmpeg developers built with gcc 4.8 (GCC) configuration: --target-os=linux --cross-prefix=/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/bin/arm-linux-androideabi- --arch=arm --cpu=cortex-a8 --enable-runtime-cpudetect --sysroot=/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/sysroot --enable-pic --enable-libx264 --enable-libass --enable-libfreetype --enable-libfribidi --enable-libmp3lame --enable-fontconfig --enable-pthreads --disable-debug --disable-ffserver --enable-version3 --enable-hardcoded-tables --disable-ffplay --disable-ffprobe --enable-gpl --enable-yasm --disable-doc --disable-shared --enable-static --pkg-config=/home/vagrant/SourceCode/ffmpeg-android/ffmpeg-pkg-config --prefix=/home/vagrant/SourceCode/ffmpeg-android/build/armeabi-v7a --extra-cflags='-I/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/include -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -fno-strict-overflow -fstack-protector-all' --extra-ldflags='-L/home/vagrant/SourceCode/ffmpeg-android/toolchain-android/lib -Wl,-z,relro -Wl,-z,now -pie' --extra-libs='-lpng -lexpat -lm' --extra-cxxflags= libavutil 55. 17.103 / 55. 17.103 libavcodec 57. 24.102 / 57. 24.102 libavformat 57. 25.100 / 57. 25.100 libavdevice 57. 0.101 / 57. 0.101 libavfilter 6. 31.100 / 6. 31.100 libswscale 4. 0.100 / 4. 0.100 libswresample 2. 0.101 / 2. 0.101 libpostproc 54. 0.100 / 54. 0.100 Trailing options were found on the commandline. Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/storage/emulated/0/ffmpegTest/vtv_status.mp4': Metadata: major_brand : isom minor_version : 512 compatible_brands: isomiso2avc1mp41 encoder : Lavf57.71.100 Duration: 00:00:15.25, start: 0.046440, bitrate: 890 kb/s Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 640x272 [SAR 1:1 DAR 40:17], 757 kb/s, 25 fps, 25 tbr, 12800 tbn, 50 tbc (default) Metadata: handler_name : VideoHandler Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default) Metadata: handler_name : SoundHandler At least one output file must be specified

DroidCraftsmanKK avatar Feb 02 '19 12:02 DroidCraftsmanKK

String[] mcpress={"-i","/storage/emulated/0/ffmpegTest/vtv_status.mp4","-c:v","h264","-acodec","mp3","/storage/emulated/0/ffmpegTest/mout.mp4"};

make this array list like this

VineshChauhan24 avatar Sep 08 '21 05:09 VineshChauhan24