|
|
@ -4,8 +4,10 @@ import android.annotation.SuppressLint; |
|
|
|
import android.os.Handler; |
|
|
|
import android.os.Handler; |
|
|
|
import android.os.Message; |
|
|
|
import android.os.Message; |
|
|
|
import android.os.Bundle; |
|
|
|
import android.os.Bundle; |
|
|
|
|
|
|
|
|
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager; |
|
|
|
import androidx.recyclerview.widget.LinearLayoutManager; |
|
|
|
import androidx.recyclerview.widget.RecyclerView; |
|
|
|
import androidx.recyclerview.widget.RecyclerView; |
|
|
|
|
|
|
|
|
|
|
|
import android.view.SurfaceHolder; |
|
|
|
import android.view.SurfaceHolder; |
|
|
|
import android.view.SurfaceView; |
|
|
|
import android.view.SurfaceView; |
|
|
|
import android.view.View; |
|
|
|
import android.view.View; |
|
|
@ -13,6 +15,7 @@ import android.widget.Button; |
|
|
|
import android.widget.CompoundButton; |
|
|
|
import android.widget.CompoundButton; |
|
|
|
import android.widget.ToggleButton; |
|
|
|
import android.widget.ToggleButton; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import com.frank.ffmpeg.FFmpegApplication; |
|
|
|
import com.frank.ffmpeg.R; |
|
|
|
import com.frank.ffmpeg.R; |
|
|
|
import com.frank.ffmpeg.VideoPlayer; |
|
|
|
import com.frank.ffmpeg.VideoPlayer; |
|
|
|
import com.frank.ffmpeg.adapter.HorizontalAdapter; |
|
|
|
import com.frank.ffmpeg.adapter.HorizontalAdapter; |
|
|
@ -24,23 +27,21 @@ import java.util.Arrays; |
|
|
|
import java.util.List; |
|
|
|
import java.util.List; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* 使用ffmpeg进行滤镜 |
|
|
|
* Using ffmpeg to filter |
|
|
|
* Created by frank on 2018/6/5. |
|
|
|
* Created by frank on 2018/6/5. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
public class FilterActivity extends BaseActivity implements SurfaceHolder.Callback{ |
|
|
|
public class FilterActivity extends BaseActivity implements SurfaceHolder.Callback { |
|
|
|
|
|
|
|
|
|
|
|
//本地视频路径
|
|
|
|
|
|
|
|
private String videoPath = ""; |
|
|
|
private String videoPath = ""; |
|
|
|
|
|
|
|
|
|
|
|
private VideoPlayer videoPlayer; |
|
|
|
private VideoPlayer videoPlayer; |
|
|
|
private SurfaceView surfaceView; |
|
|
|
private SurfaceView surfaceView; |
|
|
|
private SurfaceHolder surfaceHolder; |
|
|
|
private SurfaceHolder surfaceHolder; |
|
|
|
//surface是否已经创建
|
|
|
|
|
|
|
|
private boolean surfaceCreated; |
|
|
|
private boolean surfaceCreated; |
|
|
|
//是否正在播放
|
|
|
|
//is playing or not
|
|
|
|
private boolean isPlaying; |
|
|
|
private boolean isPlaying; |
|
|
|
//滤镜数组
|
|
|
|
//the array of filter
|
|
|
|
private String[] filters = new String[]{ |
|
|
|
private String[] filters = new String[]{ |
|
|
|
"lutyuv='u=128:v=128'", |
|
|
|
"lutyuv='u=128:v=128'", |
|
|
|
"hue='h=60:s=-3'", |
|
|
|
"hue='h=60:s=-3'", |
|
|
@ -52,20 +53,20 @@ public class FilterActivity extends BaseActivity implements SurfaceHolder.Callba |
|
|
|
"vflip", |
|
|
|
"vflip", |
|
|
|
"unsharp" |
|
|
|
"unsharp" |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
//vflip is up and down, hflip is left and right
|
|
|
|
private String[] txtArray = new String[]{ |
|
|
|
private String[] txtArray = new String[]{ |
|
|
|
"素描", |
|
|
|
FFmpegApplication.getInstance().getString(R.string.filter_sketch), |
|
|
|
"鲜明",//hue
|
|
|
|
FFmpegApplication.getInstance().getString(R.string.filter_distinct), |
|
|
|
"暖蓝", |
|
|
|
FFmpegApplication.getInstance().getString(R.string.filter_warming), |
|
|
|
"边缘", |
|
|
|
FFmpegApplication.getInstance().getString(R.string.filter_edge), |
|
|
|
"九宫格", |
|
|
|
FFmpegApplication.getInstance().getString(R.string.filter_division), |
|
|
|
"均衡", |
|
|
|
FFmpegApplication.getInstance().getString(R.string.filter_equalize), |
|
|
|
"矩形", |
|
|
|
FFmpegApplication.getInstance().getString(R.string.filter_rectangle), |
|
|
|
"翻转",//vflip上下翻转,hflip是左右翻转
|
|
|
|
FFmpegApplication.getInstance().getString(R.string.filter_flip), |
|
|
|
"锐化" |
|
|
|
FFmpegApplication.getInstance().getString(R.string.filter_sharpening) |
|
|
|
}; |
|
|
|
}; |
|
|
|
private HorizontalAdapter horizontalAdapter; |
|
|
|
private HorizontalAdapter horizontalAdapter; |
|
|
|
private RecyclerView recyclerView; |
|
|
|
private RecyclerView recyclerView; |
|
|
|
//是否播放音频
|
|
|
|
|
|
|
|
private boolean playAudio = true; |
|
|
|
private boolean playAudio = true; |
|
|
|
private ToggleButton btnSound; |
|
|
|
private ToggleButton btnSound; |
|
|
|
private Button btnSelect; |
|
|
|
private Button btnSelect; |
|
|
@ -73,11 +74,11 @@ public class FilterActivity extends BaseActivity implements SurfaceHolder.Callba |
|
|
|
private final static int MSG_HIDE = 222; |
|
|
|
private final static int MSG_HIDE = 222; |
|
|
|
private final static int DELAY_TIME = 5000; |
|
|
|
private final static int DELAY_TIME = 5000; |
|
|
|
@SuppressLint("HandlerLeak") |
|
|
|
@SuppressLint("HandlerLeak") |
|
|
|
private Handler mHandler = new Handler(){ |
|
|
|
private Handler mHandler = new Handler() { |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void handleMessage(Message msg) { |
|
|
|
public void handleMessage(Message msg) { |
|
|
|
super.handleMessage(msg); |
|
|
|
super.handleMessage(msg); |
|
|
|
if (msg.what == MSG_HIDE){//无操作5s后隐藏滤镜操作栏
|
|
|
|
if (msg.what == MSG_HIDE) { //after idle 5s, hide the controller view
|
|
|
|
recyclerView.setVisibility(View.GONE); |
|
|
|
recyclerView.setVisibility(View.GONE); |
|
|
|
btnSound.setVisibility(View.GONE); |
|
|
|
btnSound.setVisibility(View.GONE); |
|
|
|
btnSelect.setVisibility(View.GONE); |
|
|
|
btnSelect.setVisibility(View.GONE); |
|
|
@ -85,12 +86,13 @@ public class FilterActivity extends BaseActivity implements SurfaceHolder.Callba |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
private class HideRunnable implements Runnable{ |
|
|
|
private class HideRunnable implements Runnable { |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void run() { |
|
|
|
public void run() { |
|
|
|
mHandler.obtainMessage(MSG_HIDE).sendToTarget(); |
|
|
|
mHandler.obtainMessage(MSG_HIDE).sendToTarget(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private HideRunnable hideRunnable; |
|
|
|
private HideRunnable hideRunnable; |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
@ -110,7 +112,7 @@ public class FilterActivity extends BaseActivity implements SurfaceHolder.Callba |
|
|
|
mHandler.postDelayed(hideRunnable, DELAY_TIME); |
|
|
|
mHandler.postDelayed(hideRunnable, DELAY_TIME); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void initView(){ |
|
|
|
private void initView() { |
|
|
|
surfaceView = getView(R.id.surface_filter); |
|
|
|
surfaceView = getView(R.id.surface_filter); |
|
|
|
surfaceHolder = surfaceView.getHolder(); |
|
|
|
surfaceHolder = surfaceView.getHolder(); |
|
|
|
surfaceHolder.addCallback(this); |
|
|
|
surfaceHolder.addCallback(this); |
|
|
@ -129,14 +131,13 @@ public class FilterActivity extends BaseActivity implements SurfaceHolder.Callba |
|
|
|
initViewsWithClick(R.id.btn_select_file); |
|
|
|
initViewsWithClick(R.id.btn_select_file); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//注册监听器
|
|
|
|
private void registerLister() { |
|
|
|
private void registerLister(){ |
|
|
|
|
|
|
|
horizontalAdapter.setOnItemClickListener(new OnItemClickListener() { |
|
|
|
horizontalAdapter.setOnItemClickListener(new OnItemClickListener() { |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void onItemClick(int position) { |
|
|
|
public void onItemClick(int position) { |
|
|
|
if(!surfaceCreated) |
|
|
|
if (!surfaceCreated) |
|
|
|
return; |
|
|
|
return; |
|
|
|
if (!FileUtil.checkFileExist(videoPath)){ |
|
|
|
if (!FileUtil.checkFileExist(videoPath)) { |
|
|
|
showSelectFile(); |
|
|
|
showSelectFile(); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@ -149,8 +150,8 @@ public class FilterActivity extends BaseActivity implements SurfaceHolder.Callba |
|
|
|
public void onClick(View v) { |
|
|
|
public void onClick(View v) { |
|
|
|
btnSelect.setVisibility(View.VISIBLE); |
|
|
|
btnSelect.setVisibility(View.VISIBLE); |
|
|
|
btnSound.setVisibility(View.VISIBLE); |
|
|
|
btnSound.setVisibility(View.VISIBLE); |
|
|
|
recyclerView.setVisibility(View.VISIBLE);//按下SurfaceView,弹出滤镜操作栏
|
|
|
|
recyclerView.setVisibility(View.VISIBLE); |
|
|
|
mHandler.postDelayed(hideRunnable, DELAY_TIME);//5s后发消息通知隐藏滤镜操作栏
|
|
|
|
mHandler.postDelayed(hideRunnable, DELAY_TIME); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
@ -162,12 +163,15 @@ public class FilterActivity extends BaseActivity implements SurfaceHolder.Callba |
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* switch filter |
|
|
|
|
|
|
|
* @param position position in the array of filters |
|
|
|
|
|
|
|
*/ |
|
|
|
private void doFilterPlay(final int position) { |
|
|
|
private void doFilterPlay(final int position) { |
|
|
|
new Thread(new Runnable() { |
|
|
|
new Thread(new Runnable() { |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public void run() { |
|
|
|
public void run() { |
|
|
|
//切换播放
|
|
|
|
if (isPlaying) { |
|
|
|
if(isPlaying){ |
|
|
|
|
|
|
|
videoPlayer.again(); |
|
|
|
videoPlayer.again(); |
|
|
|
} |
|
|
|
} |
|
|
|
isPlaying = true; |
|
|
|
isPlaying = true; |
|
|
@ -176,8 +180,7 @@ public class FilterActivity extends BaseActivity implements SurfaceHolder.Callba |
|
|
|
}).start(); |
|
|
|
}).start(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//设置是否静音
|
|
|
|
private void setPlayAudio() { |
|
|
|
private void setPlayAudio(){ |
|
|
|
|
|
|
|
playAudio = !playAudio; |
|
|
|
playAudio = !playAudio; |
|
|
|
videoPlayer.playAudio(playAudio); |
|
|
|
videoPlayer.playAudio(playAudio); |
|
|
|
} |
|
|
|
} |
|
|
@ -201,7 +204,7 @@ public class FilterActivity extends BaseActivity implements SurfaceHolder.Callba |
|
|
|
protected void onDestroy() { |
|
|
|
protected void onDestroy() { |
|
|
|
super.onDestroy(); |
|
|
|
super.onDestroy(); |
|
|
|
isPlaying = false; |
|
|
|
isPlaying = false; |
|
|
|
//暂时注释
|
|
|
|
//FIXME
|
|
|
|
// videoPlayer.release();
|
|
|
|
// videoPlayer.release();
|
|
|
|
videoPlayer = null; |
|
|
|
videoPlayer = null; |
|
|
|
horizontalAdapter = null; |
|
|
|
horizontalAdapter = null; |
|
|
@ -217,9 +220,8 @@ public class FilterActivity extends BaseActivity implements SurfaceHolder.Callba |
|
|
|
@Override |
|
|
|
@Override |
|
|
|
void onSelectedFile(String filePath) { |
|
|
|
void onSelectedFile(String filePath) { |
|
|
|
videoPath = filePath; |
|
|
|
videoPath = filePath; |
|
|
|
//选择滤镜模式
|
|
|
|
|
|
|
|
doFilterPlay(5); |
|
|
|
doFilterPlay(5); |
|
|
|
//默认关闭声音
|
|
|
|
//sound off by default
|
|
|
|
btnSound.setChecked(true); |
|
|
|
btnSound.setChecked(true); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|