2017-04-18 32 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; 
}