android使用ffmpeg生成有声图片,多张图片添加音频文件合成mp4文件

首先 强烈推荐 我师父的ffmeg的两篇课程 对于有一点编程知识的android开发者 对视频这块会有很大的进步 

FFMPEG打造万能视频播放器  基础篇

FFMPEG打造万能视频播放器 进阶篇

FFMPEG直播推流拉流

 

基础篇还有ffmpeg生成android库 讲到一些怎么调用C++的ffmpeg的方法 如果想发展这方面 一定要去看课程!

首先是我师父通过基础篇和进阶篇的内容 提供的一个库!这个库只是测试所有 并没有开发完整版的功能,当然了 做好的方法开始根据视频 自己写个mode类  这样可以达到你需要的私人订制功能,并且只生成你想要的库类型 不占用apk的没用内存(跟着视频可以写一个自己需要的库)

ffmpeg Dome地址

引用方法 

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 有大神坐镇 !

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值