无法使用JavaCV合并Android中的视频(“示例说明”错误)

时间:2015-12-15 08:34:20

标签: android video merge ffmpeg javacv

我正在通过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

1 个答案:

答案 0 :(得分:1)

您正在使用MP4解析器,这意味着它不会触及视频的编码。仅当两个视频共享相同的编码器设置(如分辨率,帧速率)以列出一些最明显的编码器设置时,此功能才有效。

如果您需要将视频与不同的编解码器或参数合并,那么您必须重新编码它们以定位通用格式和参数集,在这种情况下,一个简单的MP4解析器赢了不行。

您可以使用ffmpeg直接实现此目的。