c#-使用MediaElement故事板连续播放视频

我有一个连续录制的视频文件的时间表.我需要以相同的顺序在应用程序中播放它们.

>我已经知道每个视频的相对开始时间和持续时间.
>下一个视频可能要等到上一个视频停止录制后的几秒钟,几分钟甚至几小时才能开始录制.
>我需要某种位置更改通知,以便可以将其他UI元素同步到视频位置(例如图形).
>在未录制任何视频的部分中,视频窗口将显示空白屏幕.
>不幸的是,我暂时仍无法使用WinForms,但是我将MediaElement嵌入到ElementHost中.

MediaTimeline故事板组合似乎很适合我的需求.情节提要提供一个满足条件3的CurrentTimeInvalidated事件.关于条件1和2,我相信我可以为每个视频创建MediaTimeline并将它们中的每个作为子元素添加到情节提要中.看来我有部分工作,但仍然有一些问题.

在我当前的实现中,情节提要从头到尾都可以正常播放.但是,仅显示添加到情节提要中的最后一个视频的视频.

这是我要实现的视频时间线播放器的一些简化的伪代码.

public class VideoTimelineEntry
{
    public Uri Uri;
    public TimeSpan RelativeStartTime;
    public TimeSpan Duration;
}

public class VideoTimelinePlayer : System.Windows.Forms.UserControl
{
    private MediaElement _mediaElement = ...; // Contained in ElementHost
    private Storyboard _storyboard = new Storyboard();

    public void LoadTimeline(IEnumerable<VideoTimelineEntry> entries)
    {
        foreach (VideoTimelineEntry entry in entries)
        {
            MediaTimeline mediaTimeline = new MediaTimeline
            {
                BeginTime = entry.RelativeStartTime,
                Duration  = new Duration(entry.Duration),
                Source    = entry.Uri
            };

            _storyboard.Children.Add(mediaTimeline);

            // I think this is my problem. How do I set the target
            // so that it is always playing the current video, and
            // not just the last one in my timeline?
            Storyboard.SetTarget(mediaTimeline, _mediaElement);
        }
    }

    public void Play()
    {
        _storyboard.Begin();
    }

    public void Pause()
    {
        _storyboard.Pause();
    }

    public void Stop()
    {
        _storyboard.Stop();
    }
}

任何帮助将不胜感激.

解决方法:

看来每个MediaTimeline只能定位1个MediaElement.解决方法是,我现在为每个MediaTimeline创建一个专用的MediaElement.在我看来,这并不是一个好的解决方案,但是除非我想处理轮询/定时和动态更改视频源,否则我想不出更好的方法.但是,我使用Storyboard的全部理由是为了避免这样做.

更新7/24/14

我决定发布一个非常精简的示例来改善此答案.

public void LoadTimeline(IEnumerable<MediaTimeline> mediaTimelines)
{
    // Check that none of the timelines overlap as specified by the
    // acceptance criteria.
    // e.g. timeline2.BeginTime < timeline1.BeginTime + timeline1.Duration.

    _storyboard.Children.Clear();

    foreach (MediaTimeline mediaTimeline in mediaTimelines)
    {
        _storyboard.Children.add(mediaTimeline);

        MediaElement mediaElement = new MediaElement();

        // _grid is just an empty <Grid></Grid> in the xaml layer.
        _grid.Children.Add(mediaElement);

        // Each media timeline now targets a dedicated media element.
        Storyboard.SetTarget(mediaTimeline, mediaElement);

        // Bring the active media element to the top.
        mediaTimeline.CurrentStateInvalidated += (sender, args) =>
        {
            Panel.SetZIndex(mediaElement, int.MaxValue);
        };
    }
}
上一篇:(转)如何从storyBoard中加载其中一个controller


下一篇:c# – 在代码隐藏中将RotateTransform动画添加到Storyboard