2016-07-14 14 views
1

私は実際にウェブカメラからフレームをキャプチャするJavaクラスを持っています。このクラスには、開始と終了の2つのメソッドがあります。このクラスを私が作成したGUIに追加したいと思います。しかし、私が彼らのように機能を追加するとき、私のゲームは固執しています。私はここでいくつかのマルチスレッドをする必要があるようです。クラスメソッドを新しいスレッドに追加するにはどうすればよいですか?新しいスレッドにJavaクラスメソッドを追加

EDIT:今私のコードは以下の通りです:

Thread t2 = new Thread(new Runnable() { 
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(); 

    //System.in.read(); 
    //videoCapture.stop(); 

    }}); 

私はt2.startを呼び出すことによって、このスレッドを実行している()私は第二の機能でvideoCapture.stop()を呼び出すことができますか?

答えて

1

使用AtomicBooleanあなたの2間の状態を表すために、メソッドを呼び出し、ストリームを読み込みまたは終了するために状態を使用します。

import java.util.concurrent.atomic.AtomicBoolean; 

public class CameraCapture { 

    private AtomicBoolean doCapture = new AtomicBoolean(); 

    public Thread startCapture() { 
     System.out.println("Setting Capture status to true"); 
     doCapture.set(true); 


     Thread capture = new Thread(new Runnable() { 
      public void run() { 
       System.out.println("Initializing Sources"); 
       /* Initialization Code here. */ 
       System.out.println("Found WebCam!"); 

       System.out.println("Configuring Codec"); 

       while(doCapture.get()) { 
        System.out.println("\tReading Data!"); 
        //Read and handle input. 
        try { 
         Thread.sleep(1000); 
        } catch (InterruptedException exception) { 
         // FIXME: minimum of logging. 
         exception.printStackTrace(); 
        } 
       } 

       System.out.println("Capture Terminated!"); 

      }}, "CameraCapture Injest"); //Name the thread! 

     System.out.println("Starting Capture");   
     capture.start(); 
     return capture; 
    } 

    public void stopCapture() { 
     System.out.println("Disabling capture"); 
     doCapture.set(false); 
    } 
} 

このテストでは、ワークフローがコンソールに表示されます。

@Test 
    public void captureThreadTest() throws Exception { 
     CameraCapture capture = new CameraCapture(); 
     Thread captureRunner = capture.startCapture(); 
     Thread.sleep(10000); 

     capture.stopCapture(); 

     captureRunner.join(); 
    } 

得るために、私はユニットテストの例の目的のためにstartCaptureソリー からスレッド参照を返すよ注意(私は は(参加を実行するために必要なので)最後の出力)。プロダクションコードで を公開することはお勧めできません。それは良いカプセル化 とそのスレッドの状態の所有権を提供しないためです。

Setting Capture status to true 
Starting Capture 
Initializing Sources 
Found WebCam! 
Configuring Codec 
    Reading Data! 
    Reading Data! 
    Reading Data! 
    Reading Data! 
    Reading Data! 
    Reading Data! 
    Reading Data! 
    Reading Data! 
    Reading Data! 
    Reading Data! 
Disabling capture 
Capture Terminated! 
2

Runner。 Eclipseを使用している場合は、ランナーを自動的に作成するテンプレートがあります。また、Swingを使用している場合は、すべてをSwingイベントキューに指定する必要があります。

これをまだ実行していない場合は、アプリケーション自体ではなくコントローラになるようにGUIを再設計する必要があるかもしれません(おそらく、GUIにこのスレッドの問題があることから) 。

関連ドキュメント

Runnableドキュメント:https://docs.oracle.com/javase/7/docs/api/java/lang/Runnable.html

EventQueue.invokeLater(Runnable)ドキュメント:http://docs.oracle.com/javase/8/docs/api/java/awt/EventQueue.html#invokeLater-java.lang.Runnable-

の同時実行性とSwingWorkerhttps://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

+0

私はeclipseとjavafxを使用しています。だからクラスのランナーを作ることができますか? – konstantin

+0

ランナーを使用して新しいスレッドを取得します。そのランナーを使ってスキャンします。また、SwingWorkerとJavaFXの代替案を調べることもできます。 JavaFXでは、 'invokeLater'は' Platform.runLater(...) 'に相当します。 – ifly6

+0

私はそれを行うことはできません:(私はjavafxで作業しなければなりません) – konstantin

関連する問題