cancel
Showing results for 
Search instead for 
Did you mean: 
yashag2255

Shoot Videos in PowerApps: Possible with a work-around!

In this article I will show you how to shoot a video in PowerApps. I will pass the data collected in a collection from a Camera control and a Microphone control from the canvas app to an Azure Storage blob via Flow. I will then use those to reference to an external API and finally create the video.

In one of my previous blog articles, I have shown how we can move the image and audio files from a canvas app to a document library using the JSON function and a Flow. I will be using that schema to move these files from the app and get back the URL of the video to stream on the canvas app.

This article focuses on a canvas app and a flow. We will look at the component wise structuring of both the app and the flow to achieve the objective.

Canvas App

Let’s look at the control wise screens and functions used in the Canvas App.

1. The "Camera" control is used to stream photos in the canvas app. The images are being collected on a local collection "ImagesCollection". We are also creating a column in the collection to store the names of these images based on the stream order. 

Expression used on the "OnStream" property of the Camera control: 

Collect(
    ImagesCollection,
    {
        Name: Concatenate(
            Text(
                CountRows(ImagesCollection) + 1,
                "[$-en-US]0000"
            ),
            ".jpg"
        ),
        Url: Camera1.Stream
    }
)

Explanation: This creates a local collection with two columns. The "Name" column contains a concatenated string as the name of the image. A text conversion is being done to appropriately name the image based on the order of the stream as the API requires the image names to be sorted in order to create the video according to the frames. The "URL" column stores the image content. 

A variable "streamvar" is used to set the stream rate of the "Camera" control to 100 (10 frames per second). This variable is set using the "Microphone" control on the canvas app. The variable is set to 0 on the "OnVisible" property of this screen. 

2. The Microphone control on the app is used to record audio. The audio is recorded in sync with the stream rate of the camera. When the audio recording is stopped, the camera stream rate is reset to 0. 

Expression used on the "OnStart" property of the "Microphone" control: 

Concurrent(
    Clear(ImagesCollection),
    Clear(AudioCollection),
    Set(
        streamvar, 100
    )
)

Explanation: Using the concurrent function we are clearing the "ImageCollection", "AudioCollection" collections and settting the "streamvar" stream rate of the "Camera" control. 

Expression used on the "OnStop" property of the "Microphone" control: 

Concurrent(
    Set(
        streamvar, 0
    ),
    ClearCollect(
        AudioCollection,
        Microphone1.Audio
    )
)

Explanation: Using the concurrent function, we are resetting the stream rate of the "Camera" control and collecting the audio file in the "AudioCollection" collection. 

Expression used on the "Submit" button: 

CreateVideo.Run(
    JSON(
        ImagesCollection,
        JSONFormat.IncludeBinaryData
    ),
    JSON(
        First(AudioCollection),
        JSONFormat.IncludeBinaryData
    )
);
Navigate('Display Videos')

Explanation: Here we are passing the images from the "ImageCollection" and the audio from the "AudioCollection" as variables to the "CreateVideo" Flow and executing it. The user is now navigated to the "Display Videos" screen where the videos are displayed on a "Gallery" control. Bv5.PNG

On the second screen, we have a "Gallery" control where the "Items" property is set to the "Videos List" on SharePoint. A refresh button is provided to refresh the data source when a new video is added to the list. 

We have a "Video Player" control that plays the video in reference to the selected item on the "Gallery".  Bv6.PNG

MS Flow

Trigger: Button from PowerApps

Action 1: Initialize a variable(1): String to store the URL of the blob created in Azure Storage. The address of the image/ audio/ video files will be appended along with this URL. 

Action 2: Initialize a variable(2): Array to store all the display names of steps created during the import of the images for the API execution to create the video. 

Action 3: Initialize a variable(3): String to store the audiofile generated from the Micophone control of the canvas app. 

Action 4: Parse JSON 2: Parses the keys and values from the audio file recieved as a string in the previous variable step.

Action 5: Create blob 2: To store the audio file as a blob on the azure storage account. 

Action 6: Initialize a variable(4): String to get the image data from the canvas app. 

Bv1.png

Action 7: Initialize a variable(5): Through this action we are creating the request body for creating the assembly using the API reference. This value will be later encoded using the compose action. 

Expression:

concat(variables('BlobUrl'),body('Create_blob_2')?['Path'])

Action 8: Parse JSON: To parse the data and extract the image data from the Variable 4. 

Action 9: Apply to Each control: To iterate over each image in the body of the Parse Json action. 

Action 10: Create Blob: Creating the image as a blob on Azure Storage account. 

Action 11: Append to String Variable: Through this action, we are creating the parameter for importing the image blob files created in azure storage in the previous step. This will be passed in the request body while creating the assembly using the API reference. 

Action 12: Append to Array Variable: The names of the image blob files created in the azure storage are put appended in the array variable to pass in the request body of the HTTP request. 

Action 13: Append to String Variable 2: In this we are appending the final request body to resize the images, merge them as a video and add the audio file to create the video and finally export the video file as blob to azure storage. 

Action 14: Compose: To encode the parameters being sent as the Request Body to the API reference. 

Expression used: 

encodeUriComponent(variables('ImageUrls'))

Bv2.png

Action 15: Send an HTTP Request: To create an assembly and pass the images, audio file as parameters in the form of encoded URL created in the compose action. 

Action 16: Parse JSON 3: To parse the response body of the HTTP request to get the id of the assembly created using the API reference. 

Action 17: Delay: A small delay for the assembly id to be generated and the assembly to executed. 

Action 18: Send an HTTP Request 2: To get the status/output response from the assembly that was created using the API in the Send HTTP request. 

Action 19: Parse JSON 4: To parse the response body from the HTTP Request 2 to get the URL of the newly created video file on the Azure storage. 

Action 20: Create Item: To create an item in the 'Videos' SharePoint List with the User as title and the URL of the newly created video (Azure Blob) on the 'VideoURL' column. 

Bv3.png

API Reference 

To create the video I have used the Transloadit API. The process followed here is:

1. Sign up for an account and this will generate an API key. This key will be further used for authenticating the API from Flow. 

2. Create the credentails for the Azure storage account by entering the storage account name, access key and the container name. 

3. Create an assembly to import the images, resize these images, import the audio file, merge the resized images and the audio file and then finally create and export the video. 

More details on generating video from image files using the Transloadit API: here!

In this article I have shown you a work around for recording videos using canvas apps. This might not be the most efficient way to do this and PowerApps might be working on launching the video control in the upcoming releases, but until then we have this work-around to create short videos/ GIF’s. Another school of thought that I want to showcase through this blog is the logic flow for creating work arounds with what is already available on the platform.

I hope you found this interesting and it helped you. Thank you for reading!

Comments