Java 捕获视频流并在文件系统中另存为多个mp4视频

Java 捕获视频流并在文件系统中另存为多个mp4视频,java,rx-java,Java,Rx Java,我的目标是建立一种从网络捕获视频流的方法(在本例中为RTSP),并从流中创建5秒的视频,并保存为单独的MP4文件,以下不是一种新颖的方法,但捕获bufferedimage是可行的,但视频编码是非常错误的,它既抛出ConcurrentModificationException,也抛出 java.lang.RuntimeException: Unable to create stream id 0, index 0, codec com.xuggle.xuggler.ICodec@-11772921

我的目标是建立一种从网络捕获视频流的方法(在本例中为RTSP),并从流中创建5秒的视频,并保存为单独的MP4文件,以下不是一种新颖的方法,但捕获
bufferedimage
是可行的,但视频编码是非常错误的,它既抛出
ConcurrentModificationException
,也抛出

java.lang.RuntimeException: Unable to create stream id 0, index 0, codec com.xuggle.xuggler.ICodec@-1177292192[type=CODEC_TYPE_VIDEO;id=CODEC_ID_MPEG4;name=mpeg4;]
以下是完整的代码:

public class App {

    static {
        String name = "WowzaBunny";
        String rtsp = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_175k.mov";
        Webcam.setDriver(new VlcjDriver(Arrays.asList(new MediaListItem(name, rtsp, new ArrayList<MediaListItem>()))));
    }

    private static final String OUTPUT_FOLDER = "C:\\Image\\";

    public static void main( String[] args ) throws Exception {
        Webcam webcam = Webcam.getWebcams().get(0);
        webcam.setViewSize(WebcamResolution.VGA.getSize());

        WebcamPanel panel = new WebcamPanel(webcam);
        panel.setFPSDisplayed(true);

        double fps = webcam.getFPS();
        if(fps == 0.0) {
            fps = 30.0;
        }
        long interval = (long) (1000 / fps);

        final long[] startTime = {System.nanoTime()};
        final IMediaWriter writer = ToolFactory.makeWriter(OUTPUT_FOLDER + "video.mp4");

        List<BufferedImage> bufferedImageList = new LinkedList<>();

        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
        executor.scheduleAtFixedRate(() -> {
            String imgName = "image.png";
            File filePath = new File(FileSystems.getDefault().getPath("C:\\Image").toString() + File.separator + imgName);
            BufferedImage bufferedImage = webcam.getImage();
            if(bufferedImage != null) {
                try {
                    bufferedImageList.add(bufferedImage);
                    ImageIO.write(bufferedImage, "JPG", filePath);
                    System.out.format("File %s has been saved in %s\n", imgName, filePath.getAbsolutePath());
                } catch (IOException e) {
                    e.printStackTrace();
                    System.out.println("Error - " + e.getMessage());
                }
            }
        }, 0, interval, TimeUnit.MILLISECONDS);

        ScheduledExecutorService singleThreadScheduledExecutor =
                Executors.newSingleThreadScheduledExecutor();

        singleThreadScheduledExecutor.scheduleAtFixedRate(() -> {
            try {
                bufferedImageList.forEach(bufferedImage -> {
                    bufferedImage = convertToType(bufferedImage, BufferedImage.TYPE_3BYTE_BGR);
                    writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_MPEG4,
                            bufferedImage.getWidth() / 2, bufferedImage.getHeight() / 2);
                    long elapsed = System.nanoTime() - startTime[0];
                    writer.encodeVideo(0, bufferedImage, elapsed,
                            TimeUnit.NANOSECONDS);
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                });
                bufferedImageList.clear();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, 0, 5, TimeUnit.SECONDS);

        Object o = new Object();
        synchronized (o) {
            o.wait();
        }

        writer.close();

    }

    public static BufferedImage convertToType(BufferedImage sourceImage,
                                              int targetType) {
        BufferedImage image;
        if (sourceImage.getType() == targetType) {
            image = sourceImage;
        } else {
            image = new BufferedImage(sourceImage.getWidth(),
                    sourceImage.getHeight(), targetType);
            image.getGraphics().drawImage(sourceImage, 0, 0, null);
        }
        return image;
    }

}
公共类应用程序{
静止的{
String name=“WowzaBunny”;
字符串rtsp=”rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_175k.mov";
Webcam.setDriver(新的VlcjDriver(Arrays.asList)(新的MediaListItem(name,rtsp,newarraylist()));
}
私有静态最终字符串输出\u FOLDER=“C:\\Image\\”;
公共静态void main(字符串[]args)引发异常{
Webcam Webcam=Webcam.getWebcams().get(0);
webcam.setViewSize(WebcamResolution.VGA.getSize());
网络摄像机面板=新的网络摄像机(网络摄像机);
显示面板。设置FPS(真);
double fps=webcam.getFPS();
如果(fps==0.0){
fps=30.0;
}
长间隔=(长)(1000/fps);
final long[]startTime={System.nanoTime()};
最终IMediaWriter=ToolFactory.makeWriter(输出文件夹+“video.mp4”);
List bufferedImageList=新链接列表();
ScheduledExecutorService executor=执行者。newScheduledThreadPool(1);
执行者。日程安排固定日期(()->{
字符串imgName=“image.png”;
File filePath=新文件(FileSystems.getDefault().getPath(“C:\\Image”).toString()+File.separator+imgName);
BuffereImage BuffereImage=webcam.getImage();
if(buffereImage!=null){
试一试{
添加(BuffereImage);
写入(buffereImage,“JPG”,文件路径);
System.out.format(“文件%s已保存在%s\n”、imgName、filePath.getAbsolutePath());
}捕获(IOE异常){
e、 printStackTrace();
System.out.println(“错误-”+e.getMessage());
}
}
},0,间隔,时间单位为毫秒);
ScheduleXecutorService SingleThreadScheduleXecutor=
Executors.newSingleThreadScheduledExecutor();
singleThreadScheduledExecutor.scheduleAtFixedRate(()->{
试一试{
forEach(BuffereImage->{
BuffereImage=转换类型(BuffereImage,BuffereImage.TYPE_3BYTE_BGR);
writer.addVideoStream(0,0,ICodec.ID.CODEC\u ID\u MPEG4,
buffereImage.getWidth()/2,buffereImage.getHeight()/2);
长时间运行=System.nanoTime()-startTime[0];
writer.encodeVideo(0,缓冲区图像,已用,
时间单位(纳秒);
试一试{
睡眠(500);
}捕捉(中断异常e){
e、 printStackTrace();
}
});
bufferedImageList.clear();
}捕获(例外e){
e、 printStackTrace();
}
},0,5,时间单位为秒);
对象o=新对象();
同步(o){
o、 等待();
}
writer.close();
}
公共静态BuffereImage转换类型(BuffereImage sourceImage,
int目标类型){
缓冲图像;
if(sourceImage.getType()==targetType){
图像=源图像;
}否则{
image=new BufferedImage(sourceImage.getWidth(),
sourceImage.getHeight(),targetType);
image.getGraphics().drawImage(sourceImage,0,0,null);
}
返回图像;
}
}
在Java/RxJava中捕获视频流并保存到多个mp4视频文件的正确方法是什么