MediaElement Source 無法在 SaveState/LoadState 之後設定

本文关键字:LoadState SaveState Source MediaElement | 更新日期: 2023-09-27 18:35:33

注意:所有代码都经过了严重简化。

问题

挂起/恢复后未设置媒体元素源。设置源后,当前状态会迅速更改为"已关闭"。

我正在处理 MediaFailed 事件 — 它不会触发。我还在处理 MediaOpen 事件,该事件也不会触发。

我有以下方法可以更新媒体元素的源。只要应用程序在被暂停后尝试恢复,它就运行良好。

  private async void UpdateMediaElementSource(object sender, EventArgs e)
  {
     var videoSource = this.DefaultViewModel.CurrentSource; // a string
     var file = await StorageFile.GetFileFromPathAsync(videoSource);
     var videoStream = await file.OpenAsync(FileAccessMode.Read);
     this.videoMediaElement.SetSource(videoStream, file.ContentType);
     // The above line works many times as long as the app is not trying to Resume.
  }

当应用挂起时,它会调用 SaveState 方法:

  protected async override void SaveState(Dictionary<String, Object> pageState)
  {
     pageState["MediaElementSource"] = this.DefaultViewModel.CurrentSource;
     // I also made the videoStream global so I can dispose it — but no dice.
     this.videoStream.Dispose();
     this.videoStream = null;
  }

当应用恢复时,它会调用 LoadState 方法:

  protected async override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
  {
     string source = string.Empty;
     if (pageState != null)
     {
        if (pageState.ContainsKey("MediaElementSource"))
        {
           source = (string)pageState["MediaElementSource"];
        }
     }
     var document = PublicationService.GetDocument(this.currentDocumentIdNumber);
     this.DefaultViewModel = new DocumentViewModel(document);
     this.DefaultViewModel.CurrentMarkerSourceChanged += UpdateMediaElementSource;
     if (!string.IsNullOrEmpty(source))
     {
        // This causes the UpdateMediaElementSource() method to run.
        this.DefaultViewModel.CurrentSource = source;
     }
  }

我感谢在这个问题上的任何帮助。如果您需要更多详细信息,请告诉我。

MediaElement Source 無法在 SaveState/LoadState 之後設定

因此,事实证明mediaElement的源是在添加到可视化树之前

设置的。

通常,执行此操作时这不是问题:

mediaElement.Source = whatever;

但当你这样做时,这是一个问题:

mediaElement.SetSource(stream, MimeType);

结论

当你调用SetSource(...)时,确保你的MediaElement是VisualTree的一部分。

使上述代码正常工作的一种简单方法是添加一个全局布尔值,一旦触发mediaElement.Loaded事件,该布尔值将设置为 true。然后,在调用 SetSource() 的代码中,将其包装在if(_mediaElementLoaded)块中。