2017-04-18 40 views
0

我有一個用java編寫的rtsp播放器應用程序,它構建在gstreamer之上1.當我嘗試在流水線中只有一個textoverlay元素時在播放視頻的頂部顯示文本它工作正常。但我需要在窗口的所有角落顯示不同的文本。連接兩個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行刪除其中一個覆蓋圖,如下所示:

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

那麼如何在視頻畫布上放置多個靜態疊加字符串?

回答

1

我通過創建Bin元素解決了這個問題,並且將兩個疊加元素包裹在其中。 下面的方法是一個工作代碼示例,用於創建帶有鬼點的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; 
}