美文网首页
WPF 实现图片/视频自动轮播(MediaElement/定时器

WPF 实现图片/视频自动轮播(MediaElement/定时器

作者: 缺水的海豚 | 来源:发表于2023-07-28 00:00 被阅读0次

    最近改造公司的播控系统,客户端采用了 WPF 进行开发,IDE 是 VS 2022(C#)。

    20230809 添加:WPF 实现图片/视频自动轮播(VLC/定时器)

    WPF 的代码很简单,给 Grid 一个名称就好了。

    // WPF
    <Grid x:Name="Wrapper"></Grid>
    

    由于 MediaElement 可以播放视频,也能播放图片,所以就直接采用了。

    原理就是,采用了两个 MediaElement,交替显示内容,这样可以避免单个 MediaElement 在切换素材的时候,短暂出现的 “黑屏现象”。

    主要需要注意 MediaElement 占用内存的问题,所以,一定要及时移除播放完毕的 MediaElement!!!

    // C#
    public partial class MainWindow : Window
    {
        readonly Timer _timer;   // 单个视频播放的定时器(有可能视频时长大于播放时长)
        readonly string[] _videos;
    
        int _idx;
        MediaElement _player1, _player2;
    
        public MainWindow()
        {
            InitializeComponent();
    
            _idx = 0;
            _videos = Directory.GetFiles("<素材所在的路径>");   // 获取待播放的素材列表
    
            _timer = new()
            {
                Interval = 10000   // 单个素材播放的时长(10秒)
            };
    
            _timer.Elapsed += Timer_Elapsed;
    
            // 设置窗体的标题、样式(无边框)、位置、窗体大小等等
            Title = "Player";
            AllowsTransparency = true;
            WindowStyle = WindowStyle.None;
            WindowStartupLocation = WindowStartupLocation.Manual;
            Top = 0;
            Left = 0;
    
            Width = 1152;
            Height = 640;
    
            Loaded += MainWindow_Loaded;
        }
    
        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            _player1 = InitPlayer();
            _player1.Source = new(_videos[_idx], UriKind.Absolute);
    
            Wrapper.Children.Add(_player1);   // 窗体加载完毕后,将第一个播放器添加到界面中
    
            _player2 = PreparePlayer();   // 准备第二个播放器,但不添加到界面中
    
            _timer.Start();   // 计时器开始计时
            _player1.Play();   // 第一个播放器开始播放
        }
    
        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            Dispatcher.Invoke(_player2.Play);   // 计时器时间到,播放第二个播放器的内容
        }
    
        private void Player_Loaded(object sender, RoutedEventArgs e)
        {
            _player1.Stop();
            _player1.Close();
            Wrapper.Children.Remove(_player1);   // 将第一个播放器从界面中移除
    
            _player1 = _player2;
            _player2 = PreparePlayer();
        }
    
        private void Player_MediaOpened(object sender, RoutedEventArgs e)
        {
            if (sender == _player2)
            {
                Wrapper.Children.Add(_player2);   // 将下一个播放器添加到界面中
            }
        }
    
        // 如果不需要计时器,可以用这个事件,在上一个素材播放完毕后,自动切换播放下一个素材
        //private void Player_MediaEnded(object sender, RoutedEventArgs e)
        //{
        //    _player2.Play();
        //}
    
        // 初始化播放器(MediaElement)
        private MediaElement InitPlayer()
        {
            var player = new MediaElement
            {
                LoadedBehavior = MediaState.Manual,
                UnloadedBehavior = MediaState.Manual,
                Stretch = Stretch.UniformToFill
            };
    
            player.MediaOpened += Player_MediaOpened;
            //player.MediaEnded += Player_MediaEnded;
    
            return player;
        }
    
        // 准备下一个播放器,并加载下一个素材,如果是最后一个素材,则循环到第一个素材
        private MediaElement PreparePlayer()
        {
            var player = InitPlayer();
            player.Loaded += Player_Loaded;
    
            if (++_idx == _videos.Length)
            {
                _idx = 0;
            }
    
            player.Source = new(_videos[_idx], UriKind.Absolute);
            return player;
        }
    
        protected override void OnClosed(EventArgs e)
        {
            _player1.Stop();
            _player1.Close();
    
            _player2.Stop();
            _player2.Close();
    
            _timer.Dispose();
    
            base.OnClosed(e);
        }
    }
    

    20230809 添加:WPF 实现图片/视频自动轮播(VLC/定时器)

    相关文章

      网友评论

          本文标题:WPF 实现图片/视频自动轮播(MediaElement/定时器

          本文链接:https://www.haomeiwen.com/subject/vsyrpdtx.html