這是有大師把DirectShowdotnet包起來的DLL!!

http://directshownet.sourceforge.net/

 

 

以下程式轉載自下面連結裡面的大師

http://aaronmind.blogspot.com/2009/01/dddd.html

 

/// <summary>
/// 播放狀態
/// </summary>
public enum PlayState
{
Stopped, //視訊停止
Paused, //視訊暫停
Playing, //視訊播放中
Init //尚未開啟任何影片檔
};

/// <summary>
/// 播放Video物件
/// </summary>
public class Video
{

private const int WMGraphNotify = 0x0400 + 13;
public const int VolumeFull = 0;
public const int VolumeSilence = -10000;

private DirectShowLib.IGraphBuilder graphBuilder = null;
private DirectShowLib.IMediaControl mediaControl = null;
private DirectShowLib.IMediaEventEx mediaEventEx = null;
private DirectShowLib.IVideoWindow videoWindow = null;
private DirectShowLib.IBasicAudio basicAudio = null;
private DirectShowLib.IBasicVideo basicVideo = null;
private DirectShowLib.IMediaSeeking mediaSeeking = null;
private DirectShowLib.IMediaPosition mediaPosition = null;
private DirectShowLib.IVideoFrameStep frameStep = null;

private string filePath = string.Empty;
private bool _FullScreen = false;
private int _Volume = VolumeFull;
public PlayState State = PlayState.Init;
private double currentPlaybackRate = 1.0;

private Size _size = new Size(0, 0);
private IntPtr hDrain = IntPtr.Zero;

#if DEBUG
private DsROTEntry rot = null;
#endif

/// <summary>
/// 裝載視訊物件的Container
/// </summary>
public Control Owner;


/// <summary>
/// 是否全螢幕模式
/// </summary>
public bool FullScreen
{
get
{
return _FullScreen;
}
set
{
if (this.State == PlayState.Init)
{
throw new Exception("No video file has been opened");
}

if (value != _FullScreen)
{
int hr = 0;
OABool lMode;

if (value)
{
//設定為全螢幕
hr = this.videoWindow.get_MessageDrain(out hDrain);
DsError.ThrowExceptionForHR(hr);
hr = this.videoWindow.put_MessageDrain(Owner.Handle);
DsError.ThrowExceptionForHR(hr);

lMode = OABool.True;
hr = this.videoWindow.put_FullScreenMode(lMode);
DsError.ThrowExceptionForHR(hr);
}
else
{
//回復視窗模式
lMode = OABool.False;
hr = this.videoWindow.put_FullScreenMode(lMode);
DsError.ThrowExceptionForHR(hr);

hr = this.videoWindow.put_MessageDrain(hDrain);
DsError.ThrowExceptionForHR(hr);
hr = this.videoWindow.SetWindowForeground(OABool.True);
DsError.ThrowExceptionForHR(hr);
}
}

this._FullScreen = value;

}

}

/// <summary>
/// 取得/設定寬度
/// </summary>
public int Width
{
get
{
return _size.Width;
}
set
{
if (this.State == PlayState.Init)
{
throw new Exception("No video file has been opened");
}

int hr = 0;
this.Owner.Width = value;
hr = this.videoWindow.SetWindowPosition(0, 0, value, _size.Height);
DsError.ThrowExceptionForHR(hr);
this._size.Height = value;
}
}

/// <summary>
/// 取得/設定高度
/// </summary>
public int Height
{
get
{
return _size.Height;
}
set
{
if (this.State == PlayState.Init)
{
throw new Exception("No video file has been opened");
}

int hr = 0;
this.Owner.Height = value;
hr = this.videoWindow.SetWindowPosition(0, 0, _size.Width, value);
DsError.ThrowExceptionForHR(hr);
this._size.Height = value;
}
}

/// <summary>
/// 取得目前影片的長度(秒數)
/// </summary>
public long Duration
{
get
{
if (State == PlayState.Init)
{
return 0;
}
else
{
int hr = 0;
long dur;
hr = this.mediaSeeking.GetDuration(out dur);
DsError.ThrowExceptionForHR(hr);

TimeSpan t = new TimeSpan(dur);
return (long)t.TotalSeconds;
}
}
}

/// <summary>
/// 目前的位置(秒數)
/// </summary>
public long Position
{
get
{
if (State == PlayState.Init)
{
return 0;
}
else
{
int hr = 0;
long pos, stop;
hr = this.mediaSeeking.GetPositions(out pos, out stop);

TimeSpan t = new TimeSpan(pos);


return (long)t.TotalSeconds;
}
}

set
{
if (this.State == PlayState.Init)
{
throw new Exception("No video file has been opened");
}

if (Position < 0 || Position > Duration)
{
throw new Exception("Position out of range");
}

int hr = 0;
TimeSpan t = new TimeSpan(0, 0,(int)value);

DsLong newPosition = new DsLong(t.Ticks);
hr = this.mediaSeeking.SetPositions(newPosition, AMSeekingSeekingFlags.AbsolutePositioning, null, AMSeekingSeekingFlags.NoPositioning);
}
}


/// <summary>
/// 目前的音量大小 0~100
/// </summary>
public int Volume
{
get
{

return this._Volume / 100 + 100;
}
set
{
if (value > 100 || value < 0)
{
throw new Exception("Volume must between 0 to 100");
}

int hr = 0;
this._Volume = (value - 100) * 100;
hr = this.basicAudio.put_Volume(this._Volume);
}
}




/// <summary>
/// 初始化Video物件
/// </summary>
/// <param name="owner">Video附著的Container 通常是一個Pannel或Form</param>
public Video(ref Control owner)
{
this.Owner = owner;
}

/// <summary>
/// 開啟視訊檔
/// </summary>
/// <param name="filePath">視訊檔案路徑</param>
/// <param name="autoPlay">開啟後是否自動播放</param>
public void Open(string filePath, bool autoPlay)
{
int hr = 0;

if (!System.IO.File.Exists(filePath))
{
throw new Exception("File " + filePath + "Not Found!");
}


if (State != PlayState.Init)
{
CloseVideo();
}


//取得檔案stream
this.graphBuilder = (DirectShowLib.IGraphBuilder)new FilterGraph();
hr = this.graphBuilder.RenderFile(filePath, null);
DsError.ThrowExceptionForHR(hr);


//Get DirectShow Control interfaces
this.mediaControl = (DirectShowLib.IMediaControl)this.graphBuilder;
this.mediaEventEx = (DirectShowLib.IMediaEventEx)this.graphBuilder;
this.mediaSeeking = (DirectShowLib.IMediaSeeking)this.graphBuilder;
this.mediaPosition = (DirectShowLib.IMediaPosition)this.graphBuilder;

this.videoWindow = this.graphBuilder as DirectShowLib.IVideoWindow;
this.basicVideo = this.graphBuilder as DirectShowLib.IBasicVideo;
this.basicAudio = this.graphBuilder as DirectShowLib.IBasicAudio;

if (!IsVideo())
{
throw new Exception("The File Is Not A Video File Or The Codec Is Unsupported!");
}

//Set the playback event handle object
//hr = this.mediaEventEx.SetNotifyWindow(this.Owner.Handle, WMGraphNotify, IntPtr.Zero);
//DsError.ThrowExceptionForHR(hr);

//Set the video owner object to contain the vidwo window
hr = this.videoWindow.put_Owner(this.Owner.Handle);
DsError.ThrowExceptionForHR(hr);

//Set video window layout
hr = this.videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings | WindowStyle.ClipChildren);
DsError.ThrowExceptionForHR(hr);


//Get vedio size
int lHeight, lWidth;
hr = this.basicVideo.GetVideoSize(out lWidth, out lHeight);
DsError.ThrowExceptionForHR(hr);

//set owner object size as video size
this.Owner.Width = lWidth;
this.Owner.Height = lHeight;
this._size.Width = lWidth;
this._size.Height = lHeight;

hr = this.videoWindow.SetWindowPosition(0, 0, lWidth, lHeight);
DsError.ThrowExceptionForHR(hr);


GetFrameStepInterface();


this._FullScreen = false;
this.currentPlaybackRate = 1.0;

this.State = PlayState.Stopped;
this.filePath = filePath;

if (autoPlay)
{
Play();
}


}


/// <summary>
/// 播放視訊檔
/// </summary>
public void Play()
{
if (State == PlayState.Stopped || State == PlayState.Paused)
{
int hr = 0;
hr = this.mediaControl.Run();
DsError.ThrowExceptionForHR(hr);

this.State = PlayState.Playing;
}


}

/// <summary>
/// 停止播放視訊檔
/// </summary>
public void Stop()
{
if (State == PlayState.Playing || State == PlayState.Paused)
{
int hr = 0;

//停止播放
hr = this.mediaControl.Stop();
DsError.ThrowExceptionForHR(hr);

//回到第一個影格
DsLong pos = new DsLong(0);
hr = this.mediaSeeking.SetPositions(pos, AMSeekingSeekingFlags.AbsolutePositioning, null, AMSeekingSeekingFlags.NoPositioning);
//顯示第一個影格
hr = this.mediaControl.Pause();

this.State = PlayState.Stopped;
}
}


/// <summary>
/// 停止播放視訊檔
/// </summary>
public void Pause()
{
if (State == PlayState.Playing)
{
int hr = 0;
hr = this.mediaControl.Pause();
DsError.ThrowExceptionForHR(hr);

this.State = PlayState.Paused;
}
}

/// <summary>
/// 前進
/// </summary>
/// <param name="second">前進的秒數</param>
public void Forward(int second)
{
if (Position + second < Duration)
{
Position += second;
}
else
{
Position = Duration;
}

}

/// <summary>
/// 倒退
/// </summary>
/// <param name="second">倒退的秒數</param>
public void Backward(int second)
{
if (Position - second > 0)
{
Position -= second;
}
else
{
Position = 0;
}

}


/// <summary>
/// 視訊檔案是否是一個被支援的視訊檔?
/// </summary>
/// <returns>true = 是; false = 否</returns>
private bool IsVideo()
{
int hr = 0;
OABool lVisible;
bool result = true;

if ((this.videoWindow == null) || (this.basicVideo == null))
{
//是一個Audio檔(沒有視訊,只有音訊)
result = false;
}


hr = this.videoWindow.get_Visible(out lVisible);
if (hr < 0)
{
// 視訊檔使用的Codec不被支援的或根本不是視訊檔
if (hr == unchecked((int)0x80004002)) //E_NOINTERFACE
{
result = false;
}
else
DsError.ThrowExceptionForHR(hr);
}

return result;
}


/// <summary>
/// 取得格放時要用的IVideoFrameStep介面
/// </summary>
/// <returns>true = 可以取得格放介面 false = 無法取得格放介面</returns>
private bool GetFrameStepInterface()
{
int hr = 0;

DirectShowLib.IVideoFrameStep frameStepTest = null;

// Get the frame step interface, if supported
frameStepTest = (DirectShowLib.IVideoFrameStep)this.graphBuilder;

// Check if this decoder can step
hr = frameStepTest.CanStep(0, null);
if (hr == 0)
{
this.frameStep = frameStepTest;
return true;
}
else
{
this.frameStep = null;
return false;
}
}



/// <summary>
/// 關閉視訊檔
/// </summary>
public void CloseVideo()
{
int hr = 0;

//停止播放
if (this.mediaControl != null)
hr = this.mediaControl.Stop();

// Clear global flags
this.State = PlayState.Stopped;
this.FullScreen = false;

//關閉DirectShow Control Interfece
CloseInterfaces();


this.filePath = string.Empty;
this.State = PlayState.Init;
}

/// <summary>
/// 關閉DirectShow的Control Interface
/// </summary>
private void CloseInterfaces()
{
int hr = 0;

try
{
lock (this)
{
// Relinquish ownership (IMPORTANT!) after hiding video window

if (this.videoWindow != null)
{
hr = this.videoWindow.put_Visible(OABool.False);
DsError.ThrowExceptionForHR(hr);
hr = this.videoWindow.put_Owner(IntPtr.Zero);
DsError.ThrowExceptionForHR(hr);
}
if (this.mediaEventEx != null)
{
hr = this.mediaEventEx.SetNotifyWindow(IntPtr.Zero, 0, IntPtr.Zero);
DsError.ThrowExceptionForHR(hr);
}

#if DEBUG
if (rot != null)
{
rot.Dispose();
rot = null;
}
#endif
// Release and zero DirectShow interfaces
if (this.mediaEventEx != null)
this.mediaEventEx = null;
if (this.mediaSeeking != null)
this.mediaSeeking = null;
if (this.mediaPosition != null)
this.mediaPosition = null;
if (this.mediaControl != null)
this.mediaControl = null;
if (this.basicAudio != null)
this.basicAudio = null;
if (this.basicVideo != null)
this.basicVideo = null;
if (this.frameStep != null)
this.frameStep = null;
if (this.graphBuilder != null)
Marshal.ReleaseComObject(this.graphBuilder); this.graphBuilder = null;

GC.Collect();
}
}
catch(Exception ex)
{
throw new Exception("Video close faild:\r\n" + ex.Message);
}
}






}

welkingunther 發表在 痞客邦 PIXNET 留言(0) 人氣()