locked
How to detect MediaCapture is closed?

    Question

  • MediaCapture.StopPreviewAsync() occasionally generates the following System.ObjectDisposedException:

    "The object has been closed".

    Is there a way to detect whether a MediaCapture is closed?


    Hong


    Friday, October 31, 2014 1:46 PM

Answers

  • Hello Hong,

    I don't think the MediaCapture is getting closed. The error indicates that the GC has collected the object and that it no longer exists. It sounds like your MediaCapture object is going out of scope somewhere in your app causing the error that you are seeing. Make sure your object stays in scope.

    I hope this helps,

    James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    • Marked as answer by Hong (MA, USA) Saturday, November 01, 2014 7:46 PM
    Friday, October 31, 2014 8:22 PM
    Moderator

All replies

  • Hello Hong,

    I don't think the MediaCapture is getting closed. The error indicates that the GC has collected the object and that it no longer exists. It sounds like your MediaCapture object is going out of scope somewhere in your app causing the error that you are seeing. Make sure your object stays in scope.

    I hope this helps,

    James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    • Marked as answer by Hong (MA, USA) Saturday, November 01, 2014 7:46 PM
    Friday, October 31, 2014 8:22 PM
    Moderator
  • Thanks a lot for the tip, James.  It seem to explain everything.

    This happens when the app is sent to the background, but before it is suspended.  There is another related thread.  

    Is catching an exception the only way to detect an object has been collected by GC?  The object is not null.


    Hong


    Saturday, November 01, 2014 2:45 AM
  • Try to organise your code better, you got two equals signs on the same line and your code is not well formated so it's hard to read.

    To use Camera in Windows 8.1 stop app I use this code :

    // First need to find all webcams
    DeviceInformationCollection webcamList = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture)
    
    // Then I do a query to find the front webcam
    DeviceInformation frontWebcam = (from webcam in webcamList
     where webcam.EnclosureLocation != null 
     && webcam.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Front
     select webcam).FirstOrDefault();
    
    // Same for the back webcam
    DeviceInformation backWebcam = (from webcam in webcamList
     where webcam.EnclosureLocation != null 
     && webcam.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back
     select webcam).FirstOrDefault();
    
    // Then you need to initialize your MediaCapture
    var captureManager = new MediaCapture();
    await captureManager.InitializeAsync(new MediaCaptureInitializationSettings
    {
        // Choose the webcam you want (backWebcam or frontWebcam)
        VideoDeviceId = backWebcam.Id,
        AudioDeviceId = "",
        StreamingCaptureMode = StreamingCaptureMode.Video,
        PhotoCaptureSource = PhotoCaptureSource.VideoPreview
    });
    
    // Set the source of the CaptureElement to your MediaCapture
    capturePreview1.Source = captureManager;
    
    // Start the preview
    await captureManager.StartPreviewAsync();

    This way it's easier to read. The code is not very different, MediaCaptureInitializationSettings is not the same.

    This code works for me on Surface 2 RT and Nokia 635 so it should work for you.

    Edit:

    Seems it works on devices with Windows RT but on full windows 8.1 devices it's always null. Msdn says that:

    If no enclosure location information is available, the property will be null

    so what you can do is first try to see if you find a backwebcam and if it's null take the last one;

    DeviceInformation backWebcam = (from webcam in webcamList
     where webcam.EnclosureLocation != null 
     && webcam.EnclosureLocation.Panel == Windows.Devices.Enumeration.Panel.Back
     select webcam).FirstOrDefault();
    
    if (backWebcam == null)
    {
       backWebcam = webcamList.Last();
    }

    But you are not sure the last one in the collection is the back one, so you should add a button to let the user switch camera

    If you change camera,

    await captureManager.StopPreviewAsync();
    
    await captureManager.InitializeAsync(new MediaCaptureInitializationSettings
        {
            // Choose an other webcam 
            VideoDeviceId = //id of the new webcam,
            AudioDeviceId = "",
            StreamingCaptureMode = StreamingCaptureMode.Video,
            PhotoCaptureSource = PhotoCaptureSource.VideoPreview
        });
    
     await captureManager.StartPreviewAsync();

    this way you can be sure the user can choose the right camera even is you programmaticaly cannot tell which one is which

    Monday, November 03, 2014 7:23 AM
  • Thank you for the suggestion, EngSoonCheah.

    Could you let me know which code you were referring to?  I have not posted any code for this thread.  I have just checked my recent posts, but have not found any code.  


    Hong

    Monday, November 03, 2014 11:54 AM