DirectX 是微軟提供的多媒體 API 集合,將多樣化的硬體(顯示卡、音效卡、輸入裝置)抽象為統一介面。對於 .NET 開發者,Managed DirectX (MDX) 封裝了非受控 DirectX COM 介面,讓 C# 能以物件導向方式操作影音播放、3D 繪圖、輸入處理等功能。本文以 Microsoft.DirectX.AudioVideoPlayback 命名空間為核心,逐步建構一個具備開啟、播放、暫停、停止功能的影片播放器。
dxsdk_apr2005.exe)C:\Windows\Microsoft.Net\Managed DirectX 產生 9 個 DLL 與對應 XML 文件Microsoft.DirectX.AudioVideoPlayback.dll| 命名空間 | 主要功能 |
|---|---|
Microsoft.DirectX | 公用類別、數學結構(Vector, Matrix) |
Microsoft.DirectX.Direct3D | 3D 圖形繪製、特效、Mesh 處理 |
Microsoft.DirectX.DirectSound | 音效播放、錄製、3D 音效定位 |
Microsoft.DirectX.DirectInput | 鍵盤、滑鼠、搖桿等輸入裝置 |
Microsoft.DirectX.AudioVideoPlayback | 影音播放核心(本文重點) |
Microsoft.DirectX.DirectPlay | 網路遊戲通訊 |
Microsoft.DirectX.Diagnostics | 除錯、效能分析 |
AudioVideoAudioVideo| 屬性 | 型別 | 說明 |
|---|---|---|
Owner | Control | 影片渲染宿主容器(Panel, Form 等) |
CurrentPosition | double | 目前播放位置(秒),可讀寫 |
Duration | double | 影片總長度(秒),唯讀 |
State | StateFlags | 播放狀態:Playing, Paused, Stopped 等 |
Fullscreen | bool | 全螢幕模式切換 |
Size | Size | 播放視窗大小 |
Audio | Audio | 取得音訊軌控制物件 |
Caption | string | 視窗標題 |
| 方法 | 說明 |
|---|---|
Play() | 開始/繼續播放 |
Pause() | 暫停播放 |
Stop() | 停止播放,位置歸零 |
SeekCurrentPosition(double) | 跳轉至指定時間(秒) |
HideCursor() / ShowCursor() | 隱藏/顯示滑鼠游標 |
Dispose() | 釋放非受控資源(必須呼叫) |
OpenFileDialog(openFileDialog1):篩選 *.avi;*.mpg;*.wmv;*.mp4Panel(panel1):影片渲染區域,Dock = TopButton:開啟(btnOpen)、播放(btnPlay)、暫停(btnPause)、停止(btnStop)using System;
using System.Windows.Forms;
using Microsoft.DirectX.AudioVideoPlayback;
namespace VideoPlayerDemo
{
public partial class MainForm : Form
{
private Video _video = null;
public MainForm()
{
InitializeComponent();
InitializePlayerState();
}
private void InitializePlayerState()
{
btnPlay.Enabled = btnPause.Enabled = btnStop.Enabled = false;
}
// 開啟檔案
private void btnOpen_Click(object sender, EventArgs e)
{
openFileDialog1.InitialDirectory = Application.StartupPath;
openFileDialog1.Filter = "影片檔案|*.avi;*.mpg;*.wmv;*.mp4;*.mov|所有檔案|*.*";
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
LoadVideo(openFileDialog1.FileName);
}
}
private void LoadVideo(string filePath)
{
try
{
// 釋放舊影片資源
_video?.Dispose();
// 建立新 Video 實例並指定宿主
_video = new Video(filePath);
_video.Owner = panel1;
// 保持 Panel 尺寸不變
int w = panel1.Width, h = panel1.Height;
panel1.Size = new Size(w, h);
// 播放第一幀以顯示預覽
_video.Play();
_video.Pause();
UpdateButtonStates(true);
}
catch (Exception ex)
{
MessageBox.Show($"載入失敗:{ex.Message}", "錯誤", MessageBoxButtons.OK, MessageBoxIcon.Error);
UpdateButtonStates(false);
}
}
// 播放
private void btnPlay_Click(object sender, EventArgs e)
{
_video?.Play();
}
// 暫停
private void btnPause_Click(object sender, EventArgs e)
{
_video?.Pause();
}
// 停止
private void btnStop_Click(object sender, EventArgs e)
{
_video?.Stop();
}
private void UpdateButtonStates(bool hasVideo)
{
btnPlay.Enabled = btnPause.Enabled = btnStop.Enabled = hasVideo;
}
// 表單關閉時釋放資源
protected override void OnFormClosed(FormClosedEventArgs e)
{
_video?.Dispose();
base.OnFormClosed(e);
}
}
}
TrackBar 綁定 CurrentPosition,Timer 定期更新_video.Audio.Volume (-10000 到 0,單位:百分之一分貝)_video.Fullscreen = !_video.Fullscreen;_video.PlaybackRate (1.0 為正常)_video.Ending 事件處理播放結束邏輯| 問題 | 原因 | 解決方式 |
|---|---|---|
| 影片無畫面/黑畫面 | 解碼器缺失、Owner 未設定、Panel 可見度問題 | 安裝 K-Lite Codec Pack;確認 _video.Owner = panel1;Panel 不可 Visible=false |
例外:FileNotFoundException (Managed DirectX DLL) | 專案參考路徑錯誤、目標機未安裝 DirectX | 複製 DLL 至輸出目錄或部署 DirectX 執行階段 |
| 記憶體洩漏 | 未呼叫 Dispose() | 實作 IDisposable、using、FormClosed 釋放 |
| 影片比例失真 | Panel 尺寸與影片原始比例不符 | 計算 AspectRatio,調整 Panel Size 或設定 _video.Size |
Managed DirectX 1.0 (DirectX 9.0) 已於 2010 年停止支援。現代專案建議採用:
本文範例僅供學習 DirectX 歷史架構與 Managed 互操作概念,生產環境請評估現代替代方案。
透過 Microsoft.DirectX.AudioVideoPlayback.Video 類別,我們能以極少程式碼實現基本影片播放功能。核心在於:正確設定 Owner 控制項、妥善管理 Video 實例生命週期(Dispose)、處理格式相容性。雖然 Managed DirectX 已淘汰,但其封裝設計思路(宿主控制項、狀態機、事件驅動)在現代多媒體程式庫中依然普遍適用。理解這些基礎概念,有助於快速上手新一代影音開發框架。