您好,登錄后才能下訂單哦!
上一篇文章談到音頻剪切、混音、拼接與轉碼,也詳細介紹cMake配置與涉及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。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。