ffpeg 简单视频压缩 普通需求类型

   在这个直播 ,点播时代 这个市场对Andriod 音视频开发 需求越来越多   这个门槛也是有点高的,如果你能熟练的掌握 ffpeg   就业问题不大了。



   ffpeg 太强大  我在项目中也有用到,只是摸到边而已,自己写一下记录一下,自己也挺想往这个方向走,技多不压身嘛。



   使用ffpeg 压缩视频    文末放一个demo 好了   包括视频录制 + 压缩 + 上传


   我使用的是  Andriod原生  MediaRecorder +SurfaceView + Camera  进行视频录制   ffpeg  cmd 命令 执行压缩。


   先说下压缩命令好了 :

final String path1 = new File(path).getParent() + "/"
						+ getDate() + "vido.mp4";
				String cmd = "-y -i "
						+ path
						+ " -strict -2 -vcodec libx264 -preset ultrafast -crf 24 -acodec aac -ar 44100 -ac 2 -b:a 96k -s 480x480 -aspect 16:16 "
						+ path1;


参数说明 :  path  录制源视频地址     path1  压缩后视频保存地址     

 -y(覆盖输出文件,即如果1.***文件已经存在的话,不经提示就覆盖掉了) 
-i "1.avi"(输入文件是和ffmpeg在同一目录下的1.avi文件,可以自己加路径,改名字) 

-strict strictness 跟标准的严格性

-vcodec xvid(使用XVID编码压缩视频,不能改的)  本demo 是 libx264    这个是设置压缩视频的格式

-preset:指定编码的配置。x264编码算法有很多可供配置的参数,不同的参数值会导致编码的速度大相径庭,甚至可能影响质量。为了免去用户了解算法,然后手工配置参数的麻烦。x264提供了一些预设值,而这些预设值可以通过preset指定。这些预设值有包括:ultrafast,superfast,veryfast,faster,fast,medium,slow,slower,veryslow和placebo。ultrafast编码速度最快,但压缩率低,生成的文件更大,placebo则正好相反。x264所取的默认值为medium。需要说明的是,preset主要是影响编码的速度,并不会很大的影响编码出来的结果的质量。压缩高清电影时,我一般用slow或者slower,当你的机器性能很好时也可以使用veryslow,不过一般并不会带来很大的好处。

-crf:这是最重要的一个选项,用于指定输出视频的质量,取值范围是0-51,默认值为23,数字越小输出视频的质量越高。这个选项会直接影响到输出视频的码率。一般来说,压制480p我会用20左右,压制720p我会用16-18,1080p我没尝试过。个人觉得,一般情况下没有必要低于16。最好的办法是大家可以多尝试几个值,每个都压几分钟,看看最后的输出质量和文件大小,自己再按需选择。

- acodec aac(音频编码用AAC) 

-ac 2(声道数1或2) 


-ar 24000(声音的采样频率,好像PSP只能支持24000Hz)

-b 1500(视频数据流量,用 -b xxxx的指令则使用固定码率,数字随便改,1500以上没效果;还可以用动态码率如:-qscale 4和-qscale 6,4的质量比6高) 

-s 368x208(输出的分辨率为368x208,注意片源一定要是16:9的不然会变形) 


-aspect aspect 设置横纵比 4:3 16:9 或 1.3333 1.7777



 这么在代码中使用

artts 文件   armeabi-v7a-neon   x86  下放 ffpeg 资源




libs  jar       sardar.jar



写 3个封装类 方便调用

package com.mly.sardar;

import android.app.Activity;

import com.github.hiteshsondhi88.libffmpeg.ExecuteBinaryResponseHandler;
import com.github.hiteshsondhi88.libffmpeg.FFmpeg;
import com.github.hiteshsondhi88.libffmpeg.LoadBinaryResponseHandler;
import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegCommandAlreadyRunningException;
import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegNotSupportedException;

/**
 *
 */
public class Compressor {

    public Activity a;
    public FFmpeg ffmpeg;
    public Compressor(Activity activity){
        a = activity;
        ffmpeg = FFmpeg.getInstance(a);
    }

    public void loadBinary(final InitListener mListener) {
        try {
            ffmpeg.loadBinary(new LoadBinaryResponseHandler() {
                @Override
                public void onStart() {}

                @Override
                public void onFailure() {
                    mListener.onLoadFail("incompatible with this device");
                }

                @Override
                public void onSuccess() {
                    mListener.onLoadSuccess();
                }
                @Override
                public void onFinish() {

                }
            });
        } catch (FFmpegNotSupportedException e) {
            e.printStackTrace();
        }
    }

    public void execCommand(String cmd,final CompressListener mListener){
        try {
            ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {

                @Override
                public void onStart() {}

                @Override
                public void onProgress(String message) { mListener.onExecProgress(message);}

                @Override
                public void onFailure(String message) { mListener.onExecFail(message); }

                @Override
                public void onSuccess(String message) {
                    mListener.onExecSuccess(message);
                }

                @Override
                public void onFinish() {}
            });
        } catch (FFmpegCommandAlreadyRunningException e) {
            e.printStackTrace();
        }
    }




}


package com.mly.sardar;


/**
 * 
 */
public interface InitListener {
    public void onLoadSuccess();
    public void onLoadFail(String reason);
}

package com.mly.sardar;

/**
 * 
 */
public interface CompressListener {
    public void onExecSuccess(String message);
    public void onExecFail(String reason);
    public void onExecProgress(String message);
}



在oncreate 中初始化

 Compressor com = new Compressor(this);


com.loadBinary(new InitListener() {
			@Override
			public void onLoadSuccess() {
				final String path1 = new File(path).getParent() + "/"
						+ getDate() + "vido.mp4";
				String cmd = "-y -i "
						+ path
						+ " -strict -2 -vcodec libx264 -preset ultrafast -crf 24 -acodec aac -ar 44100 -ac 2 -b:a 96k -s 480x480 -aspect 16:16 "
						+ path1;
				com.execCommand(cmd, new CompressListener() {
					@Override
					public void onExecSuccess(String message) {
						Log.i("success", message);
						record_video_activity_up_text
								.setVisibility(View.VISIBLE);
						new File(path).delete();
						path = path1;
						record_video_activity_up.setVisibility(View.VISIBLE);
						StarLoadDirlog.dialog.dismiss();
						
					}

					@Override
					public void onExecFail(String reason) {
						Log.i("fail", reason);
					}

					@Override
					public void onExecProgress(String message) {
						Log.i("progress", message);
					}
				});


 Demo   整理中····




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值