2017-04-18 15 views
0

Javaで書かれたrtspプレーヤーアプリケーションがあり、gstreamerの上に構築されています1.パイプラインのtextoverlay要素が1つしかない再生ビデオの上にテキストを表示しようとするとそれはうまくいきます。しかし、私はウィンドウのすべてのコーナーに異なるテキストを表示する必要があります。2つのtextoverlay要素をリンクするJava gstreamerが機能しない

最初は、gst-launch-1.0でコマンドラインから実際に働いていたオーバーレイ要素を連鎖していたと思います。

gst-launch-1.0 -v rtspsrc location=rtsp://10.0.5.41:8554 ! rtpjitterbuffer ! rtph264depay ! vaapiparse_h264 ! vaapidecodebin ! textoverlay text = "live video" halignment=left ! textoverlay text="action camera 1" ! xvimagesink 

次のようにjavaを使用して同じパイプラインを構築しようとします。

this.sourceElement = ElementFactory.make(RTSP_SOURCE, RTSP_SOURCE); 
    final Element videoQueue = ElementFactory.make(QUEUE, QUEUE); 
    final Element videoDepay = ElementFactory.make(RTP_H264_DEPAY, RTP_H264_DEPAY); 
    final Element videoParser = ElementFactory.make(VAAPI_H264_PARSE, VAAPI_H264_PARSE); 
    final Element videoDecoder = ElementFactory.make(VAAPI_DECODE, VAAPI_DECODE); 
    videoTypeOverlay = ElementFactory.make(TEXT_OVERLAY, TEXT_OVERLAY); 
    videoSourceOverlay = ElementFactory.make(TEXT_OVERLAY, TEXT_OVERLAY); 
    sinkElement = ElementFactory.make(XV_IMAGE_SINK, XV_IMAGE_SINK); 

    pipe.addMany(sourceElement, videoQueue, videoDepay, videoParser, videoDecoder, videoSourceOverlay, videoTypeOverlay, sinkElement); 
    Element.linkMany(videoQueue, videoDepay, videoParser, videoDecoder, videoSourceOverlay, videoTypeOverlay, sinkElement); 

     sourceElement.connect((Element.PAD_ADDED) (element, pad) -> { 
     if (pad.isLinked()) { 
      return; 
     } 
     Caps caps = pad.getCaps(); 
     if (caps.size() > 0) { 
      String mediaType = caps.getStructure(0).getString("media"); 
      if ("video".equalsIgnoreCase(mediaType)) { 
       pad.link(videoQueue.getStaticPad("sink")); 
      } 
     } 
    }); 

@Override 
     public void play(PlaySettings playSettings) { 
      videoTimeOverlay.set("text", text); 
      videoTimeOverlay.set("valignment", valign); 
      videoTimeOverlay.set("halignment", halign); 
      ... 
    } 

私は空白のキャンバスを取得します。 アプリケーションを少なくとも動作させる唯一の方法は、linkManyおよびaddMany行からオーバーレイの1つを次のように削除することです。

pipe.addMany(sourceElement, videoQueue, videoDepay, videoParser, videoDecoder, videoSourceOverlay, sinkElement); 
Element.linkMany(videoQueue, videoDepay, videoParser, videoDecoder, videoSourceOverlay, sinkElement); 

どのようにビデオキャンバスに複数の静的オーバーレイ文字列を配置できますか?

答えて

1

私はBin要素を作成し、2つのオーバーレイ要素をラップしてこの問題を解決しました。 以下のメソッドは、ゴーストパッドを使用してBinコンテナエレメントを作成するための作業コードの例です。

private Bin createTextOverlayBin() { 
    Bin textOverlayBin = new Bin(); 
    videoTypeOverlay = ElementFactory.make(TEXT_OVERLAY, "video-type-overlay"); 

    Optional<Pad> textOverlaySinkPad = playIdOverlay.getSinkPads().stream().filter(pad -> pad.getName().equals("video_sink")).findAny(); 
    Optional<Pad> textOverlaySrcPad = videoTypeOverlay.getSrcPads().stream().filter(pad -> pad.getName().equals("src")).findAny(); 

    if (textOverlaySinkPad.isPresent() && textOverlaySrcPad.isPresent()) { 
     textOverlayBin.add(playIdOverlay); 
     textOverlayBin.add(videoTypeOverlay); 

     GhostPad ghostSinkPad = new GhostPad("sink", textOverlaySinkPad.get()); 
     textOverlayBin.addPad(ghostSinkPad); 

     GhostPad ghostSrcPad = new GhostPad("src", textOverlaySrcPad.get()); 
     textOverlayBin.addPad(ghostSrcPad); 


     playIdOverlay.link(videoTypeOverlay); 
    } else { 
     LOGGER.error("Video text overlay element creation is failed!"); 
    } 
    return textOverlayBin; 
} 
関連する問題