Mobile SDK for Windows Apps2.0
Transforming Windows apps into Mobile apps
native/capturevideo/capturevideo.cpp
// C++ Capture video example using Citrix Mobility Pack SDK
//
// Uses Citrix Mobility Pack SDK to take a video.
//
// Copyright (c) 2013 Citrix Systems
//


#include <stdio.h>
#include <windows.h>
#include <fstream>
#include <tchar.h>

// Citrix Mobility Pack include files
#include <cmp.h>

// Local functions
void ReportStatus(LPCSTR text, CMPRESULT rc);
CMPRESULT RegisterForEvent(HANDLE hCMP);
CMPRESULT CaptureVideo(HANDLE hCMP, const CMP_CAPTURE_VIDEO_OPTIONS *options, CMP_UNIQUE_LONG_ID *uniqueId);
void CMPCALL VideoCaptured(HANDLE hCMP, CMPRESULT result, CMP_UNIQUE_LONG_ID uniqueId, UTF8_STRING videoMetadata, UTF8_STRING filename, UINT32 videoSize, const CMP_CAPTURE_VIDEO_OPTIONS *options);
CMPRESULT RemoveCapturedData(HANDLE hCMP, CMP_UNIQUE_LONG_ID uniqueId);
void LoadFileLocally(UTF8_STRING clientFilename);

// Local structure
struct VIDEO_DATA
{
    CMPRESULT result;
    CMP_UNIQUE_LONG_ID uniqueId;
    UTF8_STRING videoMetadata;
    UTF8_STRING filename;
    UINT32 videoSize;
    const CMP_CAPTURE_VIDEO_OPTIONS *options;
};

// local variables
HANDLE hCaptureEvent = NULL; // local video event
VIDEO_DATA g_VideoData = { CMP_NO_ERROR, 0, NULL, NULL, 0, NULL }; // event data
CMP_UNIQUE_LONG_ID uniqueId;

int __cdecl main(int argc, char **argv)
{
    CMPRESULT rc;
    DWORD winrc;

    // create an event that is not manual reset with initial state set to non-signaled
    hCaptureEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    // initialize Citrix Mobility Pack for MultiThreadApartment(TRUE)
    rc = CMPInitialize(TRUE);

    ReportStatus("CMPInitialize", rc);

    if(CMP_SUCCESS(rc))
    {
        HANDLE hCMP;

        // open the Citrix Mobility Pack handle
        rc = CMPOpen(&hCMP);

        // report if failure
        ReportStatus("CMPOpen", rc);

        if(CMP_SUCCESS(rc))
        {
            // establish a connection between XenApp and Receiver (virtual channel)
            rc = CMPOpenSession(hCMP);

            // report if failure
            ReportStatus("CMPOpenSession", rc);

            if(CMP_SUCCESS(rc))
            {
                // register for the video capture event
                rc = RegisterForEvent(hCMP);

                if(CMP_SUCCESS(rc))
                {
                    CMP_CAPTURE_VIDEO_OPTIONS options;
                    memset(&options, 0, sizeof(CMP_CAPTURE_VIDEO_OPTIONS));
                    
                    options.Quality = CMP_CAPTURE_QUALITY_DEFAULT; //Video quality (low, medium, high, maximum, or default)
                    options.CameraSelection = CMP_CAPTURE_CAMERA_DEFAULT; //Camera selection (front, back or default)
                    options.Encoding = CMP_VIDEO_ENCODING_DEFAULT; //Encoding of data (MPEG4, H264, H263 or default)
                    options.DesiredWidth = 1024; //Desired pixel width (0 = no desired width)
                    options.DesiredHeight = 768; //Desired pixel height (0 = no desired height)
                    options.DurationLimit = 120; //Limit of time in seconds (0 = no limit)

                    //Request that a video be taken with the above options
                    rc = CaptureVideo(hCMP, &options, &uniqueId);

                    if(CMP_SUCCESS(rc))
                    {
                        DWORD waitTime = 60000;
                        printf("Waiting for the video to be taken within the next 60 seconds.\n");

                        while(waitTime > 0)
                        {
                            winrc = WaitForSingleObject(hCaptureEvent, 1000); //Wait for one second for the video to be captured

                            if(winrc == WAIT_OBJECT_0)
                            {
                                // Capture event caught within the time limit.
                                
                                // only process video if it is one of ours
                                if(uniqueId == g_VideoData.uniqueId)
                                {
                                    if(CMP_SUCCESS(g_VideoData.result))
                                    {
                                        //Show the capture data
                                        printf("CaptureVideo success\nresult(0x%X)\nid(0x%I64X)\nmetadata(%s)\nfilename(%s)\nvideoSize(%u)\n",
                                            g_VideoData.result, g_VideoData.uniqueId, g_VideoData.videoMetadata, g_VideoData.filename, g_VideoData.videoSize);

                                    } else {
                                        //User cancelled the capture
                                        ReportStatus("CaptureVideo event", g_VideoData.result);
                                    }
                                    break;
                                }
                            }
                            else
                            {
                                waitTime -= 1000;
                                printf("Waiting for capture... (%u)\n", waitTime/1000);
                            }
                        }
                    }
                }

                printf("\nCapture complete! Closing in 10 seconds...\n");
                Sleep(10000);

                rc = CMPCloseSession(hCMP);

                ReportStatus("CMPCloseSession", rc);

            }
        }

        rc = CMPClose(hCMP);

        ReportStatus("CMPClose", rc);

        rc = CMPUninitialize();

        ReportStatus("CMPUninitialize", rc);
    }

}

void ReportStatus(LPCSTR text, CMPRESULT rc)
{
    if(CMP_FAILURE(rc))
    {
        printf("%s CMPResult(%08X)\n", text, rc);
        switch (rc) {
            case CMP_ERROR_CLIENT_DRIVE_UNAVAILABLE: printf("Client Drive unavailable. Check session options on Receiver.\n"); break;
            case CMP_ERROR_CAPABILITY_NOT_SUPPORTED: printf("This device does not support video capture.\n"); break;
            case CMP_ERROR_CAPTURE_CANCEL: printf("Capture was cancelled by user.\n"); break;
        }
    }

    return;
}

// <summary>
// VideoCaptured event handler.
// </summary>
// <param name="hCMP">CMP handler.</param>
// <param name="result">Capture result.</param>
// <param name="uniqueId">Capture identifier.</param>
// <param name="videoMetadata">Capture metadata.</param>
// <param name="filename">Capture filename.</param>
// <param name="videoSize">Size of capture.</param>
// <param name="options">Capture options.</param>
void CMPCALL CapturedVideo(
    HANDLE hCMP, 
    CMPRESULT result, 
    CMP_UNIQUE_LONG_ID uniqueId,
    UTF8_STRING videoMetadata,
    UTF8_STRING filename,
    UINT32 videoSize,
    const CMP_CAPTURE_VIDEO_OPTIONS *options)
{
    printf("VideoCaptured event\n");

    memset(&g_VideoData, 0, sizeof(VIDEO_DATA));

    // Copy the relevant data and then signal the event
    g_VideoData.result = result;
    g_VideoData.uniqueId = uniqueId;

    if (CMP_SUCCESS(result)){
        g_VideoData.videoSize = videoSize;
        g_VideoData.options = options;
        if (videoMetadata)
            g_VideoData.videoMetadata = _strdup(videoMetadata);
        if (filename){
            g_VideoData.filename = _strdup(filename);
            LoadFileLocally(g_VideoData.filename);
        }
    }

    SetEvent(hCaptureEvent);
}

CMPRESULT RegisterForEvent(HANDLE hCMP)
{
    CMPRESULT rc;

    // Subscribe to VideoCaptured event.
    rc = CMPRegisterForEvent(hCMP, CMP_EVENT_VIDEO_CAPTURED, (CMP_EVENT_CALLBACK)CapturedVideo);

    // report if failure
    ReportStatus("CMPRegisterForEvent", rc);

    return(rc);
}

CMPRESULT CaptureVideo(HANDLE hCMP, const CMP_CAPTURE_VIDEO_OPTIONS *options, CMP_UNIQUE_LONG_ID *uniqueId)
{
    CMPRESULT rc;

    // Request that a video be taken.
    rc = CMPCaptureVideo(hCMP, options, uniqueId);

    // report if failure
    ReportStatus("CMPCaptureVideo", rc);

    return(rc);
}

CMPRESULT RemoveCapturedData(HANDLE hCMP, CMP_UNIQUE_LONG_ID uniqueId)
{
    CMPRESULT rc;

    // Request the video be removed.
    rc = CMPRemoveCapturedData(hCMP, uniqueId);

    ReportStatus("CMPRemoveCapturedData", rc);

    return(rc);
}

void LoadFileLocally (UTF8_STRING clientFilename)
{
    TCHAR tempPath[MAX_PATH];

    GetTempPath(MAX_PATH, tempPath);

    char filename [MAX_PATH];
    char ext [5];

    _splitpath_s(clientFilename, NULL, 0 , NULL, 0, filename, MAX_PATH, ext, 5);

    _tcscat_s(tempPath, filename); 
    _tcscat_s(tempPath, ext); 

    CopyFile(clientFilename, tempPath, false);
    ShellExecute(NULL, NULL, tempPath, NULL, NULL, SW_SHOW );
}
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Events Defines