2012-02-14 93 views
3

所以我使用gstreamer爲java,我試圖播放實時視頻流並在同一時間錄製它。現在,我可以一次做一個,但我不知道如何在同一時間做到這一點。我嘗試過對它進行線程化,但是由於兩個線程都試圖訪問相同的資源,所以發生衝突。那麼,我告訴我,我需要使用T恤和隊列,基本上,所有不同的路徑共享相同的資源,而不是試圖控制它(這就是我的想法),我不知道如何做到這一點雖然在java中,現在互聯網沒有一個關於tees的java的好教程...(看了一下,所有的代碼都沒有在我的機器上編譯)繼承了我在做什麼的想法Gstreamer三通/排隊多流水線

public class Main { 
private static Pipeline pipe; 
private static Pipeline pipeB; 
public static void main(String[] args) { 
    args = Gst.init("SwingVideoTest", args); 




    pipe = new Pipeline("pipeline"); 
    pipeB = new Pipeline("pipeline"); 

    final Element tee = ElementFactory.make("queue", null); 
    Element queue0 = ElementFactory.make("queue", null); 
    Element queue1 = ElementFactory.make("queue", null); 
    AppSink appsink = (AppSink)ElementFactory.make("appsink", null); 

    tee.set("silent", "false"); 
    appsink.set("emit-signals", "true"); 

    final Element videosrc = ElementFactory.make("v4l2src", "source"); 
    videosrc.set("device" , "/dev/video1"); 

    final Element colorspace = ElementFactory.make("ffmpegcolorspace", "colorspace"); 
    final Element videofilter = ElementFactory.make("capsfilter", "flt"); 
    videofilter.setCaps(Caps.fromString("video/x-raw-yuv, width=640, height=480, framerate=10/1")); 

    final Element enc = ElementFactory.make("ffenc_mpeg4", "Encoder"); 
    final Element mux = ElementFactory.make("avimux", "muxer"); 

    final Element sink = ElementFactory.make("filesink", "File sink"); 
    sink.set("location", "./test.avi"); 


    final Element videosrcB = ElementFactory.make("v4l2src", "source"); 
    videosrcB.set("device" , "/dev/video0"); 
    final Element videofilterB = ElementFactory.make("capsfilter", "flt"); 
    videofilterB.setCaps(Caps.fromString("video/x-raw-yuv, width=640, height=480")); 



    VideoPlayer threadA = new VideoPlayer("screen", videosrcB, null, videofilterB, null, null, null, pipe); 
    VideoPlayer threadB = new VideoPlayer("recorder", videosrc, colorspace, videofilter, enc, mux, sink, pipeB); 


    threadA.run(); 
    threadB.run(); 
} 




public class VideoPlayer implements Runnable{ 

private String playerType; 
private Element videosrc, colorspace, videofilter, enc, mux, sink; 
private Pipeline pipe; 

VideoPlayer(final String playerType, final Element videosrc, final Element colorspace, final Element videofilter, final Element enc, final Element mux, final Element sink, final Pipeline pipe){ 
     this.playerType = playerType; 
     this.videosrc = videosrc; 
     this.colorspace = colorspace; 
     this.videofilter = videofilter; 
     this.enc = enc; 
     this.mux = mux; 
     this.sink = sink; 
     this.pipe = pipe; 
} 

public void run(){ 
    VideoComponent videoComponent = new VideoComponent(); 

    Element videosink = videoComponent.getElement(); 



    if(playerType.equals("screen")){ 

     System.out.println(playerType); 

     pipe.addMany(videosrc, videofilter, videosink); 

     Element.linkMany(videosrc, videofilter, videosink); 

     JFrame frame = new JFrame("Swing Video Test"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(videoComponent, BorderLayout.CENTER); 
     videoComponent.setPreferredSize(new Dimension(640, 480)); 
     frame.pack(); 
     frame.setVisible(true); 
     // Start the pipeline processing 

     pipe.setState(State.PLAYING); 
    } 

    else if(playerType.equals("recorder")){ 

     System.out.println(playerType); 


     pipe.addMany(videosrc, colorspace, videofilter, enc, mux, sink); 
     Element.linkMany(videosrc, colorspace, videofilter, enc, mux, sink);  

     JFrame frame = new JFrame("Swing Video Test"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(videoComponent, BorderLayout.CENTER); 
     videoComponent.setPreferredSize(new Dimension(640, 480)); 
     frame.pack(); 
     //frame.setVisible(true); 

     pipe.setState(State.PLAYING); 
    } 
} 

有點長,但很容易看到我正在嘗試做什麼。如果有人能告訴我如何實施T恤(我嘗試過?),那會很棒。謝謝!

回答

4

你不應該像你那樣創建兩個視頻源。 videosrc & videosrcB

基本上,您應該接收來自videosrc的數據並將其提供給GstTee現在Tee必須有兩個SrcPads。這將允許兩條路徑分開工作。

第一個src路徑應該連接到您的encmux這將繼續錄製第二條路徑將顯示在屏幕上。所有應該同時工作。

Tee可以在每個路徑中被Queue緩衝。從電路的角度來看,這不是必需的,但它是好的,所以#2路徑不會等到路徑#1在阻塞呼叫下完成。

這裏是電路的樣子。

Circuit

+0

我在哪裏放隊列? – 2012-02-14 13:04:25