Due to the way the local clips are stored on disk, local clips are not directly accessible as file objects. Given that the clips will be uploaded to the cloud eventually, this should not be a problem for most playback scenarios.
The example below demonstrates how to copy a clip to a file using GetLocalClipStreamAsync.
In the snippet below, OnStopRecordAsyncCompletion is the completion handler for StopRecordAsync and filePath is where the video will be saved.
void Game::OnGetLocalStreamAsyncCompletion(IAsyncOperation<Streams::IRandomAccessStream^>^ asyncOp
, AsyncStatus status)
{
if (status == AsyncStatus::Completed)
{
auto stream = asyncOp->GetResults();
if (stream != nullptr)
{
concurrency::create_task([stream]
{
auto size = stream->Size;
HANDLE hFile = CreateFile(filePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS
, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
DebugTrace(L"Cannot open output file to stream to\n");
}
else
{
while (0 < size)
{
auto buffer = ref new Streams::Buffer(1000);
ComPtr<Streams::IBufferByteAccess> pBufferByteAccess;
auto task = concurrency::create_ task(stream->ReadAsync(buffer
, min(static_ cast<unsigned int>(size)
, buffer->Capacity), Streams::InputStreamOptions::None));
task.wait();
auto result = task.get();
ComPtr<IUnknown> pBuffer((IUnknown*)result);
byte* byteBuffer;
pBuffer.As(&pBufferByteAccess);
pBufferByteAccess->Buffer(&byteBuffer);
WriteFile(hFile, byteBuffer, result->Length, NULL, NULL);
size -= result->Length;
}
CloseHandle(hFile);
});
}
}
}
}
void Game::OnStopRecordAsyncCompletion(IAsyncOperation<ApplicationClip^>^ asyncOp, AsyncStatus status)
{
if (status == AsyncStatus::Completed)
{
ApplicationClip^ result = asyncOp->GetResults();
auto operation = result->GetLocalClipStreamAsync();
if (operation != nullptr)
{
operation->Completed =
ref new AsyncOperationCompletedHandler<Streams::IRandomAccessStream^>( this
, &Game::OnGetLocalStreamAsyncCompletion);
}
}
}