1、基于Windows meida player的视频播放,应用于最早的EXPO项目内的视频播放:

VideoWindow
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MvcNetwork;
using log4net;
using NetworkHelper;
using ExpoSignageShare;
using System.Configuration;
using Helper;
using WMPLib;
using PlayModel;
using System.IO;

namespace PlayApplication.MediaPlayers {
    
public partial class VideoWindow : MediaWindow {
        
static readonly ILog logger = LogManager.GetLogger(typeof(VideoWindow));

        
private Delay delay;
        
private EventHandler handler;
        
private System.Timers.Timer videoTimer = new System.Timers.Timer(15);
        
private System.Timers.Timer liveTimer = new System.Timers.Timer(15);
        
private MediaItem item;

        
public VideoWindow() {
            InitializeComponent();

            axWindowsMediaPlayer1.settings.setMode(
"loop"false);
            videoTimer.Elapsed 
+= (o1, e1) => {
                videoTimer.Stop();
                
this.UIInvoke(() => {
                    axWindowsMediaPlayer1.Size 
= this.Size;
                    axWindowsMediaPlayer1.URL 
= Path.GetFullPath(item.LocalPath);
                });
            };
            liveTimer.Elapsed 
+= (o1, e1) => {
                liveTimer.Stop();
                
this.UIInvoke(() => {
                    axWindowsMediaPlayer1.Size 
= this.Size;
                    axWindowsMediaPlayer1.URL 
= item.LocalPath;
                });
                
try {
                    
if (item.Duration == 0) {
                        item.Duration 
= 5;
                        logger.Warn(
"Live Duration is 0");
                    }
                    delay 
= Delay.DelayExecute(new Duration { Seconds = item.Duration }, () => {
                        
if (handler != null) { handler(this, EventArgs.Empty); }
                    });
                    delay.Start();
                } 
catch (Exception ex) {
                    logger.Warn(ex);
                    
if (handler != null) { handler(this, EventArgs.Empty); }
                }
            };
        }

        
public VideoWindow(bool arg)
            : 
this() {
            
if (arg) {
                axWindowsMediaPlayer1.settings.volume 
= 100;
            } 
else {
                axWindowsMediaPlayer1.settings.volume 
= 0;
            }
        }

        
public override void Play(MediaItem item, EventHandler playHandler) {
            
if (Debug) {
                
base.Play(item, playHandler);
                
return;
            }

            
try {
                
this.item = item;
                handler 
= playHandler;
                
if (item.Type == MediaItemType.Video) {
                    
bool bExists = File.Exists(item.LocalPath);
                    
if (bExists == false) {
                        
base.Play(item, playHandler);
                        
return;
                    }

                    videoTimer.Start();
                } 
else {
                    liveTimer.Start();
                }
            } 
catch (Exception ex) { logger.Warn(ex); }
        }

        
public override void Stop() {
            
if (Debug) { base.Stop(); return; }

            
try { videoTimer.Close(); } catch { }
            
try { liveTimer.Close(); } catch { }
            
try { delay.Cancel(); } catch { }
            
try { axWindowsMediaPlayer1.close(); } catch { }
        }

        
private void axWindowsMediaPlayer1_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e) {
            
if (axWindowsMediaPlayer1.playState == WMPPlayState.wmppsMediaEnded) {
                
if (handler != null) { handler(this, EventArgs.Empty); }
            }
        }
    }
}

 

  WMP最大的缺点是不稳定,有些功能不是很合理,而且对于重复播放的处理也比较扭曲;

  基于Direct X开发的一个视频播放控件,控件代码如下:  

ShgbitVideo
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.DirectX.AudioVideoPlayback;
using System.IO;
using System.Diagnostics;

namespace ShgbitVideo {
    
public partial class VideoBox : UserControl {
        
public string FileName { get { return fileName; } }
        
//public bool Loop { get { return loop; } set { loop = value; } }
        public int Volumn {
            
get {
                
int result = 0;
                
if (IsVideo() && audio != null && !audio.Disposed) {
                    result 
= (audio.Volume + 10000/ 100;
                }
                
return result;
            }
            
set {
                
if (IsVideo() && audio != null && !audio.Disposed) {
                    
int arg = value;
                    
if (arg > 100) {
                        arg 
= 100;
                    } 
else if (arg < 0) {
                        arg 
= 0;
                    }
                    audio.Volume 
= arg * 100 - 10000;
                }
            }
        }
        
public double Duration {
            
get {
                
double result = 0.0f;
                
if (IsVideo()) {
                    result 
= video.Duration;
                }
                
return result;
            }
        }
        
public double CurrentPosition {
            
get {
                
double result = 0.0f;
                
if (IsVideo()) {
                    result 
= video.CurrentPosition;
                }
                
return result;
            }
            
set {
                
if (IsVideo()) {
                    
double arg = value;
                    
if (arg < 0) {
                        arg 
= 0;
                    }
                    
if (loop) {
                        
try {
                            arg 
= arg % Duration;
                        } 
catch {
                            arg 
= 0;
                        }
                    } 
else {
                        
if (arg > Duration) {
                            arg 
= Duration;
                        }
                    }
                    video.CurrentPosition 
= arg;
                }
            }
        }
        
public Size DefaultSize {
            
get {
                Size result 
= new Size(00);
                
if (IsVideo()) {
                    result 
= video.DefaultSize;
                }
                
return result;
            }
        }
        
public bool Playing {
            
get {
                
bool result = false;
                
if (IsVideo()) {
                    result 
= video.Playing;
                }
                
return result;
            }
        }
        
public ShgbitPlayState PlayState {
            
get {
                ShgbitPlayState result 
= ShgbitPlayState.Stopped;
                
if (IsVideo()) {
                    result 
= (ShgbitPlayState)((int)video.State);
                }
                
return result;
            }
        }
        
public ShgbitMediaStyle MediaStyle {
            
get {
                
return GetMediaStyle(fileName);
            }
        }

        
public VideoBox() {
            InitializeComponent();
        }

        
private void VideoBox_Load(object sender, EventArgs e) {
            
//
        }

        
public void Open(string fileName) {
            Open(fileName, 
false);
        }

        
public void Open(string fileName, bool autoRun) {
            Close();
            
if (File.Exists(fileName)) {
                
if (GetMediaStyle(fileName) == ShgbitMediaStyle.Video) {
                    
this.fileName = fileName;
                    video 
= new Video(fileName, autoRun);
                    video.Owner 
= this;
                    video.Size 
= this.ClientSize;
                    
try {
                        audio 
= video.Audio;
                    } 
catch (Exception ex) { }
                }
            } 
else {
                
throw new FileNotFoundException(null, fileName);
            }
        }

        
public void Play() {
            
if (IsVideo() && PlayState != ShgbitPlayState.Running) {
                video.Play();
            }
        }

        
public void Stop() {
            
if (IsVideo() && PlayState != ShgbitPlayState.Stopped) {
                video.Stop();
            }
            fileName 
= string.Empty;
        }

        
public void Close() {
            Stop();
            
if (video != null && !video.Disposed) {
                
if (audio != null && !audio.Disposed) {
                    audio.Dispose();
                    audio 
= null;
                }
                video.Dispose();
                video 
= null;
            }
        }

        
private bool IsVideo() {
            
bool result = false;

            
if (video != null && !video.Disposed) {
                result 
= MediaStyle == ShgbitMediaStyle.Video;
            }

            
return result;
        }

        
public static ShgbitMediaStyle GetMediaStyle(string arg) {
            ShgbitMediaStyle result 
= ShgbitMediaStyle.Others;
            
if (!string.IsNullOrEmpty(arg)) {
                
switch (Path.GetExtension(arg).ToLower()) {
                    
case ".wmv":
                    
case ".avi":
                    
case ".rm":
                    
case ".rmvb":
                        result 
= ShgbitMediaStyle.Video;
                        
break;
                    
case ".jpg":
                    
case ".jpeg":
                    
case ".bmp":
                    
case ".png":
                        result 
= ShgbitMediaStyle.Picture;
                        
break;
                }
            } 
else {
                result 
= ShgbitMediaStyle.None;
            }
            
return result;
        }

        
private void VideoBox_Resize(object sender, EventArgs e) {
            
if (video != null && !video.Disposed) {
                video.Size 
= this.ClientSize;
            }
        }

        
private Video video;
        
private Audio audio;
        
private string fileName;
        
private bool loop;
    }

    
public enum ShgbitPlayState {
        Stopped 
= 0,
        Paused 
= 1,
        Running 
= 2,
    }

    
public enum ShgbitMediaStyle {
        Others 
= 0,
        Video 
= 1,
        Picture 
= 2,
        None 
= 9
    }
}

  基于此控件开发的视频播放窗口,应用在了NUOVA,Odin和Signage中:

VideoVS
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OVNShare;
using System.IO;
using OVNShare.Helper;
using System.Threading;
using System.Diagnostics;
using log4net;
using WMPLib;

namespace NuovaVSImpl {
    [VS(Name 
= "视频", Order = 2)]
    
public partial class VideoVS : VisualSourceBase {
        
static readonly ILog logger = LogManager.GetLogger(typeof(VideoVS));

        [VSDescription(
"视频文件列表""内容设置")]
        
public List<VideoFile> VideoFiles { get { return videoFiles; } set { videoFiles = value; } }

        [VSDescription(
"基准时间""内容设置")]
        
public string StandardTime {
            
get { return standardTime.ToString(); }
            
set {
                
try {
                    standardTime 
= Convert.ToDateTime(value);
                } 
catch {
                    standardTime 
= DateTime.Now;
                }
            }
        }

        
private void VideoVS_Load(object sender, EventArgs e) {
            
if (ScreenContext.ContainsKey("NeedLocate")) {
                
try {
                    needLocate 
= Convert.ToBoolean(ScreenContext["NeedLocate"]);
                } 
catch { }
            }
            
if (ScreenContext.ContainsKey("VideoVolumn")) {
                
try {
                    videoVolumn 
= Convert.ToInt32(ScreenContext["VideoVolumn"]);
                } 
catch { }
            }
        }

        
public VideoVS() {
            InitializeComponent();
        }

        
public override void StartRender() {
            StopRender();
            
base.StartRender();

            roundtime 
= videoFiles.Sum(p => p.Duration);
            
double offset = 0;
            videoFiles.ForEach(p 
=> {
                timeTable.Add(offset, p);
                p.Offset 
= offset;
                offset 
+= p.Duration;
            });
            
if (!VSDesignMode) {
                IDownloader.AddList(videoFiles.Where(p 
=> !File.Exists(Path.Combine(MediaDir, p.FileName))).Select(p => Path.Combine(MediaDir, p.FileName)).ToList());
            }
            playThread 
= new Thread(new ThreadStart(Play));
            playThread.Start();
        }

        
public override void StopRender() {
            
base.StopRender();

            
if (playThread != null && playThread.ThreadState == System.Threading.ThreadState.Running) {
                arEvent.Set();
                playThread.Join(
2000);
            }
            timeTable.Clear();
            
try {
                
this.videoBox.Close();
            } 
catch (Exception ex) {
                logger.Warn(ex);
            }
            loadControl.Visible 
= false;
        }

        
public override void Uninstall(Control parent) {
            
if (videoBox != null) {
                videoBox.Dispose();
            }
            
base.Uninstall(parent);
        }

        
private void Play() {
            
if (videoFiles.Count == 0) {
                
this.UIInvoke(() => {
                    loadControl.Visible 
= false;
                });
                
return;
            }

            
while (Rendering && this.Created) {
                
try {
                    
double offset = (DateTime.Now - standardTime).TotalMilliseconds / 1000.0f % roundtime;
                    VideoFile vf 
= GetVideoFile(offset);
                    
this.UIBeginInvoke(() => {
                        
if (Rendering) {
                            
try {
                                
string filePath = Path.Combine(MediaDir, vf.FileName);
                                
if (File.Exists(filePath)) {
                                    loadControl.Visible 
= false;
                                    
bool isNew = false;
                                    
if (filePath != videoBox.FileName) {
                                        videoBox.Open(filePath);
                                        videoBox.Volumn 
= videoVolumn;
                                        videoBox.Play();
                                        isNew 
= true;
                                    }

                                    
double ruler = 0.2f;
                                    
if (!needLocate && !isNew) {
                                        ruler 
= vf.Duration / 5;
                                    }
                                    
if (ruler < 0.2f) {
                                        ruler 
= 0.2f;
                                    }
                                    
if (Math.Abs(videoBox.CurrentPosition - (offset - vf.Offset)) > ruler) {
                                        Console.WriteLine(
"校正: {0}", videoBox.CurrentPosition - (offset - vf.Offset));
                                        videoBox.CurrentPosition 
= offset - vf.Offset;
                                    }
                                } 
else {
                                    
if (!VSDesignMode) {
                                        IDownloader.AddList(
new List<string> { filePath });
                                        loadControl.Visible 
= true;
                                        
int percent = IDownloader.QueryProgress(vf.FileName);
                                        loadControl.UpdateProgress(percent);
                                    }
                                    videoBox.Close();
                                }
                            } 
catch (Exception ex) {
                                logger.Warn(ex.ToString());
                            }
                            arEvent.Set();
                        }
                    });
                    arEvent.WaitOne();
                    
if (Rendering) {
                        Thread.Sleep(
2000);
                    }
                } 
catch (Exception ex) {
                    logger.Warn(ex.ToString());
                }
            }
        }

        
private VideoFile GetVideoFile(double offset) {
            VideoFile result 
= null;

            
if (videoFiles.Count == 0) {
                result 
= null;
            } 
else if (videoFiles.Count == 1) {
                result 
= timeTable[0];
            } 
else {
                
try {
                    List
<double> seq = new List<double>(timeTable.Keys);
                    
for (int i = 0; i < timeTable.Count; ++i) {
                        
double x = seq[i];

                        
if (i + 1 < seq.Count) {
                            
double y = seq[i + 1];
                            
if (offset > x && offset < y) {
                                result 
= timeTable[seq[i]];
                                
break;
                            }
                        } 
else {
                            result 
= timeTable[seq[seq.Count - 1]];
                        }
                    }
                } 
catch (Exception ex) {
                    logger.Warn(ex.ToString());
                }
            }

            
return result;
        }

        
public override void Update(VisualSourcePrototype arg) {
            StopRender();
            VideoFiles 
= arg.Data["VideoFiles"as List<VideoFile>;
            StandardTime 
= (string)arg.Data["StandardTime"];
            StartRender();
        }

        
private void VideoVS_Resize(object sender, EventArgs e) {
            loadControl.Location 
= new Point((this.ClientSize.Width - loadControl.Width) / 2, (this.ClientSize.Height - loadControl.Height) / 2);
        }

        
private List<VideoFile> videoFiles = new List<VideoFile>();
        
private Dictionary<double, VideoFile> timeTable = new Dictionary<double, VideoFile>();
        
private double roundtime;
        
private DateTime standardTime;
        
private Thread playThread;
        
private AutoResetEvent arEvent = new AutoResetEvent(false);
        
private bool needLocate;
        
private int videoVolumn;
    }
}

 

  其优点在于稳定,并且在循环播放等的处理上要优于WMP控件,缺点在于因为是基于.NET3.5开发的WinForm控件,因此在显示特效的处理上平淡无奇,无法做出绚丽的效果,已经无法满足高要求用户的需求;

  3、基于.NET4.0和WPF技术的视频播放:

  基于WPF和MediaElement来实现视频播放,不但稳定,而且能够显示华丽的特效处理,这在WPF初体验里已经有所展示;但那只是一个特效的展示,而我下一步要做的,则是通过WPF来封装一个稳定并且绚丽的视频播放控件……

posted on 2010-05-28 17:40  ю意思я  阅读(462)  评论(1编辑  收藏  举报