解決WPF切換視頻播放時黑屏的問題

播放器在加載一個新視頻的時候,通常會把當前畫面清空,然後開始渲染新視頻內容,但是播放器在加載到渲染的過程中需要一定的時間,雖然時間不長,但是在視頻切換的過程中用戶還是能看到屏幕會出現黑屏的情況。所以理想的解決辦法是,播放器在加載過程中不清空畫面,依舊保留上一個視頻的最後一幀。但是這種方案需要對播放器進行底層改造,這個對於不熟悉音視頻開發的人來說是一個很大的挑戰,所以本文基於WPF的MediaElement實現視頻的無縫切換,本方案不需要對播放器底層進行任何改動,不過會造成CPU和資源佔用的提升。
本方案的核心思路就是在播放視頻後就立刻創建一個新的MediaElement對象,並且設置好下一個視頻資源,等到當前視頻播放完成的時候,先讓新的MediaElement對象先進行Play加載資源,加載完成的時候再把這個MediaElement對象添加到界面上去,添加完成以後,移除之前的MediaElement,並且釋放相關資源,同時重複開頭的步驟。代碼如下:

public partial class MainWindow : Window
    {
        string dir = @"C:\Users\w9433\Desktop\";
        string[] videos = {"1.mp4","12.mp4","13.mp4"};
        int index;
        MediaElement mNowMediaElement;
        MediaElement mNextMediaElement;

        public MainWindow()
        {
            InitializeComponent();
            Loaded += MainWindow_Loaded;
            
        }

        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {

            mNowMediaElement = new MediaElement();
            mNowMediaElement.MediaEnded += Player_MediaEnded;
            mNowMediaElement.MediaOpened += Player_MediaOpened;
            mNowMediaElement.LoadedBehavior = MediaState.Manual;
            mNowMediaElement.UnloadedBehavior = MediaState.Manual;
            mNowMediaElement.Stretch = Stretch.Uniform;
            string path = dir + videos[index % videos.Length];
            mNowMediaElement.Source = new Uri(path, UriKind.Absolute);
            ContentView.Children.Add(mNowMediaElement);//這裏的ContentView就是一個根佈局 我這裏在xaml用的Canvas
            mNextMediaElement = ReadyVideo();
            mNowMediaElement.Play();
        }

        private void Player_MediaOpened(object sender, EventArgs e)
        {
            if (sender == mNextMediaElement) {
                ContentView.Children.Add(mNextMediaElement);
            }            
        }

        private void Player_MediaEnded(object sender, EventArgs e)
        {
            mNextMediaElement.Play();
        }

        private MediaElement ReadyVideo()
        {
            MediaElement mNextMediaElement = new MediaElement();
            mNextMediaElement.MediaEnded += Player_MediaEnded;
            mNextMediaElement.MediaOpened += Player_MediaOpened;
            mNextMediaElement.LoadedBehavior = MediaState.Manual;
            mNextMediaElement.UnloadedBehavior = MediaState.Manual;
            mNextMediaElement.Stretch = Stretch.Uniform;
            mNextMediaElement.Loaded += MNextMediaElement_Loaded;
            index++;
            string path = dir + videos[index % videos.Length];
            Console.WriteLine("下一個播放的視頻爲:" + path);
            mNextMediaElement.Source = new Uri(path, UriKind.Absolute);
            return mNextMediaElement;
        }

        private void MNextMediaElement_Loaded(object sender, RoutedEventArgs e)
        {
            mNowMediaElement.Stop();
            mNowMediaElement.Close();
            ContentView.Children.Remove(mNowMediaElement);
            mNowMediaElement = mNextMediaElement;
            mNextMediaElement = ReadyVideo();
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章