如何处理网络摄像头拔出然后重新插入 sarxos java 网络摄像头?
How to handle webcam unplug then replug for sarxos java webcam?
我尝试创建一个单例 class WebCamFrame
以使用 sarxos 网络摄像头库创建网络摄像头。我正在尝试处理我的网络摄像头断开连接然后重新连接的情况。我已尝试处理这种情况,但当我重新打开网络摄像头框架时,我的网络摄像头框架显示 'no image available' 文本。我处理这个案例的尝试是否正确?
我的网络摄像头class:
/**
* WebCam Frame which is a singleton class that runs on a new thread
* It reads in video stream from webcam and attempts to read a qr code
*/
public class WebCamFrame extends JFrame implements Runnable, WebcamDiscoveryListener {
private static WebCamFrame singleton;
private Webcam webcam = null;
private WebcamPanel panel = null;
private JLabel playedCardLabel = null;
private JButton confirmButton = null;
private boolean running;
public static WebCamFrame getInstance() {
if( singleton == null )
singleton = new WebCamFrame();
return singleton;
}
@Override
public void webcamFound( WebcamDiscoveryEvent event ) {
if( webcam == null ) return;
Webcam newWebcam = event.getWebcam();
if( newWebcam.getName().equals( webcam.getName()) ) {
close();
webcam = Webcam.getWebcamByName( webcam.getName() );
webcam.open();
panel = new WebcamPanel( webcam );
}
}
@Override
public void webcamGone( WebcamDiscoveryEvent event ) {
if( webcam == null ) return;
Webcam disconnectedWebCam = event.getWebcam();
if( disconnectedWebCam.getName().equals( webcam.getName()) ) {
playedCardLabel.setText( "WebCam disconnected, please reconnect." );
webcam.close();
}
}
private WebCamFrame() {
super();
Webcam.addDiscoveryListener( this );
running = true;
setLayout( new FlowLayout() );
setTitle( "Scan a card to make your move" );
setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE );
addWindowListener( new WindowAdapter() {
@Override
public void windowClosing( WindowEvent e ) {
super.windowClosing( e );
close();
}
} );
Dimension size = WebcamResolution.QVGA.getSize();
webcam = Webcam.getWebcams().get( 1 );
webcam.setViewSize( size );
panel = new WebcamPanel( webcam );
panel.setPreferredSize( size );
panel.setFPSDisplayed( true );
panel.setLayout( new BorderLayout() );
playedCardLabel = new JLabel( "", SwingConstants.CENTER );
if( Webcam.getDefault() == null ) playedCardLabel.setText( "No Webcam detected" );
confirmButton = new JButton( "Confirm Selection" );
confirmButton.setVisible( false );
confirmButton.addActionListener( e -> {
close();
} );
add( panel );
JPanel subPanel = new JPanel();
subPanel.setLayout( new BorderLayout() );
subPanel.add( playedCardLabel, BorderLayout.NORTH );
subPanel.add( confirmButton, BorderLayout.SOUTH );
panel.add( subPanel, BorderLayout.SOUTH );
pack();
setVisible( false );
}
@Override
public void run() {
do {
try {
if( !running ) return;
Thread.sleep( 100 );
} catch( InterruptedException e ) {
e.printStackTrace();
}
Result result = null;
BufferedImage image;
// Only try to read qr code if webcam is open and frame is webCamFrame is visible
if( webcam.isOpen() && isVisible() ) {
System.out.println("Entering");
if( (image = webcam.getImage()) == null ) {
continue;
}
LuminanceSource source = new BufferedImageLuminanceSource( image );
BinaryBitmap bitmap = new BinaryBitmap( new HybridBinarizer(source) );
try {
result = new MultiFormatReader().decode( bitmap );
} catch( NotFoundException e ) {
// fall through if there is no QR code in image
}
}
if( result != null ) {
playedCardLabel.setText( "You have played card " + result.getText() );
confirmButton.setVisible( true );
}
} while( true );
}
/* Hide the webcam frame and reset its swing components */
public void close() {
setVisible( false );
resetComponents();
}
public void open() {
setVisible( true );
}
public void toggleOpen() {
if( isVisible() )
close();
else
open();
}
// Kill the webcam, join the webcam thread and dispose of the webcam frame
public void kill() throws InterruptedException {
dispose();
webcam.close();
singleton = null;
running = false;
}
private void resetComponents() {
confirmButton.setVisible( false );
playedCardLabel.setText( "" );
}
}
我在主 class 中为我的网络摄像头生成了一个新线程,如下所示:
Thread webcamThread = new Thread( WebCamFrame.getInstance() );
webcamThread.start();
try {
webcamThread.join();
} catch ( InterruptedException ex ) {
Logger.getLogger( tsInfluence.class.getName() ).log( Level.SEVERE, null, ex );
}
这是我第一次尝试实现单例class,我觉得这可能是我的问题所在,如有任何错误,请提前致歉。谢谢
@silentsudo 在评论中的建议对我有用:
“我建议创建一个单独的 class 来直接处理网络摄像头事件,然后您可以创建自己的侦听器以向 UI class”
提供回调
我尝试创建一个单例 class WebCamFrame
以使用 sarxos 网络摄像头库创建网络摄像头。我正在尝试处理我的网络摄像头断开连接然后重新连接的情况。我已尝试处理这种情况,但当我重新打开网络摄像头框架时,我的网络摄像头框架显示 'no image available' 文本。我处理这个案例的尝试是否正确?
我的网络摄像头class:
/**
* WebCam Frame which is a singleton class that runs on a new thread
* It reads in video stream from webcam and attempts to read a qr code
*/
public class WebCamFrame extends JFrame implements Runnable, WebcamDiscoveryListener {
private static WebCamFrame singleton;
private Webcam webcam = null;
private WebcamPanel panel = null;
private JLabel playedCardLabel = null;
private JButton confirmButton = null;
private boolean running;
public static WebCamFrame getInstance() {
if( singleton == null )
singleton = new WebCamFrame();
return singleton;
}
@Override
public void webcamFound( WebcamDiscoveryEvent event ) {
if( webcam == null ) return;
Webcam newWebcam = event.getWebcam();
if( newWebcam.getName().equals( webcam.getName()) ) {
close();
webcam = Webcam.getWebcamByName( webcam.getName() );
webcam.open();
panel = new WebcamPanel( webcam );
}
}
@Override
public void webcamGone( WebcamDiscoveryEvent event ) {
if( webcam == null ) return;
Webcam disconnectedWebCam = event.getWebcam();
if( disconnectedWebCam.getName().equals( webcam.getName()) ) {
playedCardLabel.setText( "WebCam disconnected, please reconnect." );
webcam.close();
}
}
private WebCamFrame() {
super();
Webcam.addDiscoveryListener( this );
running = true;
setLayout( new FlowLayout() );
setTitle( "Scan a card to make your move" );
setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE );
addWindowListener( new WindowAdapter() {
@Override
public void windowClosing( WindowEvent e ) {
super.windowClosing( e );
close();
}
} );
Dimension size = WebcamResolution.QVGA.getSize();
webcam = Webcam.getWebcams().get( 1 );
webcam.setViewSize( size );
panel = new WebcamPanel( webcam );
panel.setPreferredSize( size );
panel.setFPSDisplayed( true );
panel.setLayout( new BorderLayout() );
playedCardLabel = new JLabel( "", SwingConstants.CENTER );
if( Webcam.getDefault() == null ) playedCardLabel.setText( "No Webcam detected" );
confirmButton = new JButton( "Confirm Selection" );
confirmButton.setVisible( false );
confirmButton.addActionListener( e -> {
close();
} );
add( panel );
JPanel subPanel = new JPanel();
subPanel.setLayout( new BorderLayout() );
subPanel.add( playedCardLabel, BorderLayout.NORTH );
subPanel.add( confirmButton, BorderLayout.SOUTH );
panel.add( subPanel, BorderLayout.SOUTH );
pack();
setVisible( false );
}
@Override
public void run() {
do {
try {
if( !running ) return;
Thread.sleep( 100 );
} catch( InterruptedException e ) {
e.printStackTrace();
}
Result result = null;
BufferedImage image;
// Only try to read qr code if webcam is open and frame is webCamFrame is visible
if( webcam.isOpen() && isVisible() ) {
System.out.println("Entering");
if( (image = webcam.getImage()) == null ) {
continue;
}
LuminanceSource source = new BufferedImageLuminanceSource( image );
BinaryBitmap bitmap = new BinaryBitmap( new HybridBinarizer(source) );
try {
result = new MultiFormatReader().decode( bitmap );
} catch( NotFoundException e ) {
// fall through if there is no QR code in image
}
}
if( result != null ) {
playedCardLabel.setText( "You have played card " + result.getText() );
confirmButton.setVisible( true );
}
} while( true );
}
/* Hide the webcam frame and reset its swing components */
public void close() {
setVisible( false );
resetComponents();
}
public void open() {
setVisible( true );
}
public void toggleOpen() {
if( isVisible() )
close();
else
open();
}
// Kill the webcam, join the webcam thread and dispose of the webcam frame
public void kill() throws InterruptedException {
dispose();
webcam.close();
singleton = null;
running = false;
}
private void resetComponents() {
confirmButton.setVisible( false );
playedCardLabel.setText( "" );
}
}
我在主 class 中为我的网络摄像头生成了一个新线程,如下所示:
Thread webcamThread = new Thread( WebCamFrame.getInstance() );
webcamThread.start();
try {
webcamThread.join();
} catch ( InterruptedException ex ) {
Logger.getLogger( tsInfluence.class.getName() ).log( Level.SEVERE, null, ex );
}
这是我第一次尝试实现单例class,我觉得这可能是我的问题所在,如有任何错误,请提前致歉。谢谢
@silentsudo 在评论中的建议对我有用:
“我建议创建一个单独的 class 来直接处理网络摄像头事件,然后您可以创建自己的侦听器以向 UI class”
提供回调