StreamMediaInput 只能播放一次到最后吗?

发布于 2025-01-09 01:21:19 字数 2078 浏览 3 评论 0原文

我正在使用 LibVLCSharp 播放音频,并且在 UWP 应用程序中遇到问题。我正在通过加载到 StreamMediaInput 中的 MemoryStream 播放音频,以用作播放器的媒体。当我这样做时,如果我让播放器到达音频的末尾,音频将变得不可用。我不能玩第二次,不能寻求任何其他位置,不能用它做任何事情。当我这样做时,它会锁定线程并完全ganks应用程序。

这是我的播放音频代码的简化版本,但包含所有重要的内容:

LibVLC _libVLC = new LibVLC();
MediaPlayer _player;

public void Load(byte[] data)
{
    _player = new MediaPlayer(_libVLC);
   
    var stream = new MemoryStream(data);

    var mediaInput = new StreamMediaInput(stream);

    var media = new Media(_libVlc, mediaInput);
    player.Media = media;
    
}

public void Play()
{
   if (_player?.Media == null)
          return;
      
   _player.Play();
}

我是否遗漏了音频结束时 MediaPlayer 的行为方式的一些基本内容?

更新: 我对我的代码实施了这一更改,现在它运行得很好。看来,当 StreamMediaInput 达到“已结束”状态时,它无法继续使用该输入。因此,解决方案是在需要时手动重置所有内容。这是我所做的更改:

public bool Load(Stream stream)
{
    _player = new MediaPlayer(_libVLC);
    _currentStream = stream;
    SetupMedia();    
    return _player?.Media != null;
}

public bool Play()
{
    if (_player?.Media == null)
        return false;

    if (_player.Media.State == VLCState.Ended)
    {
        SetupMedia();
    }

    return _player.Play();
}

private void SetupMedia()
{
    if (_currentStream.Position == _currentStream.Length && _currentStream.CanSeek)
    {
        _currentStream.Seek(0, SeekOrigin.Begin);
    }
    var mediaInput = new StreamMediaInput(_currentStream);
    var media = new Media(_libVlc, mediaInput);
    if (_player == null) return;
    var oldMedia = Player.Media;
    if (oldMedia != null)
    {
        oldMedia.DurationChanged -= MediaOnDurationChanged;
        oldMedia.Dispose();
    }
    _player.Media = media;
    Duration = media.Duration;
    media.DurationChanged += MediaOnDurationChanged;   
}

private void MediaOnDurationChanged(object sender, MediaDurationChangedEventArgs args)
{
     Duration = args.Duration / 1000.0;
}

除了此更改是为了解决无法自始至终播放音频源两次的问题之外,我意识到事实上我确实省略了原始帖子中导致应用程序运行的一些代码挂起:在播放器事件的回调中,我调用了播放器本身的方法(例如 .SeekTo(0))。在研究这个问题时,我在文档中发现你绝对不应该这样做,并且删除该代码解决了冻结问题。

I am using LibVLCSharp to play audio, and am running into an issue in a UWP app. I am playing audio via a MemoryStream loaded into the StreamMediaInput to be used as a Media for the player. When I do this, if I let the player reach the end of the audio, the audio becomes unusable. I can't play it a second time, can't seek to any other position, can't do anything with it. When I do, it locks the thread and completely ganks the app.

This is a simplified version of my code to play audio, but contains all of the important stuff:

LibVLC _libVLC = new LibVLC();
MediaPlayer _player;

public void Load(byte[] data)
{
    _player = new MediaPlayer(_libVLC);
   
    var stream = new MemoryStream(data);

    var mediaInput = new StreamMediaInput(stream);

    var media = new Media(_libVlc, mediaInput);
    player.Media = media;
    
}

public void Play()
{
   if (_player?.Media == null)
          return;
      
   _player.Play();
}

Am I missing something fundamental about the way the MediaPlayer should behave when audio ends?

UPDATE:
I implemented this change to my code and it now plays just fine. It appears that when a StreamMediaInput reaches a state of "Ended", it doesn't have the ability to continue using that input. So, the solution is to reset it all manually if I need to. Here's what I changed:

public bool Load(Stream stream)
{
    _player = new MediaPlayer(_libVLC);
    _currentStream = stream;
    SetupMedia();    
    return _player?.Media != null;
}

public bool Play()
{
    if (_player?.Media == null)
        return false;

    if (_player.Media.State == VLCState.Ended)
    {
        SetupMedia();
    }

    return _player.Play();
}

private void SetupMedia()
{
    if (_currentStream.Position == _currentStream.Length && _currentStream.CanSeek)
    {
        _currentStream.Seek(0, SeekOrigin.Begin);
    }
    var mediaInput = new StreamMediaInput(_currentStream);
    var media = new Media(_libVlc, mediaInput);
    if (_player == null) return;
    var oldMedia = Player.Media;
    if (oldMedia != null)
    {
        oldMedia.DurationChanged -= MediaOnDurationChanged;
        oldMedia.Dispose();
    }
    _player.Media = media;
    Duration = media.Duration;
    media.DurationChanged += MediaOnDurationChanged;   
}

private void MediaOnDurationChanged(object sender, MediaDurationChangedEventArgs args)
{
     Duration = args.Duration / 1000.0;
}

In addition to this change to fix the issue of not being able to play an audio source twice all the way through, I realized I did, in fact, omit some code from the original post that was causing the app to hang: In a callback from an event on the player, I was calling methods on the player itself (such as .SeekTo(0)). In researching this I found in the documentation that you should definitely not do that, and removing that code fixed the freezing issue.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文