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

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

作者: 缺水的海豚 | 来源:发表于2023-08-08 15:16 被阅读0次

    前段时间在 WPF 中实现了【MediaElement + 定时器】的自动轮播。用了一段时间之后,没啥大问题,但是发现,个别 MP4 视频,在播放的时候,有卡顿的现象,看网上说是 MediaElement 解码的问题,建议使用 VLC,所以,再次改造,用 VLC 代替 MediaElement 来试试。

    前一篇:WPF 实现图片/视频自动轮播(MediaElement/定时器)

    很多教程,都是使用二次封装 VLC 的库,但我不想使用二次封装的,所以这里直接使用官方的库(以下地址都是官方地址,内容是英文的,暂时没有中文翻译)。

    1. 添加引用

    <ItemGroup>
        <PackageReference Include="LibVLCSharp.WPF" Version="3.7.0" />
        <PackageReference Include="VideoLAN.LibVLC.Windows" Version="3.0.18" />
    </ItemGroup>
    

    很多教程,都让安装最新的 VLC 播放器,然后去安装目录找 DLL 什么的,其实没必要,官方有相应的库,直接在 Nuget 添加引用就好了(VideoLAN.LibVLC.Windows)。

    2. WPF 文件

    // 就是添加了 VLC 的命名空间,同时添加了 VLC 的控件(VideoView)
    <Window x:Class="WpfVlcDemo.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfVlcDemo"
            xmlns:vlc="clr-namespace:LibVLCSharp.WPF;assembly=LibVLCSharp.WPF"
            mc:Ignorable="d"
            Title="MainWindow" Height="450" Width="800">
        <Grid>
            <vlc:VideoView x:Name="Wrapper" />
        </Grid>
    </Window>
    

    3. CS 文件

    using LibVLCSharp.Shared;
    
    using System;
    using System.IO;
    using System.Timers;
    using System.Windows;
    
    namespace WpfVlcDemo;
    
    public partial class MainWindow : Window
    {
        private readonly Timer _timer;
        private readonly string[] _videos;
    
        private LibVLC _libVlc;
        private MediaPlayer _player;
        private Media _media1, _media2;
    
        private int _idx = 0;
    
        public MainWindow()
        {
            InitializeComponent();
    
            _videos = Directory.GetFiles("<播放素材目录>");
    
            _timer = new()
            {
                Interval = 10000   // 10 秒切换素材
            };
    
            _timer.Elapsed += Timer_Elapsed;
            Wrapper.Loaded += Wrapper_Loaded;
        }
    
        private void Wrapper_Loaded(object sender, RoutedEventArgs e)
        {
            Core.Initialize();
    
            _libVlc = new();
            _player = new(_libVlc);
            _player.Opening += Player_Opening;
    
            Wrapper.MediaPlayer = _player;
    
            _media1 = new(_libVlc, new Uri(_videos[_idx++]));   // 准备第一个素材
    
            _timer.Start();   // 开始计时
            _player.Play(_media1);   // 开始播放
        }
    
        private void Player_Opening(object sender, EventArgs e)
        {
            if (_idx == _videos.Length)
            {
                _idx = 0;   // 素材列表播放完毕之后,重新开始播放
            }
    
            _media2 = new(_libVlc, new Uri(_videos[_idx++]));   // 准备下一个素材
        }
    
        private void Timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            _media1 = _media2;
            _player.Play(_media1);
        }
    }
    

    至此,测试代码就全部完毕了,可以直接运行看效果了。

    特别说明:

    1. 上面的代码,没有释放内存,如果用于生产中,需要自己释放 Media、Player 的内存
    2. 相邻的两个素材,在切换的时候,会有很短暂的黑屏现象,上面用了两个 Media 对象,试图解决这个问题,但是,效果不明显,还在寻求其他方法,比如用两个播放器(类似上一篇文章那样,用两个 MediaElement 交替),或者像网上说的,保留最后一帧的画面作为背景,直到后面的素材开始播放才取消背景

    前一篇:WPF 实现图片/视频自动轮播(MediaElement/定时器)

    相关文章

      网友评论

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

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