add dubbing:add another audio to video

add dubbing:add another audio to video
pull/166/head
xufulong 4 years ago
parent ebb94de1cd
commit 3dd8fc9920
  1. 92
      app/src/main/java/com/frank/ffmpeg/activity/MediaHandleActivity.java
  2. 13
      app/src/main/java/com/frank/ffmpeg/util/FFmpegUtil.java
  3. 7
      app/src/main/res/layout/activity_media_handle.xml
  4. 1
      app/src/main/res/values-en/strings.xml
  5. 1
      app/src/main/res/values/strings.xml

@ -1,8 +1,6 @@
package com.frank.ffmpeg.activity; package com.frank.ffmpeg.activity;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.Handler; import android.os.Handler;
@ -12,16 +10,17 @@ import android.view.View;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import com.frank.ffmpeg.FFmpegCmd;
import com.frank.ffmpeg.R; import com.frank.ffmpeg.R;
import com.frank.ffmpeg.handler.FFmpegHandler; import com.frank.ffmpeg.handler.FFmpegHandler;
import com.frank.ffmpeg.util.FFmpegUtil; import com.frank.ffmpeg.util.FFmpegUtil;
import com.frank.ffmpeg.util.FileUtil; import com.frank.ffmpeg.util.FileUtil;
import com.frank.ffmpeg.util.ThreadPoolUtil;
import java.io.File; import java.io.File;
import java.util.Locale; import java.util.Locale;
import static com.frank.ffmpeg.handler.FFmpegHandler.MSG_BEGIN; import static com.frank.ffmpeg.handler.FFmpegHandler.MSG_BEGIN;
import static com.frank.ffmpeg.handler.FFmpegHandler.MSG_CONTINUE;
import static com.frank.ffmpeg.handler.FFmpegHandler.MSG_FINISH; import static com.frank.ffmpeg.handler.FFmpegHandler.MSG_FINISH;
import static com.frank.ffmpeg.handler.FFmpegHandler.MSG_PROGRESS; import static com.frank.ffmpeg.handler.FFmpegHandler.MSG_PROGRESS;
@ -33,8 +32,7 @@ public class MediaHandleActivity extends BaseActivity {
private final static String TAG = MediaHandleActivity.class.getSimpleName(); private final static String TAG = MediaHandleActivity.class.getSimpleName();
private static final String PATH = Environment.getExternalStorageDirectory().getPath(); private static final String PATH = Environment.getExternalStorageDirectory().getPath();
private String videoFile; private String audioFile = PATH + File.separator + "tiger.mp3";
private String temp = PATH + File.separator + "temp.mp4";
private LinearLayout layoutProgress; private LinearLayout layoutProgress;
private TextView txtProgress; private TextView txtProgress;
@ -48,35 +46,6 @@ public class MediaHandleActivity extends BaseActivity {
public void handleMessage(Message msg) { public void handleMessage(Message msg) {
super.handleMessage(msg); super.handleMessage(msg);
switch (msg.what) { switch (msg.what) {
case MSG_CONTINUE:
String audioFile = PATH + File.separator + "tiger.mp3";
String muxFile = PATH + File.separator + "media-mux.mp4";
try {
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(videoFile);
mediaPlayer.prepare();
//ms
int videoDuration = mediaPlayer.getDuration() / 1000;
Log.i(TAG, "videoDuration=" + videoDuration);
mediaPlayer.release();
MediaMetadataRetriever mediaRetriever = new MediaMetadataRetriever();
mediaRetriever.setDataSource(audioFile);
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);
//mux video and audio
String[] commandLine = FFmpegUtil.mediaMux(temp, audioFile, mDuration, muxFile);
if (ffmpegHandler != null) {
ffmpegHandler.isContinue(false);
ffmpegHandler.executeFFmpegCmd(commandLine);
}
} catch (Exception e) {
e.printStackTrace();
}
break;
case MSG_BEGIN: case MSG_BEGIN:
layoutProgress.setVisibility(View.VISIBLE); layoutProgress.setVisibility(View.VISIBLE);
layoutMediaHandle.setVisibility(View.GONE); layoutMediaHandle.setVisibility(View.GONE);
@ -121,7 +90,8 @@ public class MediaHandleActivity extends BaseActivity {
initViewsWithClick( initViewsWithClick(
R.id.btn_mux, R.id.btn_mux,
R.id.btn_extract_audio, R.id.btn_extract_audio,
R.id.btn_extract_video R.id.btn_extract_video,
R.id.btn_dubbing
); );
} }
@ -152,17 +122,9 @@ public class MediaHandleActivity extends BaseActivity {
} }
switch (viewId) { switch (viewId) {
case R.id.btn_mux://mux case R.id.btn_mux://mux:pure video and pure audio
try { ThreadPoolUtil.executeSingleThreadPool(() -> mediaMux(srcFile));
videoFile = srcFile; return;
commandLine = FFmpegUtil.extractVideo(srcFile, temp);
if (ffmpegHandler != null) {
ffmpegHandler.isContinue(true);
}
} catch (Exception e) {
e.printStackTrace();
}
break;
case R.id.btn_extract_audio://extract audio case R.id.btn_extract_audio://extract audio
String extractAudio = PATH + File.separator + "extractAudio.aac"; String extractAudio = PATH + File.separator + "extractAudio.aac";
commandLine = FFmpegUtil.extractAudio(srcFile, extractAudio); commandLine = FFmpegUtil.extractAudio(srcFile, extractAudio);
@ -171,6 +133,9 @@ public class MediaHandleActivity extends BaseActivity {
String extractVideo = PATH + File.separator + "extractVideo.mp4"; String extractVideo = PATH + File.separator + "extractVideo.mp4";
commandLine = FFmpegUtil.extractVideo(srcFile, extractVideo); commandLine = FFmpegUtil.extractVideo(srcFile, extractVideo);
break; break;
case R.id.btn_dubbing://dubbing
ThreadPoolUtil.executeSingleThreadPool(() -> mediaDubbing(srcFile));
return;
default: default:
break; break;
} }
@ -179,6 +144,41 @@ public class MediaHandleActivity extends BaseActivity {
} }
} }
private void muxVideoAndAudio(String videoPath, String outputPath) {
String[] commandLine = FFmpegUtil.mediaMux(videoPath, audioFile, true, outputPath);
int result = FFmpegCmd.executeSync(commandLine);
if (result != 0) {
commandLine = FFmpegUtil.mediaMux(videoPath, audioFile, false, outputPath);
result = FFmpegCmd.executeSync(commandLine);
Log.e(TAG, "mux audio and video result=" + result);
}
}
private void mediaMux(String srcFile) {
mHandler.sendEmptyMessage(MSG_BEGIN);
String suffix = FileUtil.getFileSuffix(srcFile);
String muxPath = PATH + File.separator + "mux" + suffix;
Log.e(TAG, "muxPath=" + muxPath);
muxVideoAndAudio(srcFile, muxPath);
mHandler.sendEmptyMessage(MSG_FINISH);
}
private void mediaDubbing(String srcFile) {
mHandler.sendEmptyMessage(MSG_BEGIN);
String dubbingSuffix = FileUtil.getFileSuffix(srcFile);
String dubbingPath = PATH + File.separator + "dubbing" + dubbingSuffix;
String temp = PATH + File.separator + "temp" + dubbingSuffix;
String[] commandLine1 = FFmpegUtil.extractVideo(srcFile, temp);
int dubbingResult = FFmpegCmd.executeSync(commandLine1);
if (dubbingResult != 0) {
Log.e(TAG, "extract video fail, result=" + dubbingResult);
return;
}
muxVideoAndAudio(temp, dubbingPath);
FileUtil.deleteFile(temp);
mHandler.sendEmptyMessage(MSG_FINISH);
}
@Override @Override
protected void onDestroy() { protected void onDestroy() {
super.onDestroy(); super.onDestroy();

@ -90,13 +90,18 @@ public class FFmpegUtil {
* *
* @param videoFile the file of pure video * @param videoFile the file of pure video
* @param audioFile the file of pure audio * @param audioFile the file of pure audio
* @param duration the duration of video * @param copy copy codec
* @param muxFile output file * @param muxFile output file
* @return mux success or not * @return mux success or not
*/ */
public static String[] mediaMux(String videoFile, String audioFile, int duration, String muxFile) { public static String[] mediaMux(String videoFile, String audioFile, boolean copy, String muxFile) {
String mixAudioCmd = "ffmpeg -i %s -i %s -t %d %s"; String mixAudioCmd;
mixAudioCmd = String.format(Locale.getDefault(), mixAudioCmd, videoFile, audioFile, duration, muxFile); if (copy) {
mixAudioCmd = "ffmpeg -i %s -i %s -codec copy -y %s";
} else {
mixAudioCmd = "ffmpeg -i %s -i %s -y %s";
}
mixAudioCmd = String.format(Locale.getDefault(), mixAudioCmd, videoFile, audioFile, muxFile);
return mixAudioCmd.split(" "); return mixAudioCmd.split(" ");
} }

@ -31,6 +31,13 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/media_extract_video" android:text="@string/media_extract_video"
android:layout_marginTop="10dp" /> android:layout_marginTop="10dp" />
<Button
android:id="@+id/btn_dubbing"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/media_dubbing"
android:layout_marginTop="10dp" />
</LinearLayout> </LinearLayout>
<include <include

@ -27,6 +27,7 @@
<string name="media_extract_video">Video extract</string> <string name="media_extract_video">Video extract</string>
<string name="media_play">Media play</string> <string name="media_play">Media play</string>
<string name="media_probe">Media probe</string> <string name="media_probe">Media probe</string>
<string name="media_dubbing">Media dubbing</string>
<string name="video_cut">Video cut</string> <string name="video_cut">Video cut</string>
<string name="video_concat">Video concat</string> <string name="video_concat">Video concat</string>

@ -27,6 +27,7 @@
<string name="media_extract_video">提取视频</string> <string name="media_extract_video">提取视频</string>
<string name="media_play">音视频播放</string> <string name="media_play">音视频播放</string>
<string name="media_probe">解析多媒体格式</string> <string name="media_probe">解析多媒体格式</string>
<string name="media_dubbing">配音</string>
<string name="video_cut">视频剪切</string> <string name="video_cut">视频剪切</string>
<string name="video_concat">视频拼接</string> <string name="video_concat">视频拼接</string>

Loading…
Cancel
Save