【问题标题】:How to load and display any video in my computer to a UWP (C++)如何将我计算机中的任何视频加载并显示到 UWP (C++)
【发布时间】:2018-11-10 14:58:34
【问题描述】:

我一直在尝试为我正在制作的 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.";
        }
    });

【问题讨论】:

  • “我尝试将文件复制到 LocalAppData 文件夹,因为我知道我有权访问那里的文件” - 嗯,如果您无权读取当前位置的文件,那么显然您也无法复制它(复制意味着从一个位置读取文件,然后将其写入其他位置)——这似乎毫无意义。
  • 确实毫无意义,但我对此很陌生,所以我尝试了我想出的每一个解决方案。
  • 如果您使用FileOpenPicker,那么您已经可以访问该StorageFile。您不需要复制它,当然也不需要broadFileSystemAccess 功能。您是否正在尝试解决其他问题?

标签: c++ visual-studio xaml uwp c++-cx


【解决方案1】:

使用 Windows 10 版本 1803、SDK build 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 文件夹中。此外,应用程序 Assets 文件夹是只读的,部署后不可写。您不能对您的应用代码进行任何更改,包括创建或复制文件到此文件夹。

您应该查看文档File access permissions 以获取有关文件访问的更多详细信息,并从官方FileAccess 代码示例中获取参考代码。

---更新以添加broadFileSystemAccess 功能---

首先,右击Package.appxmanifest文件,选择View Code,就可以看到manifest中的代码了。

其次,在顶部选项卡中,添加以下代码,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>

【讨论】:

  • BroadFileSystemAccess 似乎是我的最佳选择。 Use of BFSA 看这篇文章我看到我需要在我的 Package.appxmanifest 中放入一些代码。之后我还没有找到该怎么做。你知道这方面的任何文件吗?与您的上一个链接一样,没有任何使用这种新功能的示例。
  • @CarlosHernandezPerez 我在回复中添加了 Update 部分,以便将broadFileSystemAccess 功能添加到清单中,您可以参考它。
  • 这很有帮助,虽然我在添加 broadFileSystemAccess 功能时仍然收到一条错误消息,它显示“名称 smape 中的元素功能“http ...”在命名空间中有一个辅助元素“rescap命名空间完整 url”,这是无效的。
  • @CarlosHernandezPerez broadFileSystemAccess 功能是受限功能,当您添加一些受限功能时,Visual Studio 会在一些信息下划线以警告它,这不是错误,您可以像往常一样构建您的应用程序.受限功能可供开发人员在其应用程序中使用,但需要获得商店提交的批准。请参阅Restricted capabilities 了解更多信息。
  • 这不是错误,而是警告。这是任何有兴趣的人的解释。 [警告说明]:(developercommunity.visualstudio.com/content/problem/237538/…)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-09-25
  • 1970-01-01
  • 1970-01-01
  • 2022-09-29
  • 1970-01-01
  • 2016-06-17
  • 2015-11-19
相关资源
最近更新 更多