android采用FFmpeg实现音视频合成与分离

发布时间:2019-08-08 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了android采用FFmpeg实现音视频合成与分离脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

上一篇文章谈到音频剪切、混音、拼接与转码,也详细介绍@R_872_1512@配置与涉及FFmPEg文件的导入: android端采用FFmpeg进行音频混合与拼接剪切 。现在接着探讨音视频的合成与分离。

1、音频提取

从多媒体文件中提取音频,关键命令为“-acodec copy -vn”,其中“-acodec copy”是采用音频编码器拷贝音频流,“-vn”是去掉video视频流:

  /**    * 使用ffmpeg命令行进行抽取音频    * @param srCFile 原文件    * @param targetFile 目标文件    * @return 抽取后的音频文件  */   public static String[] extractAudio(String srcFile, String targetFile){     //-vn:video not     String mixAudioCmd = "ffmpeg -i %s -acodec copy -vn %s";     mixAudioCmd = String.format(mixAudioCmd, srcFile, targetFile);     return mixAudioCmd.splIT(" ");//以空格分割为字符串数组   }

2、视频提取

从多媒体文件中提取视频,关键命令为“-vcodec copy -an”,其中“-vcodec copy”是采用视频编码器拷贝视频流,“-an”是去掉audio音频流:

 /**    * 使用ffmpeg命令行进行抽取视频    * @param srcFile 原文件    * @param targetFile 目标文件    * @return 抽取后的视频文件 */   public static String[] extractVideo(String srcFile, String targetFile){     //-an audio not     String mixAudioCmd = "ffmpeg -i %s -vcodec copy -an %s";     mixAudioCmd = String.format(mixAudioCmd, srcFile, targetFile);     return mixAudioCmd.split(" ");//以空格分割为字符串数组   }

3、音视频合成

把音频和视频文件合成多媒体文件,关键命令是“-i %s -i %s -t”,分别代表输入音频、视频和文件时长。需要注意的是,如果原视频文件包含有音频,先把单独视频流抽取出来,然后再使用独立音频和视频进行合成:

   /**    * 使用ffmpeg命令行进行音视频合成    * @param videoFile 视频文件    * @param audioFile 音频文件    * @param duration 视频时长    * @param muxFile 目标文件    * @return 合成后的文件    */   @SupPressLint("DefaultLocale")   public static String[] mediaMux(String videoFile, String audioFile, int duration, String muxFile){     //-t:时长 如果忽略音视频时长,则把"-t %d"去掉     String mixAudioCmd = "ffmpeg -i %s -i %s -t %d %s";     mixAudioCmd = String.format(mixAudioCmd, videoFile, audioFile, duration, muxFile);     return mixAudioCmd.split(" ");//以空格分割为字符串数组   } 

单独的视频提取出来后,进行音视频合成:

 public void handleMessage(Message msg) {       super.handleMessage(msg);       if(msg.what == 100){         String audioFile = PATH + File.separator + "tiger.mP3";//tiger.mp3         String muxFile = PATH + File.separator + "media-mux.mp4";           try {           //使用Mediaplayer获取视频时长           Mediaplayer mediaPlayer = new MediaPlayer();           mediaPlayer.setDataSource(videoFile);           mediaPlayer.PRepare();           //单位为ms           int videoDuration = mediaPlayer.getDuration()/1000;           LOG.i(TAG, "videoDuration=" + videoDuration);           mediaPlayer.release();           //使用MediaMetadataRetriever获取音频时长           MediaMetadataRetriever mediaRetriever = new MediaMetadataRetriever();           mediaRetriever.setDataSource(audioFile);           //单位为ms           String duration = mediaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);           int audioDuration = (int)(Long.parseLong(duration)/1000);           Log.i(TAG, "audioDuration=" + audioDuration);           mediaRetriever.release();           //如果视频时长比音频长,采用音频时长,否则用视频时长           int mDuration = Math.min(audioDuration, videoDuration);           //使用纯视频与音频进行合成           String[] commandLine = FFmpegUtil.mediaMux(temp, audioFile, mDuration, muxFile);           executeFFmpegCmd(commandLine);           isMux = false;         } catch (Exception e) {           e.printStackTrace();         }       }     }

拼接好FFmpeg命令后,调用native方法去执行:

 /**    * 调用ffmpeg处理音视频    * @param handleType handleType    */   private void doHandleMedia(int handleType){     String[] commandLine = null;     switch (handleType){       case 0://音视频合成         try {           //视频文件有音频,先把纯视频文件抽取出来           commandLine = FFmpegUtil.extractVideo(videoFile, temp);           isMux = true;         } catch (Exception e) {           e.printStackTrace();         }         break;       case 1://提取音频         String extractAudio = PATH + File.separator + "extractAudio.aac";         commandLine = FFmpegUtil.extractAudio(srcFile, extractAudio);         break;       case 2://提取视频         String extractVideo = PATH + File.separator + "extractVideo.mp4";         commandLine = FFmpegUtil.extractVideo(srcFile, extractVideo);         break;       default:         break;     }     executeFFmpegCmd(commandLine);   } FFmpeg执行的回调: /**    * 执行ffmpeg命令行    * @param commandLine commandLine    */   private void executeFFmpegCmd(final String[] commandLine){     if(commandLine == null){       return;     }     FFmpegCmd.execute(commandLine, new FFmpegCmd.OnHandleListener() {       @override       public void onBegin() {         Log.i(TAG, "handle media onBegin...");       }         @Override       public void onEnd(int result) {         Log.i(TAG, "handle media onEnd...");         if(isMux){           mHandler.oBTainMessage(100).sendToTarget();         }else {           runOnUiThread(new Runnable() {             @Override             public void run() {               Toast.makeText(MediaHandleActivity.this, "handle media finish...", Toast.LENGTH_SHORT).show();             }           });         }       }     });   }

好了,使用FFmpeg进行音视频合成与分离介绍完毕。如果各位有什么问题或者建议,欢迎交流。

码:链接地址。如果对您有帮助,麻烦fork和star。

android教程
脚本网站
android studio

脚本宝典总结

以上是脚本宝典为你收集整理的android采用FFmpeg实现音视频合成与分离全部内容,希望文章能够帮你解决android采用FFmpeg实现音视频合成与分离所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。