Java 在Android中,如何通过VidEffects渲染带有过滤器的视频
我可以使用VidEffects()成功地将过滤器应用于我应用程序中录制的视频。问题是,这样的插件不会呈现过滤后的视频,无论如何,我试图通过使用此类应用永久视频效果:Java 在Android中,如何通过VidEffects渲染带有过滤器的视频,java,android,video,effects,Java,Android,Video,Effects,我可以使用VidEffects()成功地将过滤器应用于我应用程序中录制的视频。问题是,这样的插件不会呈现过滤后的视频,无论如何,我试图通过使用此类应用永久视频效果: public class VideoProcessing extends AsyncTask { private final File myDirectory; private FFmpegFrameGrabber VIDEO_GRABBER; private FFmpegFrameRecorder vide
public class VideoProcessing extends AsyncTask {
private final File myDirectory;
private FFmpegFrameGrabber VIDEO_GRABBER;
private FFmpegFrameRecorder videoRecorder;
File file;
int totalLength;
private Context mContext;
private FFmpegFrameFilter filter;
VideoProcessing(Context context, String path) {
mContext = context;
file = new File(path);
VIDEO_GRABBER = new FFmpegFrameGrabber(file);
myDirectory = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) + "/_Pikky-Edited-Video/");
Log.i(Configurations.TAG, "VIDEO PROCESSING PATH: " + myDirectory);
if (!myDirectory.exists()) { myDirectory.mkdirs(); }
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Object doInBackground(Object[] params) {
Log.i(Configurations.TAG, "DO IN BACKGROUND: " + params);
Frame tempVideoFrame;
try {
VIDEO_GRABBER.start();
initVideoRecorder(myDirectory + "/video" + System.currentTimeMillis() + ".mp4");
filter.start();
while (VIDEO_GRABBER.grab() != null) {
tempVideoFrame = VIDEO_GRABBER.grabImage();
if (tempVideoFrame != null) {
filter.push(tempVideoFrame);
tempVideoFrame = filter.pull();
videoRecorder.record(tempVideoFrame);
}
}
filter.stop();
videoRecorder.stop();
videoRecorder.release();
VIDEO_GRABBER.stop();
VIDEO_GRABBER.release();
Log.i(Configurations.TAG, "VIDEO GRABBER STOP");
} catch (FrameGrabber.Exception | FrameRecorder.Exception | FrameFilter.Exception e) { e.printStackTrace(); }
return null;
}
@Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
Log.i(Configurations.TAG, "ON POST EXECUTED: " + o);
}
private void initVideoRecorder(String path) {
try {
// FFmpeg effect/filter that will be applied
filter = new FFmpegFrameFilter("colorchannelmixer=.393:.769:.189:0:.349:.686:.168:0:.272:.534:.131", VIDEO_GRABBER.getImageWidth(), VIDEO_GRABBER.getImageHeight());
videoRecorder = FFmpegFrameRecorder.createDefault(path, VIDEO_GRABBER.getImageWidth(), VIDEO_GRABBER.getImageHeight());
videoRecorder.start();
Log.i(Configurations.TAG, "VIDEO PROCESSING - VIDEO RECORDER START");
} catch (FrameRecorder.Exception e) { e.printStackTrace(); }
}
}
该类在切换情况下从我的EditVideo活动调用,如下所示-其中surfaceView是一个自定义GLSurfaceView:
case 2: surfaceView.init(mediaPlayer, new InvertColorsEffect());
new VideoProcessing(EditVideo.this, Configurations.videoToShareURL);
break;
dependencies {
// jCenter
implementation 'com.daasuu:Mp4Composer-android:0.1.6'
}
无论如何,doInBackground
函数似乎没有在任何地方被调用,因为应用程序只在我的Pictures目录(_Pikky-Edited-Video)中创建自定义文件夹,并在Logcat中打印其路径-请参阅Log.i(Configurations.TAG,“视频处理路径:+myDirectory”)代码>就是这样,视频预览一直在我的活动中播放-这是因为我已将MediaPlayer的循环设置为true-但是我的VideoProcessing
类的其他函数也没有被调用,initVideoRecorder()
这是我的build.gradle,所有必要的依赖项都已下载:
implementation 'com.writingminds:FFmpegAndroid:0.3.2'
implementation group: 'org.bytedeco', name: 'javacv', version: '1.1'
implementation group: 'org.bytedeco.javacpp-presets', name: 'opencv', version: '3.0.0-1.1', classifier: 'android-arm'
implementation group: 'org.bytedeco.javacpp-presets', name: 'ffmpeg', version: '2.8.1-1.1', classifier: 'android-arm'
我也欢迎使用其他解决方案来渲染带有过滤器的视频。解决方案:
我发现这个非常棒且易于实现的框架:
只需在build.gradle中添加它的依赖项即可:
case 2: surfaceView.init(mediaPlayer, new InvertColorsEffect());
new VideoProcessing(EditVideo.this, Configurations.videoToShareURL);
break;
dependencies {
// jCenter
implementation 'com.daasuu:Mp4Composer-android:0.1.6'
}
并使用此代码根据每个效果导出过滤后的视频:
renderVideoIntoMp4(myVideoURL, new GlInvertFilter()); // add the Filter you want
void renderVideoIntoMp4(String filePath, GlFilter filter) {
tempVideoPath = getVideoFilePath();
//Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/temp_video.mp4";
new Mp4Composer(filePath, tempVideoPath)
// .rotation(Rotation.ROTATION_270)
//.size(720, 1280)
.fillMode(FillMode.PRESERVE_ASPECT_FIT)
.filter(filter)
.mute(false)
.flipHorizontal(false)
.flipVertical(false)
.listener(new Mp4Composer.Listener() {
@Override
public void onProgress(double progress) {
Log.i(Configurations.TAG, "SAVING PROGRESS: " + progress);
}
@Override
public void onCompleted() {
Log.i(Configurations.TAG, "onCompleted()");
exportMp4ToGallery(getApplicationContext(), tempVideoPath);
Log.i(Configurations.TAG, "SAVED VIDEO PATH: " + tempVideoPath);
File file = new File(tempVideoPath);
file.delete();
}
@Override
public void onCanceled() {
}
@Override
public void onFailed(Exception e) {
Log.i(Configurations.TAG, "onFailed(): " + e.getMessage());
}
})
.start();
}
public static void exportMp4ToGallery(Context context, String filePath) {
final ContentValues values = new ContentValues(2);
values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
values.put(MediaStore.Video.Media.DATA, filePath);
context.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
values);
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse("file://" + filePath)));
}
public File getAndroidMoviesFolder() {
return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
}
public String getVideoFilePath() {
return getAndroidMoviesFolder().getAbsolutePath() + "/temp_video.mp4";
}
解决方案:
我发现这个非常棒且易于实现的框架:
只需在build.gradle中添加它的依赖项即可:
case 2: surfaceView.init(mediaPlayer, new InvertColorsEffect());
new VideoProcessing(EditVideo.this, Configurations.videoToShareURL);
break;
dependencies {
// jCenter
implementation 'com.daasuu:Mp4Composer-android:0.1.6'
}
并使用此代码根据每个效果导出过滤后的视频:
renderVideoIntoMp4(myVideoURL, new GlInvertFilter()); // add the Filter you want
void renderVideoIntoMp4(String filePath, GlFilter filter) {
tempVideoPath = getVideoFilePath();
//Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/temp_video.mp4";
new Mp4Composer(filePath, tempVideoPath)
// .rotation(Rotation.ROTATION_270)
//.size(720, 1280)
.fillMode(FillMode.PRESERVE_ASPECT_FIT)
.filter(filter)
.mute(false)
.flipHorizontal(false)
.flipVertical(false)
.listener(new Mp4Composer.Listener() {
@Override
public void onProgress(double progress) {
Log.i(Configurations.TAG, "SAVING PROGRESS: " + progress);
}
@Override
public void onCompleted() {
Log.i(Configurations.TAG, "onCompleted()");
exportMp4ToGallery(getApplicationContext(), tempVideoPath);
Log.i(Configurations.TAG, "SAVED VIDEO PATH: " + tempVideoPath);
File file = new File(tempVideoPath);
file.delete();
}
@Override
public void onCanceled() {
}
@Override
public void onFailed(Exception e) {
Log.i(Configurations.TAG, "onFailed(): " + e.getMessage());
}
})
.start();
}
public static void exportMp4ToGallery(Context context, String filePath) {
final ContentValues values = new ContentValues(2);
values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
values.put(MediaStore.Video.Media.DATA, filePath);
context.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI,
values);
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.parse("file://" + filePath)));
}
public File getAndroidMoviesFolder() {
return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
}
public String getVideoFilePath() {
return getAndroidMoviesFolder().getAbsolutePath() + "/temp_video.mp4";
}
完美-但是没有“File File=new File(tempVideoPath);File.delete();”完美-但是没有“File File=new File(tempVideoPath);File.delete();”