首先 强烈推荐 我师父的ffmeg的两篇课程 对于有一点编程知识的android开发者 对视频这块会有很大的进步
FFMPEG打造万能视频播放器 基础篇
FFMPEG打造万能视频播放器 进阶篇
基础篇还有ffmpeg生成android库 讲到一些怎么调用C++的ffmpeg的方法 如果想发展这方面 一定要去看课程!
首先是我师父通过基础篇和进阶篇的内容 提供的一个库!这个库只是测试所有 并没有开发完整版的功能,当然了 做好的方法开始根据视频 自己写个mode类 这样可以达到你需要的私人订制功能,并且只生成你想要的库类型 不占用apk的没用内存(跟着视频可以写一个自己需要的库)
引用方法
implementation 'ywl.ywl5320:libmusic:1.2.6'
ndk {
abiFilter("armeabi-v7a")
abiFilter("x86")
}
我想用刚导入也报错 然后把
com.android.support:appcompat-v7的版本改成27.1.1 才好的 因为这个是课程上面用到的版本 (自己定制可以随意修改)
这个dome只能看到一些视频播放和C的源文件 和怎么调用的
这里只提供视频播放的开源库 但合成的暂未开放
合成源码 可通过视频课程学习 自定义修改
或者进入QQ群806397913
下面介绍 根据视频后生产的自定义view怎么生成mp4文件
//初始化ffmpeg自定义view
private void initffmpeg() {
imgvideoview.setintImg(R.mipmap.aboutus);//防止崩溃 默认图片
wlMusic = WlMusic.getInstance();//注册music
wlMusic.setCallBackPcmData(true);//回调
wlMusic.setConvertSampleRate(SampleRateEnum.RATE_44100);//生成视频格式
wlMusic.setOnPreparedListener(new OnPreparedListener() {
@Override
public void onPrepared() {
wlMusic.playCutAudio(0, MUIZ_SIZE);//通过mp3的时间 生成 这里写的是从0秒到视频的长度 我这里暂时只接受int参数
}
});
wlMusic.setOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete() {
handler.sendEmptyMessage(1);//初始化生成样式 这里会占用主线程
}
});
wlMusic.setOnErrorListener(new OnErrorListener() {
@Override
public void onError(int code, String msg) {
Log.d("ywl5320", msg);//异常报错
}
});
wlMusic.setOnShowPcmDataListener(new OnShowPcmDataListener() {
@Override
public void onPcmInfo(int samplerate, int bit, int channels) {
wlMediaEncodec = new WlMediaEncodec(ImageVideoActivity.this, imgvideoview.getFbotextureid());
//本地路径 getNowTime 方法获取时间戳 为了生成mp4文件路径不一样 可以生成多个 不会被覆盖
outpath = "/storage/emulated/0/Music/" + getNowTime() + "wes.mp4";
/**
* 视频的context 输出 剪切 剪切
*/
wlMediaEncodec.initEncodec(imgvideoview.getEglContext(),
outpath,
720, 500, samplerate, channels);
wlMediaEncodec.startRecord();
}
@Override
public void onPcmData(byte[] pcmdata, int size, long clock) {
if (wlMediaEncodec != null) {//这里做了个进度条
wlMediaEncodec.putPCMData(pcmdata, size);
int s = zong / 100;//总是除100
s = s * 1000;//毫秒转秒 打印60000
float parcent = (float) clock / (float) s;
int g = (int) parcent;
if (g != 100 || g < 100) {
pd.setProgress(g);
KLog.e("tag", g + "");
} else {
// pd.dismiss();
}
Log.d("ywl5320", "clock:" + clock + "size" + size + "pcmdata");
}
}
});
}
开始合成
//这里我做的是 从本地获取图片 然后合成视频 我这个项目有个小bug 就是合成的时候 必须让他显示出来
正好我项目也有这个需求 所以没改
private void setTimer() {
new Thread(new Runnable() {
@Override
public void run() {
try {
Thread.sleep(1000);//休眠一秒
handler2.postDelayed(runnable, jiange);//用gadle更换图片 我是根据视频时长 //除图片数量做的切换视频图片 只需要按照时间定时给自定义view换图片就可以达到这个效果
wlMusic.setSource(musicUrl);//,musicurl是音频文件路径
wlMusic.prePared();//开始合成
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
更换图片
Handler handler2 = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
item = item + 1;//这里是自己写的逻辑 更换图片列表的position
if (bitmaplists.size() > item) {
imgvideoview.setCurrentImg(bitmaplists.get(item).getBitmap());//更换图片
handler2.postDelayed(runnable, jiange);//再次启动定时换图片
} else {
item = 0;
// countDownTimer.onFinish();
}
}
};
合成完成
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
if (wlMediaEncodec != null) {
wlMusic.stop();
wlMediaEncodec.stopRecord();
wlMediaEncodec = null;
Toast.makeText(ImageVideoActivity.this, "合成完成", Toast.LENGTH_SHORT).show();
pd.dismiss();
}
break;
}
}
};
等待进度条
private void showPD() {
//进度条对话框
pd = new ProgressDialog(this);
pd.setCancelable(false);
pd.setMax(100);
// pd.setIndeterminate(true);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("正在合成");
pd.show();
}
做完就可以生成吧图片和音频生成mp4文件 还可以添加水印 背景什么的
看到这个博客 就是项目经理有这种恶心的需求 建议 需要的朋友加QQ群 806397913 一起研究ffmpeg 有大神坐镇 !