opentok / opentok-windows-sdk-samples

Sample applications illustrating best practices using OpenTok Windows SDK
MIT License
9 stars 29 forks source link

Switch Publisher video between camera and static image #66

Open ntustzeus opened 8 months ago

ntustzeus commented 8 months ago

C#, WPF I'm asked to implement a button that can switch Publisher streaming between camera and static image.

In video conferences, some users prefer not to display their real-time video to others, so they want to show a static image instead.

Is it possible that I just upload a user selected image and show only image to others?

From the sample code, it seems I can just set PublishVideo to stop outputing streaming video.

Publisher = new Publisher.Builder(context) { Capturer = capturerDevices[0].CreateVideoCapturer(VideoCapturer.Resolution.High, VideoCapturer.FrameRate.Fps30), Renderer = PublisherVideo }.Build(); Publisher.PublishVideo = true;

sergioturgil-vonage commented 8 months ago

Yes, you can use "Publisher.PublishVideo = false" to stop publishing video (you can later set it to true to start publishing video again), however subscribers will just see an empty black screen for the publisher video feed, and not a selected image. If you want to send a preselected image as your video feed instead of the video captured from your camera you need to implement a custom "IVideoCapturer" and use that when creating the publisher instead of the one created with CreateVideoCapturer.

I'll see about adding a sample to do this. Currently the closest sample I can see is the one for "ScreenSharing" although in this case an IVideoCapturer is created that captures the screen instead of a preselected fixed image.

ntustzeus commented 8 months ago

Thanks for the replay. From the sample code of ScreenSharing, I found the following:

` Capturer = new ScreenSharingCapturer();

        // We create the publisher here to show the preview when application starts
        // Please note that the PublisherVideo component is added in the xaml file
        Publisher = new Publisher.Builder(Context.Instance)
        {
            Renderer = PublisherVideo,
            Capturer = Capturer,
            HasAudioTrack = false
        }.Build();

        // We set the video source type to screen to disable the downscaling of the video
        // in low bandwidth situations, instead the frames per second will drop.
        Publisher.VideoSourceType = VideoSourceType.Screen;

`

It doesn't use IVideoCapturer to create the Capturer. Could you give me some snippet about create IVideoCapturer and set Image as source?

If I want to switch Capturer source, can I just reset Capturer to Capturer = capturerDevices[0].CreateVideoCapturer(VideoCapturer.Resolution.High, VideoCapturer.FrameRate.Fps30), and Capturer = (Instance of IVideoCapturer),

sergioturgil-vonage commented 8 months ago

Thanks for the replay. From the sample code of ScreenSharing, I found the following:

` Capturer = new ScreenSharingCapturer();

        // We create the publisher here to show the preview when application starts
        // Please note that the PublisherVideo component is added in the xaml file
        Publisher = new Publisher.Builder(Context.Instance)
        {
            Renderer = PublisherVideo,
            Capturer = Capturer,
            HasAudioTrack = false
        }.Build();

        // We set the video source type to screen to disable the downscaling of the video
        // in low bandwidth situations, instead the frames per second will drop.
        Publisher.VideoSourceType = VideoSourceType.Screen;

`

It doesn't use IVideoCapturer to create the Capturer. Could you give me some snippet about create IVideoCapturer and set Image as source?

If I want to switch Capturer source, can I just reset Capturer to Capturer = capturerDevices[0].CreateVideoCapturer(VideoCapturer.Resolution.High, VideoCapturer.FrameRate.Fps30), and Capturer = (Instance of IVideoCapturer),

If you're talking about the ScreenSharing capturer, it does implement IVideoCapturer. The Capturer property is set to a capturer created a few lines before with: Capturer = new ScreenSharingCapturer(); If you look for ScreenSharingCapturer file, you'll see it implements IVideoCapturer.

This screensharing capturer is bit more complicated than what you require because it makes live captures of the screen. For your use case you would only need to read the fixed image once and use that inside the loop when periodically invoking frameConsumer.Consume(frame)

I'll try to save some time to provide a sample