我正在通过FFMPEG从图像创建视频,我可以从图像中获取视频。我也正在利用JavaCV合并两个视频,我可以使用JavaCV加入视频而不会出现任何问题,只要视频是通过摄像头拍摄的,即通过移动摄像头实际录制的视频。
我面临的问题:
我无法使用图像合并从FFMPEG生成的视频以及用户选择的视频,这些视频主要是未通过移动相机生成和拍摄的视频。
代码: 通过图片生成视频的代码:
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(path + "/" + "dec16.mp4", 800, 400);
try {
recorder.setVideoCodec(avcodec.AV_CODEC_ID_MPEG4);
//recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
recorder.setVideoCodecName("H264");
recorder.setVideoOption("preset", "ultrafast");
recorder.setFormat("mp4");
recorder.setFrameRate(frameRate);
recorder.setVideoBitrate(60);
recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
startTime = System.currentTimeMillis();
recorder.start();
for(int j=0;j<MomentsGetStarted.chosen_images_uri.size();j++)
{
if(MomentsGetStarted.chosen_images_uri.get(j).video_id==0)
{
chosen_images.add(MomentsGetStarted.chosen_images_uri.get(j));
}
}
for (int i = 0; i < chosen_images.size(); i++) {
opencv_core.IplImage image = cvLoadImage(chosen_images.get(i).sdcardPath);
long t = 3000 * (System.currentTimeMillis() - startTime);
if (t > recorder.getTimestamp()) {
recorder.setTimestamp(t);
recorder.record(image);
}
}
recorder.stop();
} catch (Exception e) {
e.printStackTrace();
}
要合并视频的代码:
int count = file_path.size();
System.out.println("final_joined_list size " + file_path.size());
if (file_path.size() != 1) {
try {
Movie[] inMovies = new Movie[count];
mediaStorageDir = new File(
Environment.getExternalStorageDirectory()
+ "/Pictures");
for (int i = 0; i < count; i++) {
File file = new File(file_path.get(i));
System.out.println("fileeeeeeeeeeeeeeee " + file);
System.out.println("file exists!!!!!!!!!!");
FileInputStream fis = new FileInputStream(file);
FileChannel fc = fis.getChannel();
inMovies[i] = MovieCreator.build(fc);
fis.close();
fc.close();
}
List<Track> videoTracks = new LinkedList<Track>();
List<Track> audioTracks = new LinkedList<Track>();
Log.d("Movies length", "isss " + inMovies.length);
if (inMovies.length != 0) {
for (Movie m : inMovies) {
for (Track t : m.getTracks()) {
if (t.getHandler().equals("soun")) {
audioTracks.add(t);
}
if (t.getHandler().equals("vide")) {
videoTracks.add(t);
}
if (t.getHandler().equals("")) {
}
}
}
}
Movie result = new Movie();
System.out.println("audio and videoo tracks : "
+ audioTracks.size() + " , " + videoTracks.size());
if (audioTracks.size() > 0) {
result.addTrack(new AppendTrack(audioTracks
.toArray(new Track[audioTracks.size()])));
}
if (videoTracks.size() > 0) {
result.addTrack(new AppendTrack(videoTracks
.toArray(new Track[videoTracks.size()])));
}
IsoFile out = null;
try {
out = (IsoFile) new DefaultMp4Builder().build(result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long timestamp = new Date().getTime();
String timestampS = "" + timestamp;
File storagePath = new File(mediaStorageDir
+ File.separator);
storagePath.mkdirs();
File myMovie = new File(storagePath, String.format("%s.mp4", timestampS));
FileOutputStream fos = new FileOutputStream(myMovie);
FileChannel fco = fos.getChannel();
fco.position(0);
out.getBox(fco);
fco.close();
fos.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String mFileName = Environment.getExternalStorageDirectory()
.getAbsolutePath();
// mFileName += "/output.mp4";
File sdCardRoot = Environment.getExternalStorageDirectory();
File yourDir = new File(mediaStorageDir + File.separator);
for (File f : yourDir.listFiles()) {
if (f.isFile())
name = f.getName();
// make something with the name
}
mFileName = mediaStorageDir.getPath() + File.separator
+ "output-%s.mp4";
System.out.println("final filename : "
+ mediaStorageDir.getPath() + File.separator
+ "output-%s.mp4" + "names of files : " + name);
single_video = false;
return name;
} else {
single_video = true;
name = file_path.get(0);
return name;
}
错误:
在尝试合并通过图片和普通视频生成的视频时,我遇到的错误是
12-15 12:26:06.155 26022-26111/? W/System.err﹕ java.io.IOException: Cannot append com.googlecode.mp4parser.authoring.Mp4TrackImpl@45417c38 to com.googlecode.mp4parser.authoring.Mp4TrackImpl@44ffac60 since their Sample Description Boxes differ
12-15 12:26:06.155 26022-26111/? W/System.err﹕ at com.googlecode.mp4parser.authoring.tracks.AppendTrack.<init>(AppendTrack.java:48)
修正我尝试过:
Google建议我将JavaCV中的CODEC从avcodec.AV_CODEC_ID_MPEG4
更改为avcodec.AV_CODEC_ID_H264
。但是当我这样做时,我无法从图像中获取视频,从而引发以下错误:
12-15 12:26:05.840 26022-26089/? W/linker﹕ libavcodec.so has text relocations. This is wasting memory and is a security risk. Please fix.
12-15 12:26:05.975 26022-26089/? W/System.err﹕ com.googlecode.javacv.FrameRecorder$Exception: avcodec_open2() error -1: Could not open video codec.
12-15 12:26:05.975 26022-26089/? W/System.err﹕ at com.googlecode.javacv.FFmpegFrameRecorder.startUnsafe(FFmpegFrameRecorder.java:492)
12-15 12:26:05.975 26022-26089/? W/System.err﹕ at com.googlecode.javacv.FFmpegFrameRecorder.start(FFmpegFrameRecorder.java:267)
我需要什么:
从图像创建视频是不可避免的,并且该视频肯定会用于与可能具有任何编解码格式的其他视频合并。所以我需要找到一种方法来合并任何类型的视频,无论其编解码器或任何其他参数。我试图通过使用Jars和SO文件来保持简单,我不想通过全面实施FFMPEG库来让自己疯狂。话虽这么说,如果我没有任何其他方法来实现我想要的东西,我也准备好调查该库,但是非常感谢使用ALMOST工作代码的可靠资源。干杯。
更新 我查看了OpenCV的GitHub中提到的问题,但没有发现任何可靠的问题。 OpenCV Issues
答案 0 :(得分:1)
您正在使用MP4
解析器,这意味着它不会触及视频的编码。仅当两个视频共享相同的编码器设置(如分辨率,帧速率)以列出一些最明显的编码器设置时,此功能才有效。
如果您需要将视频与不同的编解码器或参数合并,那么您必须重新编码它们以定位通用格式和参数集,在这种情况下,一个简单的MP4
解析器赢了不行。
您可以使用ffmpeg直接实现此目的。