【问题标题】:Stream video with bitmap as overlay使用位图作为叠加流式传输视频
【发布时间】:2018-08-07 15:33:52
【问题描述】:

我是 wowza 的新手,目前正在开展一个项目,以直播从 Android 设备捕获的视频。我需要将图像(动态图像)附加到视频流中,以便观看流的用户可以查看它。我尝试过的代码如下(来自 wowza 的示例源代码):

        // Read in a PNG file from the app resources as a bitmap
        Bitmap overlayBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.overlay_logo);

        // Initialize a bitmap renderer with the bitmap
        mWZBitmap = new WZBitmap(overlayBitmap);

        // Place the bitmap at top left of the display
        mWZBitmap.setPosition(WZBitmap.LEFT, WZBitmap.TOP);

        // Scale the bitmap initially to 75% of the display surface width
        mWZBitmap.setScale(0.75f, WZBitmap.SURFACE_WIDTH);

        // Register the bitmap renderer with the GoCoder camera preview view as a frame listener
        mWZCameraView.registerFrameRenderer(mWZBitmap);

这很好,但我不想在广播端显示图像,图像应该只在接收端可见。有什么办法可以完成吗?

【问题讨论】:

  • registerFrameRenderer 仅用于移动设备上的相机预览。您需要创建自己的 WZCameraView 使用 onDraw 方法来获得所需的输出。
  • @ImtiyazKhalani 感谢您的回复。我会试试这个。但是只是想确认一下,这样会不会也显示在CameraView上绘制的内容呢?问题是我不想在广播端显示内容,而是想向接收者显示。使用我尝试的当前实现,它在接收端和广播端都是可见的。
  • 如果你能好好学习WZCameraView,相信你会找到答案的。

标签: android ios wowza


【解决方案1】:

我设法通过注册FrameRenderer 并在onWZVideoFrameRendererDraw 中设置位图来完成这项工作。

代码 sn-p 如下(Kotlin):

private fun attachImageToBroadcast(scoreValue: ScoreUpdate) {
    bitmap = getBitMap(scoreValue)
    // Initialize a bitmap renderer with the bitmap
    mWZBitmap = WZBitmap(bitmap)
    // Position the bitmap in the display
    mWZBitmap!!.setPosition(WZBitmap.LEFT, WZBitmap.TOP)
    // Scale the bitmap initially
    mWZBitmap!!.setScale(0.37f, WZBitmap.FRAME_WIDTH)
    mWZBitmap!!.isVisible = false // as i dont want to show it initially
    mWZCameraView!!.registerFrameRenderer(mWZBitmap)
    mWZCameraView!!.registerFrameRenderer(VideoFrameRenderer())
}

private inner class VideoFrameRenderer : WZRenderAPI.VideoFrameRenderer {
    override fun onWZVideoFrameRendererRelease(p0: WZGLES.EglEnv?) {
    }

    override fun onWZVideoFrameRendererDraw(p0: WZGLES.EglEnv?, framSize: WZSize?, p2: Int) {
            mWZBitmap!!.setBitmap(bitmap) // note that the bitmap value gets changed once I get the new values
                                          //I have implemented some flags and conditions to check whether a new value has been obtained and only if these values are satisfied, the setBitmap is called. Otherwise, as it is called continuously, flickering can occur in the screen
            }


    override fun isWZVideoFrameRendererActive(): Boolean {
        return true
    }

    override fun onWZVideoFrameRendererInit(p0: WZGLES.EglEnv?) {
    }

}

在 iOS 中,我们可以实现 WZVideoSink 协议来实现这一点。 首先,我们需要将 scoreView 更新为最新的分数,然后将视图转换为图像。 然后我们可以使用 WZVideoSink 协议方法将此图像嵌入到捕获的帧中。 下面给出一个示例代码。

 // MARK: - WZVideoSink Protocol
func videoFrameWasCaptured(_ imageBuffer: CVImageBuffer, framePresentationTime: CMTime, frameDuration: CMTime) {

        if self.goCoder != nil && self.goCoder!.isStreaming {
           let frameImage = CIImage(cvImageBuffer: imageBuffer)
            var addCIImage: CIImage = CIImage()

            if let scoreImage = self.getViewAsImage() {
 // scoreImage is the image you want to embed.
                addCIImage = CIImage(cgImage: scoreImage.cgImage!)
            }

            let filter = CIFilter(name: "CISourceOverCompositing")
            filter?.setDefaults()
            filter?.setValue(addCIImage, forKey: kCIInputImageKey)
            filter?.setValue(frameImage, forKey: kCIInputBackgroundImageKey)

            if let outputImage: CIImage = filter?.value(forKey: kCIOutputImageKey) as? CIImage {
                let context = CIContext(options: nil)
                context.render(outputImage, to: imageBuffer)
            } else {
                let context = CIContext(options: nil)
                context.render(frameImage, to: imageBuffer)
            }
        }
}

func getViewAsImage() -> UIImage {
// convert scoreView to image
    UIGraphicsBeginImageContextWithOptions(self.scoreView.bounds.size, false, 0.0)
    self.scoreView.layer.render(in: UIGraphicsGetCurrentContext()!)

    let scoreImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    return scoreImage
}

【讨论】:

    猜你喜欢
    • 2019-01-16
    • 2011-11-30
    • 2016-09-24
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    相关资源
    最近更新 更多