locked
Strange windowing when using MediaCapture's setPreviewRotation (and setRecordRotation)

    Question

  • I'm trying to rotate the video being previewed (and recorded) using MediaCapture. I've used the methods shown here and they do rotate the video.  However, despite my video element being full-screen, the video displayed within the element is tiny.  It seems to be using the original width and height constraints of the unrotated (sideways) video.  I've included some screenshots to show what I mean.

    1.  Untouched video (no rotation) showing raw video going to video element with 100% width and height style settings. You can see that it stretches to fill the width and has black bars on top and bottom.  This is expected.

    2.  This is taken with setRecordRotation(Windows.Media.Capture.VideoRotation.clockwise270Degrees) applied.  Nothing else is changed.

    This happens on both my Lumia 820 and Lumia 920.  It seems like the video with the rotation applied is being forced into the constraints of the original video's width and height.

    What's going on here?

    *edit* You can easily replicate this by downloading the sample MS project:
    https://code.msdn.microsoft.com/windowsapps/Simple-Communication-Sample-eac73290

    I edited the CaptureManager.js file and changed a few lines in the _initializeAsync function from this:

    this._mediaCapture = new Windows.Media.Capture.MediaCapture();
                this._mediaCapture.addEventListener(CaptureDevice.failedEvent, this._captureFailedHandler);
    
                var that = this;
                return this._mediaCapture.initializeAsync().then(null, function (e)
                {
                    that._doCleanup();
                    throw e;
                });

    to this:

                this._mediaCapture = new Windows.Media.Capture.MediaCapture();
                this._mediaCapture.addEventListener(CaptureDevice.failedEvent, this._captureFailedHandler);
    
                var that = this;
                return this._mediaCapture.initializeAsync().then(function () {
                    return that._mediaCapture.setPreviewRotation(Windows.Media.Capture.VideoRotation.clockwise270Degrees);
                    }).then(null, function (e)
                {
                    that._doCleanup();
                    throw e;
                });
    Now just put the video element somewhere you can see it stretch and voila.


    Lee McPherson


    • Edited by Lee McPherson Wednesday, February 4, 2015 4:50 AM how to replicate
    Wednesday, February 4, 2015 4:46 AM

Answers

  • I have a workaround but it's really not ideal. Do not do the MediaCapture rotation.  Instead, use CSS to do a transform on the video element for both rotation and scale.

    video {
        height:100%;
        width:100%;
        transform: rotate(-90deg) scale(1.5);
    }

    Two reasons why this sucks:

    1.  You have to listen for the orientationChanged event and change your rotation based on them.  This creates animation problems between the views.

    2. The scale value will have to be calculated using the ratio calculated from either the preview encoding properties' height and width or record encoding properties' height and width.   (I'm using TypeScript below... not plain JavaScript)

    this._defaultPreviewProperties = <Windows.Media.MediaProperties.VideoEncodingProperties>this._captureDevice.videoDeviceController.getMediaStreamProperties(Windows.Media.Capture.MediaStreamType.videoPreview);

    this._defaultRecordProperties = <Windows.Media.MediaProperties.VideoEncodingProperties>this._captureDevice.videoDeviceController.getMediaStreamProperties(Windows.Media.Capture.MediaStreamType.videoRecord);



    Lee McPherson

    • Marked as answer by Lee McPherson Sunday, February 8, 2015 7:58 PM
    Wednesday, February 4, 2015 8:44 PM
  • Hello Lee,

    I think this is a known issue with the Video element. Unfortunately I can't verify this for you at this time. Your workaround sounds sound. For the time being I would recommend you go this route.

    Thanks,

    James


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

    • Marked as answer by Lee McPherson Sunday, February 8, 2015 7:58 PM
    Wednesday, February 4, 2015 11:16 PM
    Moderator

All replies

  • I have a workaround but it's really not ideal. Do not do the MediaCapture rotation.  Instead, use CSS to do a transform on the video element for both rotation and scale.

    video {
        height:100%;
        width:100%;
        transform: rotate(-90deg) scale(1.5);
    }

    Two reasons why this sucks:

    1.  You have to listen for the orientationChanged event and change your rotation based on them.  This creates animation problems between the views.

    2. The scale value will have to be calculated using the ratio calculated from either the preview encoding properties' height and width or record encoding properties' height and width.   (I'm using TypeScript below... not plain JavaScript)

    this._defaultPreviewProperties = <Windows.Media.MediaProperties.VideoEncodingProperties>this._captureDevice.videoDeviceController.getMediaStreamProperties(Windows.Media.Capture.MediaStreamType.videoPreview);

    this._defaultRecordProperties = <Windows.Media.MediaProperties.VideoEncodingProperties>this._captureDevice.videoDeviceController.getMediaStreamProperties(Windows.Media.Capture.MediaStreamType.videoRecord);



    Lee McPherson

    • Marked as answer by Lee McPherson Sunday, February 8, 2015 7:58 PM
    Wednesday, February 4, 2015 8:44 PM
  • Hello Lee,

    I think this is a known issue with the Video element. Unfortunately I can't verify this for you at this time. Your workaround sounds sound. For the time being I would recommend you go this route.

    Thanks,

    James


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

    • Marked as answer by Lee McPherson Sunday, February 8, 2015 7:58 PM
    Wednesday, February 4, 2015 11:16 PM
    Moderator
  • Thanks for confirming this.  The workaround is fine for now.

    Lee McPherson

    Wednesday, February 4, 2015 11:49 PM