如何将我计算机中的任何视频加载并显示到 UWP (C++)

How to load and display any video in my computer to a UWP (C++)

我一直在尝试为我正在制作的 UWP 应用程序实现一项功能。我的 XAML 文档中声明了一个 MediaElement,如下所示:

<MediaElement x:Name="_media" AutoPlay="True" IsLooping="True" Margin="0,0,8,227" AreTransportControlsEnabled="true" RenderTransformOrigin="0.499,0.41" >
        <MediaElement.RenderTransform>
            <CompositeTransform ScaleX="1"/>
        </MediaElement.RenderTransform>
</MediaElement>

我需要能够从计算机中的任何位置加载视频,但 UWP 无法访问所有目录。我正在通过一个按钮(下面的代码)加载视频文件。长话短说,我尝试将文件复制到 LocalAppData 文件夹中,因为我知道我有权访问那里的文件。

第一个问题: 我可以按照我在下面的代码中使用它的方式通过 CopyFileA() 复制文件吗?

第二个问题 复制文件后,我需要将其添加到应用程序的 Assets 中。我怎样才能通过代码做到这一点?

这是我尝试加载文件时 运行 的代码。

void SDKTemplate::Scenario4_ReproVideo::Button_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
    //This lines are here to get the path of the local folder of my app
    Windows::Storage::StorageFolder^ f = Windows::Storage::ApplicationData::Current->LocalFolder;
    stdext::cvt::wstring_convert<std::codecvt_utf8<wchar_t>> convert_local_path;
    Platform::String^ path_ss = f->Path;
    txtBlockOutput->Text = path_ss;
    std::string path_local = convert_local_path.to_bytes(path_ss->Data());



    FileOpenPicker^ fop = ref new FileOpenPicker();
    fop->SuggestedStartLocation = PickerLocationId::Desktop;
    fop->FileTypeFilter->Append(".mp4");
    fop->FileTypeFilter->Append(".wmv");


    create_task(fop->PickSingleFileAsync()).then([this](StorageFile^ file) {
        if (file)
        {


            //We take the path of the file
            Platform::String^ path = file->Path;
            stdext::cvt::wstring_convert<std::codecvt_utf8<wchar_t>> convert_path;
            std::string sourcePath = convert_path.to_bytes(path->Data());

            //We take the name of the file
            Platform::String^ name = file->Name;
            stdext::cvt::wstring_convert<std::codecvt_utf8<wchar_t>> convert_name;
            std::string name_s = convert_name.to_bytes(name->Data());

            //We find out the local path (again) not sure if needed
            Platform::String^ path_ss = Windows::Storage::ApplicationData::Current->LocalFolder->Path;
            stdext::cvt::wstring_convert<std::codecvt_utf8<wchar_t>> convert_local_path;            
            std::string path_local = convert_local_path.to_bytes(path_ss->Data());

            // Use Path class to manipulate file and directory paths.
            std::string sourceFile = sourcePath +"/" + name_s;
            std::string destFile = path_local +"/"+ name_s;

            if (CopyFileA(sourceFile.c_str(), destFile.c_str(), FALSE)) {
                txtBlockOutput->Text = "File is copied into local directory";
            }
            else { txtBlockOutput->Text = "File didn't copy"; }



            _media->Source = ref new Uri(destFile);
        }
        else
        {
            txtBlockOutput->Text = "Operation cancelled.";
        }
    });

使用 windows 10 版本 1803,SDK 内部版本 17134,您可以使用 broadFileSystemAccess 功能访问用户有权访问的所有文件。

另一方面,您的应用有权访问本地 LocalAppData 位置,您可以使用 ms-appdata uri 直接访问该文件,

using Windows::Storage;
auto getFileTask = create_task(StorageFile::GetFileFromApplicationUriAsync(ref new Uri("ms-appdata:///local/file.txt")));
getFileTask.then([](StorageFile^ file) 
{
    // Process file
});

因此您无需将文件复制到应用程序的 Assets 文件夹中。此外,应用程序资产文件夹是只读的,一旦部署就不可写。您不能对您的应用程序代码进行任何更改,包括创建文件或将文件复制到此文件夹。

您应该查看文档 File access permissions to get more details about file access, and get the reference code from official FileAccess 代码示例。

---更新添加broadFileSystemAccess能力---

首先,右键单击Package.appxmanifest文件并select查看代码,您将能够在清单中看到代码。

其次,在顶部选项卡中,添加以下代码,xmlns:rescap="..."并将rescap放入IgnorableNamespaces值中,看起来像IgnorableNamespaces="uap mp rescap",它看起来喜欢,

<Package
  ...
  xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
  IgnorableNamespaces="uap mp rescap">

最后,在选项卡中添加broadFileSystemAccess能力,

<Capabilities>
    <rescap:Capability Name="broadFileSystemAccess" />
</Capabilities>