Java多线程问题:如果我没有';t让system.in.read()捕获器立即启动和停止,即使不调用stop
我试图理解线程在java中是如何工作的。我有一个javafx项目,它是一个简单的游戏界面,有问题和用户。我正试图用视频捕捉每个游戏环节的视觉信息。问题是我必须使用多线程,因为我不能同时运行gui和capturer。我有一个扩展线程的类,如下所示: 编辑:Java多线程问题:如果我没有';t让system.in.read()捕获器立即启动和停止,即使不调用stop,java,multithreading,javafx,Java,Multithreading,Javafx,我试图理解线程在java中是如何工作的。我有一个javafx项目,它是一个简单的游戏界面,有问题和用户。我正试图用视频捕捉每个游戏环节的视觉信息。问题是我必须使用多线程,因为我不能同时运行gui和capturer。我有一个扩展线程的类,如下所示: 编辑: startTestButton = new Button("START"); startTestButton.addEventHandler(ActionEvent.ACTION, (e) -> { n
startTestButton = new Button("START");
startTestButton.addEventHandler(ActionEvent.ACTION, (e) -> {
new Thread(new Runnable() {
@Override public void run() {
VideoCapture videoCapture = VideoCapture.create(VideoFormat.WMV);
List<VideoSource> availableVideoSources = VideoSource.getAvailable();
System.out.println("availableVideoSources = " + availableVideoSources);
if (availableVideoSources.isEmpty()) {
throw new IllegalStateException("No external video sources available");
}
VideoSource webCamera = availableVideoSources.get(0);
System.out.println("webCamera = " + webCamera);
videoCapture.setVideoSource(webCamera);
java.util.List<Codec> videoCodecs = videoCapture.getVideoCodecs();
System.out.println("videoCodecs = " + videoCodecs);
if (videoCodecs.isEmpty()) {
throw new IllegalStateException("No video codecs available");
}
Codec videoCodec = videoCodecs.get(2);
System.out.println("videoCodec = " + videoCodec);
EncodingParameters encodingParameters = new EncodingParameters(new File("file.wmv"));
encodingParameters.setBitrate(500000);
encodingParameters.setFramerate(10);
encodingParameters.setKeyFrameInterval(1);
encodingParameters.setCodec(videoCodec);
videoCapture.setEncodingParameters(encodingParameters);
videoCapture.start();
try {
System.in.read();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
});
startTestButton=新按钮(“开始”);
startTestButton.addEventHandler(ActionEvent.ACTION,(e)->{
新线程(newrunnable()){
@重写公共无效运行(){
VideoCapture VideoCapture=VideoCapture.create(VideoFormat.WMV);
List availableVideoSources=VideoSource.getAvailable();
System.out.println(“availableVideoSources=“+availableVideoSources”);
if(availableVideoSources.isEmpty()){
抛出新的IllegalStateException(“没有可用的外部视频源”);
}
VideoSource网络摄像机=availableVideoSources.get(0);
System.out.println(“webCamera=“+webCamera”);
videoCapture.setVideoSource(网络摄像机);
java.util.List videoCodecs=videoCapture.getVideoCodecs();
System.out.println(“videoCodecs=“+videoCodecs”);
if(videoCodecs.isEmpty()){
抛出新的IllegalStateException(“没有可用的视频编解码器”);
}
Codec videoCodec=videoCodecs.get(2);
System.out.println(“videoCodec=“+videoCodec”);
EncodingParameters EncodingParameters=新的编码参数(新文件(“File.wmv”));
编码参数.setBitrate(500000);
编码参数。设置帧率(10);
encodingParameters.setKeyFrameInterval(1);
编码参数。设置编解码器(视频编解码器);
videoCapture.setEncodingParameters(编码参数);
videoCapture.start();
试一试{
System.in.read();
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
}
}).start();
});
我的线程问题是,如果我没有system.in.read()捕获程序,即使不调用stop,捕获程序也会立即启动和停止 我不使用JXCapture,但根据文档,方法
VideoCapture.start()
异步启动捕获。因此,根本没有明显的理由创建自己的背景线程。只需使用“开始”按钮启动捕获,然后使用“停止”按钮停止捕获:
private VideoCapture videoCapture = null ;
private Button startTestButton ;
private Button stopTestButton ;
// ...
startTestButton = new Button("START");
startTestButton.addEventHandler(ActionEvent.ACTION, (e) -> {
if (videoCapture == null) {
videoCapture = VideoCapture.create(VideoFormat.WMV);
List<VideoSource> availableVideoSources = VideoSource.getAvailable();
System.out.println("availableVideoSources = " + availableVideoSources);
if (availableVideoSources.isEmpty()) {
throw new IllegalStateException("No external video sources available");
}
VideoSource webCamera = availableVideoSources.get(0);
System.out.println("webCamera = " + webCamera);
videoCapture.setVideoSource(webCamera);
java.util.List<Codec> videoCodecs = videoCapture.getVideoCodecs();
System.out.println("videoCodecs = " + videoCodecs);
if (videoCodecs.isEmpty()) {
throw new IllegalStateException("No video codecs available");
}
Codec videoCodec = videoCodecs.get(2);
System.out.println("videoCodec = " + videoCodec);
EncodingParameters encodingParameters = new EncodingParameters(new File("file.wmv"));
encodingParameters.setBitrate(500000);
encodingParameters.setFramerate(10);
encodingParameters.setKeyFrameInterval(1);
encodingParameters.setCodec(videoCodec);
videoCapture.setEncodingParameters(encodingParameters);
videoCapture.start();
startTestButton.setDisable(true);
stopTestButton.setDisable(false);
} else {
throw new IllegalStateException("Capture already in progress");
}
});
stopTestButton = new Button("Stop");
stopTestButton.setDisable(true);
stopTestButton.addEventHandler(ActionEvent.ACTION, e -> {
if (videoCapture != null) {
videoCapture.stop();
videoCapture = null ;
startTestButton.setDisable(false);
stopTestButton.setDisable(true);
} else {
throw new IllegalStateException("No capture in progress");
}
});
private VideoCapture VideoCapture=null;
私人按钮开始按钮;
私有按钮stopTestButton;
// ...
开始按钮=新按钮(“开始”);
startTestButton.addEventHandler(ActionEvent.ACTION,(e)->{
if(videoCapture==null){
videoCapture=videoCapture.create(VideoFormat.WMV);
List availableVideoSources=VideoSource.getAvailable();
System.out.println(“availableVideoSources=“+availableVideoSources”);
if(availableVideoSources.isEmpty()){
抛出新的IllegalStateException(“没有可用的外部视频源”);
}
VideoSource网络摄像机=availableVideoSources.get(0);
System.out.println(“webCamera=“+webCamera”);
videoCapture.setVideoSource(网络摄像机);
java.util.List videoCodecs=videoCapture.getVideoCodecs();
System.out.println(“videoCodecs=“+videoCodecs”);
if(videoCodecs.isEmpty()){
抛出新的IllegalStateException(“没有可用的视频编解码器”);
}
Codec videoCodec=videoCodecs.get(2);
System.out.println(“videoCodec=“+videoCodec”);
EncodingParameters EncodingParameters=新的编码参数(新文件(“File.wmv”));
编码参数.setBitrate(500000);
编码参数。设置帧率(10);
encodingParameters.setKeyFrameInterval(1);
编码参数。设置编解码器(视频编解码器);
videoCapture.setEncodingParameters(编码参数);
videoCapture.start();
startTestButton.setDisable(真);
stopTestButton.setDisable(假);
}否则{
抛出新的非法状态异常(“捕获已在进行”);
}
});
stopTestButton=新按钮(“停止”);
stopTestButton.setDisable(真);
stopTestButton.addEventHandler(ActionEvent.ACTION,e->{
如果(视频捕获!=null){
videoCapture.stop();
视频捕获=空;
startTestButton.setDisable(false);
stopTestButton.setDisable(真);
}否则{
抛出新的非法状态异常(“无捕获进行中”);
}
});
同样,由于我没有访问此库的权限,这是未经测试的,但它应该可以工作。您看过吗?我尝试使用javafx并发的方法。扩展线程时,您需要将代码放在run()方法中,而不是start()。若您不需要改变特定于线程的行为,那个么最好实现Runnable接口并使用它来启动新线程。我不知道jxcapture,但我玩了一些JavaCV库和网络摄像头捕获,你可以看到一些例子,为什么你需要一个线程?声明
start()
异步启动捕获(即该方法立即退出,捕获可能已经在另一个线程中运行)。@whitesite我更喜欢jxcapture,因为它似乎是一个更轻松的解决方案,更容易理解,而且似乎可以工作。“James_D”似乎错误与多线程无关。但是,我还是遇到了与System.in.read()相同的问题,如果没有这一行,我的捕获会立即启动和停止