0

我在页面上有一个按钮,按钮的单击事件具有以下方法:

StorageFile _sourceFile;    
private string _sourceToken;
private async void btnSelect_Click(object sender, RoutedEventArgs e)
{
    FileOpenPicker fop = new FileOpenPicker();
    fop.FileTypeFilter.Add(".mp4");

    StorageFile inFile = await fop.PickSingleFileAsync();
    _sourceToken = Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.Add(inFile);

    _sourceFile = await Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList.GetFileAsync(_sourceToken);
    mediaElement.AutoPlay = false;
    IRandomAccessStream stream = await _outFile.OpenAsync(FileAccessMode.ReadWrite);
    mediaElement.SetSource(stream, _outFile.ContentType);

}

如果我在 MediaElement 上单击播放,我选择的视频可以正常播放。

我还有另一个按钮,在其点击事件中有以下代码:

private async void btnExport_Click(object sender, RoutedEventArgs e)
{
    StorageFile outFile = await KnownFolders.VideosLibrary.CreateFileAsync("Outfie.mp4", CreationCollisionOption.ReplaceExisting);

    MediaEncodingProfile profile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD1080p);

    MediaTranscoder transcoder = new MediaTranscoder();

    PrepareTranscodeResult prepareOp = await transcoder.PrepareFileTranscodeAsync(_sourceFile, outFile, profile);

    if (prepareOp.CanTranscode)
    {
        var transcodeOp = prepareOp.TranscodeAsync();

        transcodeOp.Progress += new AsyncActionProgressHandler<double>(TranscodeProgress);
        transcodeOp.Completed += new AsyncActionWithProgressCompletedHandler<double>(TranscodeComplete);
    }
    else
    {
        switch (prepareOp.FailureReason)
        {
            case TranscodeFailureReason.CodecNotFound:
                System.Diagnostics.Debug.WriteLine("Codec not found.");
                break;
            case TranscodeFailureReason.InvalidProfile:
                System.Diagnostics.Debug.WriteLine("Invalid profile.");
                break;
            default:
                System.Diagnostics.Debug.WriteLine("Unknown failure.");
                break;
        }
    }
}

不幸的是,transcoder.PrepareFileTranscodeAsync 行抛出了 UnauthorizedAccessException。但是,如果我使用以下内容而不是 _sourceFile 它可以工作:

StorageFile sourceFile = await KnownFolders.VideosLibrary.GetFileAsync("sourceFile.mp4");

抛出的错误是:

System.UnauthorizedAccessException: '访问被拒绝。(来自 HRESULT 的异常:0x80070005 (E_ACCESSDENIED))'

需要明确的是,我选择的是 KnownFolders 枚举之外的文件,因此我使用的是 Windows.Storage.AccessCache.StorageApplicationPermissions.FutureAccessList。

谁能解释为什么?

编辑:如果我将源文件更改为 FileOpenPicker 的结果,那么它可以工作。所以它引出了一个问题,为什么 FutureAccessList 不起作用?

private async void btnExport_Click(object sender, RoutedEventArgs e)
{
    StorageFile outFile = await KnownFolders.VideosLibrary.CreateFileAsync("Outfie.mp4", CreationCollisionOption.ReplaceExisting);

    FileOpenPicker fop = new FileOpenPicker();
    fop.SuggestedStartLocation = PickerLocationId.ComputerFolder;
    fop.FileTypeFilter.Add(".mp4");

    StorageFile sourceFile = await fop.PickSingleFileAsync();

    MediaEncodingProfile profile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD1080p);

    MediaTranscoder transcoder = new MediaTranscoder();

    PrepareTranscodeResult prepareOp = await transcoder.PrepareFileTranscodeAsync(sourceFile, outFile, profile);

    if (prepareOp.CanTranscode)
    {
        var transcodeOp = prepareOp.TranscodeAsync();

        transcodeOp.Progress += new AsyncActionProgressHandler<double>(TranscodeProgress);
        transcodeOp.Completed += new AsyncActionWithProgressCompletedHandler<double>(TranscodeComplete);
    }
    else
    {
        switch (prepareOp.FailureReason)
        {
            case TranscodeFailureReason.CodecNotFound:
                System.Diagnostics.Debug.WriteLine("Codec not found.");
                break;
            case TranscodeFailureReason.InvalidProfile:
                System.Diagnostics.Debug.WriteLine("Invalid profile.");
                break;
            default:
                System.Diagnostics.Debug.WriteLine("Unknown failure.");
                break;
        }
    }
}
4

2 回答 2

1

您是否有权访问要写入的文件?也许它是只读的或由您以外的其他用户创建?(在资源管理器中的文件上单击鼠标右键 + 属性应该可以让您更清楚地了解文件权限)

此外,如果您尝试写入您无权访问的文件夹,您可能会遇到该异常。

检查您的凭据,我猜这与此有关。

于 2017-04-23T11:26:28.437 回答
1

所以看来我是在读写模式下打开源文件的

IRandomAccessStream stream = await _outFile.OpenAsync(FileAccessMode.ReadWrite);

是问题的原因。根据这个页面

仅当您准备好立即写入时才使用读/写模式,以避免与其他操作发生冲突。

所以我改成了这个,一切正常

IRandomAccessStream stream = await _outFile.OpenAsync(FileAccessMode.Read);
于 2017-04-24T02:35:23.680 回答