首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 使用 DirectX 實作影片播放器:Managed DirectX AudioVideoPlayback 完整教學

     編輯:關於C語言

前言:DirectX 在多媒體開發的角色

DirectX 是微軟提供的多媒體 API 集合,將多樣化的硬體(顯示卡、音效卡、輸入裝置)抽象為統一介面。對於 .NET 開發者,Managed DirectX (MDX) 封裝了非受控 DirectX COM 介面,讓 C# 能以物件導向方式操作影音播放、3D 繪圖、輸入處理等功能。本文以 Microsoft.DirectX.AudioVideoPlayback 命名空間為核心,逐步建構一個具備開啟、播放、暫停、停止功能的影片播放器。

一、環境建置與 SDK 安裝

必要元件

  • Windows 2000/XP/2003 或更新作業系統
  • .NET Framework 1.1/2.0+ SDK
  • DirectX SDK 9.0(.NET Framework SDK 不包含 DirectX)

安裝步驟

  1. 下載 DirectX SDK(範例連結:dxsdk_apr2005.exe)
  2. 執行安裝,完成後會在 C:\Windows\Microsoft.Net\Managed DirectX 產生 9 個 DLL 與對應 XML 文件
  3. 專案中加入參考:Microsoft.DirectX.AudioVideoPlayback.dll

二、核心命名空間與類別架構

DirectX 9.0 主要命名空間

命名空間主要功能
Microsoft.DirectX公用類別、數學結構(Vector, Matrix)
Microsoft.DirectX.Direct3D3D 圖形繪製、特效、Mesh 處理
Microsoft.DirectX.DirectSound音效播放、錄製、3D 音效定位
Microsoft.DirectX.DirectInput鍵盤、滑鼠、搖桿等輸入裝置
Microsoft.DirectX.AudioVideoPlayback影音播放核心(本文重點)
Microsoft.DirectX.DirectPlay網路遊戲通訊
Microsoft.DirectX.Diagnostics除錯、效能分析

AudioVideoPlayback 核心類別

  • Video:影片播放控制,繼承自 AudioVideo
  • Audio:純音訊播放控制,繼承自 AudioVideo
  • TextureRenderEventArgs:影像渲染事件參數(進階用途)

三、Video 類別關鍵屬性與方法

常用屬性

屬性型別說明
OwnerControl影片渲染宿主容器(Panel, Form 等)
CurrentPositiondouble目前播放位置(秒),可讀寫
Durationdouble影片總長度(秒),唯讀
StateStateFlags播放狀態:Playing, Paused, Stopped 等
Fullscreenbool全螢幕模式切換
SizeSize播放視窗大小
AudioAudio取得音訊軌控制物件
Captionstring視窗標題

常用方法

方法說明
Play()開始/繼續播放
Pause()暫停播放
Stop()停止播放,位置歸零
SeekCurrentPosition(double)跳轉至指定時間(秒)
HideCursor() / ShowCursor()隱藏/顯示滑鼠游標
Dispose()釋放非受控資源(必須呼叫)

四、WinForms 播放器完整實作

1. 專案建立與介面設計

  • 專案類型:Windows Forms Application
  • 工具箱拖放元件:
    • OpenFileDialog(openFileDialog1):篩選 *.avi;*.mpg;*.wmv;*.mp4
    • Panel(panel1):影片渲染區域,Dock = Top
    • 四個 Button:開啟(btnOpen)、播放(btnPlay)、暫停(btnPause)、停止(btnStop)

2. 核心程式碼

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);
        }
    }
}

3. 進階功能擴充建議

  • 進度條: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 年停止支援。現代專案建議採用:

  • Media Foundation (MF):Windows 內建新一代多媒體平台,支援硬體加速 H.264/HEVC
  • Windows Media Player Control (AxWMPLib):簡單嵌入播放器
  • LibVLCSharp:跨平台、支援幾乎所有格式、硬體解碼
  • FFmpeg + SharpFFmpeg:底層控制、轉碼、串流處理
  • SkiaSharp / ImageSharp:影像處理、逐幀播放

本文範例僅供學習 DirectX 歷史架構與 Managed 互操作概念,生產環境請評估現代替代方案。

總結

透過 Microsoft.DirectX.AudioVideoPlayback.Video 類別,我們能以極少程式碼實現基本影片播放功能。核心在於:正確設定 Owner 控制項、妥善管理 Video 實例生命週期(Dispose)、處理格式相容性。雖然 Managed DirectX 已淘汰,但其封裝設計思路(宿主控制項、狀態機、事件驅動)在現代多媒體程式庫中依然普遍適用。理解這些基礎概念,有助於快速上手新一代影音開發框架。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved