question

DavidH-7160 avatar image
0 Votes"
DavidH-7160 asked ·

[UWP] Camera Preview while recording

Hello,

I'm attempting to work with video capture in a UWP app and am running across an issue when it comes to the preview of the video.

Everything works fine to preview, capture, play back a video if I don't resize the window. If recording is taking place when the visual state manager triggers a change in the layout of the control, my capture element loses the feed from the camera and I cannot get it back while recording. If simply previewing before recording, I can simply restart the preview from the MediaCapture object again as normal. The issue is really just losing the feed while recording if they resize the window.

The process that is being triggered is the parent Grid that contains the capture object is being removed from being the child of one grid and put into another when the screen becomes too small/large enough. I'm assuming the time it's detached from having a parent is why this occurs, but I'm not sure how to work around it. Simple setting the Source of the CaptureElement back to the MediaCapture does not work, and calling StartPreviewAsync() on the MediaCapture does not work while recording. Is there some other way I could go about handling this?

 Here's the code I'm using for this. First is the VisualStateManager that triggers the view change. This part is working perfectly. The grids show/hide and the WideViewLayout property on videoControl calls some other code below.
 
     // The visual state manager. Everything in here seems to be working fine.  Can't seem to figure out how to make XAML work here so the opening tags are removed so they show up. But it's basic Visual state manager code.
 
         VisualStateManager.VisualStateGroups
             VisualStateGroup
                 VisualState x:Name="WideLayout"
                     VisualState.StateTriggers
                         AdaptiveTrigger MinWindowWidth="1024" /
                     /VisualState.StateTriggers>
                     VisualState.Setters>
                         Setter Target="videoControl.WideViewLayout" Value="True" />
                         Setter Target="wideViewControl.Visibility" Value="Visible" />
                         Setter Target="narrowViewControl.Visibility" Value="Collapsed" />
                     /VisualState.Setters>
                 /VisualState>
             /VisualStateGroup>
         /VisualStateManager.VisualStateGroups>
 
    
     //The grid being moved from one parent grid to another during layout change.
     
                 Grid x:Name="videoCaptureGrid" Grid.Row="1">
                     Grid.RowDefinitions>
                         RowDefinition />
                         RowDefinition Height="Auto" />
                     Grid.RowDefinitions>
                     Viewbox VerticalAlignment="Top">
                         /Grid>
                             Canvas Grid.Row="1" x:Name="previewCanvas" Width="300" Height="220" Background="Black" HorizontalAlignment="Center" VerticalAlignment="Center">
                                 CaptureElement x:Name="previewElement" Width="300" Height="220" />
                             /Canvas>
                         
                     /Viewbox>
                     ComboBox Grid.Row="1" Background="Black" ItemsSource="{Binding DeviceInformationCollection}" BorderBrush="Black" FontSize="35" Margin="20,3,20,3" DisplayMemberPath="Name" 
                               IsEnabled="{Binding IsCameraOn, Converter={StaticResource boolNegationConverter}}" SelectedItem="{Binding SelectedVideoDevice, Mode=TwoWay}" />
                 /Grid>
 
 
     //The code moving the grid from one element to another. I think this is where the problem is with it losing the preview, but not sure of another approach to take.
 
     private void SetupWideViewMode()
         {
               narrowVideoElementGrid.Children.Remove(videoCaptureGrid);    
               wideViewControl.Children.Add(videoCaptureGrid);
             
               Grid.SetRow(videoCaptureGrid, 1);
               Grid.SetColumn(videoCaptureGrid, 0);
         }
 
 Please let me know if I can provide any other information.
 
 Thank you!
uwpuwp-xaml
· 2
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi, Can you show the code and trigger settings? This helps us reproduce your problem and solve it

0 Votes 0 · ·

I've revised the original post to contain the operational code. Thank you!

0 Votes 0 · ·

1 Answer

RichardZhang-MSFT avatar image
0 Votes"
RichardZhang-MSFT answered ·

Hello,​

Welcome to our Microsoft Q&A platform!

I reproduced your problem, the migration of controls on the visual tree may cause the disconnection of mediaCapture and previewElement.

So before the videoCaptureGrid migration, you need to stop the video preview.

Here are the variable and methods needed in the operation

 private bool isPreviewing = false;
 
 private async Task StartPreviewAsync()
 {
     try
     {
         mediaCapture = new MediaCapture();
         await mediaCapture.InitializeAsync();
     }
     catch (UnauthorizedAccessException)
     {
         return;
     }
 
     try
     {
         previewElement.Source = mediaCapture;
         await mediaCapture.StartPreviewAsync();
         isPreviewing = true;
     }
     catch (FileLoadException)
     {
         
     }
 }
 private async Task CleanupCameraAsync()
 {
     if (mediaCapture != null)
     {
         if (isPreviewing)
         {
             await mediaCapture.StopPreviewAsync();
         }
 
         await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
         {
             previewElement.Source = null;
             mediaCapture.Dispose();
             mediaCapture = null;
         });
     }
 
 }


Usage

 private async void SetupWideViewMode()
 {
     await CleanupCameraAsync();
     narrowVideoElementGrid.Children.Remove(videoCaptureGrid);
     wideViewControl.Children.Add(videoCaptureGrid);
 
     Grid.SetRow(videoCaptureGrid, 1);
     Grid.SetColumn(videoCaptureGrid, 0);
     await StartPreviewAsync();
 }

This will restart the preview after moving the Grid.

Thanks.

· 4 · Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Thank you for the reply. I have been able to fix the issue while previewing the camera feed, but the main issue if that this does not working while recording is taking place. It will throw an exception that restarting the preview is not valid while recording. It doesn't seem that there's a way to resume the preview without stopping recording.

It may not be a common use case to resize the window during recording, but I am trying to support as many scenarios as I can.

0 Votes 0 · ·

Hi,

In fact, if you only make UI adjustments on the current page, there is no need to remove previewElement, it can be adjusted through the UI. If you move it directly out of the visual tree, it will inevitably cause the interruption of the video streaming connection.

0 Votes 0 · ·

That is also the conclusion I came to about it. I could try and re-work the rest of the page so that the capture element is only moving positions in the grid and not moved as a child from one to another. This might keep it from getting interrupted, though I would still need to test it out.

At least I know I'm not missing something with not being able to restore the video feed. It seems not actually possible to do in this case.

Thanks for your help!

0 Votes 0 · ·
Show more comments