程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 展現自我:使用Microsoft Expression Encoder 3 SDK進行視頻編碼

展現自我:使用Microsoft Expression Encoder 3 SDK進行視頻編碼

編輯:關於.NET

在我最喜歡的一個電影場景中,Clark W. Griswold(《瘋狂聖誕假期》中由 Chevy Chase 飾演)在藏聖誕禮物時將自己困在了閣樓上。為了保暖,他戴上了從落滿灰塵的衣櫃中找到的 粉紅色手套、綠色帽子和棕色毛皮披肩。在衣櫃底部,他發現了從少年時期開始錄制的家庭電 影。他含著眼淚,用一台老舊的電影放映機看完了這些電影。

從那時起,家庭電影已經經歷了一段漫長的歷程,但是人們仍然被同一個問題所困擾:如何 向親朋好友展示我的電影?我們可以通過 YouTube、Vimeo 和 Facebook 這樣的網站輕松共享 視頻,但是對於每分鐘上百兆字節的高清視頻來說,將數據上傳到這些網站是一項非常費時的 任務。您的便攜式設備、游戲系統或家庭影院媒體中心甚至有可能播放不了這些文件。為了解 決這些問題,您需要將視頻轉換為其他格式。這個過程稱為“編碼”。

關於 Expression Encoder

Microsoft 視頻編碼工具 Expression Encoder 3 是 Expression 系列產品的一部分,該系 列產品可用來為 Web 和桌面應用程序創建引人注目的用戶界面。Expression Encoder 同時提 供免費版和付費版。付費版包含在 Expression Studio 3 Suite(599 美元)和 Expression Web 3 Suite(149 美元)中。免費下載版不支持編碼成 Silverlight Smooth Streaming 或 H.264 視頻,也不支持 H.264 視頻源,但是支持編碼成 Windows Media Video 文件,並帶有 一個不錯的 SDK。本文中的許多代碼示例要求使用付費版的程序,但是所有的代碼示例都可以 在免費版的 SDK 中編譯生成,只是會在運行時收到 InvalidMediaException 或 FeatureNotAvailableException 提示。

如果您不打算購買 Expression Suite,可以通過以下鏈接下載免費版的 Expression Encoder:microsoft.com/expression。Expression Professional MSDN 訂閱或 Visual Studio Professional with MSDN Premium 訂閱中也包含 Expression Encoder。請注意,您只 需花費 149 美元就可以購買到帶有此功能包且支持各種輸入和輸出格式的專業視頻編碼軟件應 用程序,這真是一個相當優惠的價格。而購買類似的視頻編碼解決方案則要付出多達 3,000 美 元。

無論您選擇哪種版本,都要安裝 Encoder 3 QFE。它增加了對更多文件類型和輸入設備的支 持,改善了某些情況下的程序性能,並修復了一些小的錯誤。QFE 安裝程序可在 Microsoft Expression 網站的 Expression Encoder 頁面獲得。

支持的格式

支持以下輸入視頻格式:

Windows Media Video (.wmv)

DVD 視頻 (.vob)

MPEG(.mpg、.mpeg)

Audio Video Interleave (.avi)

Microsoft Digital Video Recording (.dvr-ms)

付費版軟件增加了對以下格式的支持(另外還支持一些其他格式):

MPEG-4(.mp4、.m4v)

Quicktime (.mov)

AVC HD (.mts)

移動設備視頻(.3gp、.3g2)

在大多數情況下,Expression Encoder 支持 Windows Media Player 能夠播放的任何媒體 文件。如果您要支持更多文件格式(並且能夠在 Windows Media Player 中播放),您需要安 裝一個編解碼器,例如 K-Lite Codec Pack (codecguide.com) 或 Community Combined Codec Pack (cccp-project.net)。這兩種編解碼器都基於開源 ffdshow 項目,並且會添加對 VP6 編 碼的 Flash (.flv) 文件、Matroska 容器中的 H.264 視頻 (.mkv) 以及 Ogg 視頻 (.ogg) 文 件的支持。

免費版的 Expression Encoder 僅支持 Microsoft VC-1 作為輸出編解碼器。然而,您仍然 能夠為 Silverlight(僅單比特率)、Xbox 360、Zune 和 Zune HD 編碼視頻。而且,VC-1 編 解碼器也不錯,其壓縮能力與 H.264 不相上下(某些情況下可能更好)。升級到付費版軟件, 您就可以輸出 Silverlight Smooth Streaming 視頻(多比特率)和 H.264 視頻,這意味著您 編碼的視頻能夠在 iPhone、PS3、Flash 播放器(版本 10 支持 H.264/.mp4)和其他無數設備 上播放。

編碼基礎知識

如果要支持特定的輸出設備,則需要更改視頻配置文件的一些設置,所以您需要了解視頻編 碼的一些基本知識。對視頻進行重新編碼實際上是對視頻進行解壓縮,然後使用其他編解碼器 或是手動更改視頻屬性(例如大小、長寬比或幀速率),對其重新壓縮。盡管存在無損壓縮方 法,但並不常用,因為用這些方法壓縮出來的視頻文件仍舊太大。因此,為了減少存儲(以及 傳輸)視頻所需的空間,就需要一種算法(我們稱之為編解碼器)來壓縮和解壓縮視頻。壓縮 後的視頻流隨即按照某種規范(我們稱之為容器,如 WMV 或 MP4)存儲起來。容器和編解碼器 通常不是綁定使用的,因此盡管 H.264 是 MP4 容器中最常見的編解碼器,但也可以使用其他 編解碼器。 

比特率,以每秒千比特來表示,用於定義應該使用多少數據來存儲壓縮的視頻。降低比特率 即是讓編碼器用較高的比率來壓縮視頻,因此會降低視頻的質量。有不同的方法可用於指示編 碼器如何確定視頻的比特率。最簡單的方法就是使用恆定比特率 (CBR),強迫編碼器對每一秒 視頻使用相同數量的數據。可變比特率 (VBR) 用來告訴編碼器,文件的整體比特率應該是多少 ,但是允許編碼器根據視頻的特定區段所需的數據量,來提高或降低比特率。限制可變比特率 類似於不受限的 VBR,唯一的差別是您不僅要指定一個平均比特率,還要指定一個最高比特率 作為上限。

在對 Silverlight Smooth Streaming 視頻進行編碼時,限制可變比特率非常有用。它有助 於確保比特率不會超出客戶端帶寬,避免迫使客戶端請求質量較差的視頻流。CBR 和 VBR 通過 指定整體視頻文件的大小來指明要使用的壓縮量。

或者,您也可以讓編碼器使用基於質量的 VBR。您不用指定視頻的整體大小,而是指定一個 質量百分比,也就是在解壓後要保留的源視頻中數據量。例如,相對於自然風光或動作視頻, 卡通視頻只需保留較少的數據量就可以保持高質量的視頻。因此,如果您擁有高質量的源視頻 ,並且希望將其轉換成其他格式並保留最佳質量,可以考慮使用基於質量的 VBR。這些定義只 是冰山一角,但它們是選擇輸出設置的核心概念。在本文中,您還能夠看到其他的編碼定義應 用在不同的代碼示例中。

使用 SDK

若要使用代碼示例,您需要使用一個高質量的視頻。如果您手頭沒有高分辨率視頻,可以從 以下地址獲取一些不錯的 HD 視頻: microsoft.com/windows/windowsmedia/musicandvideo/hdvideo/contentshowcase.aspx。我會 使用 Adrenaline Rush 視頻作為這些示例的源。

安裝完 Expression Encoder 3 後,創建一個新的 Visual Studio C# 控制台應用程序項目 。添加對 Microsoft.Expression.Encoder.dll 和 Microsoft.Expression.Encoder.Utilities.dll 的引用,這兩個文件位於 \Program Files (x86)\Microsoft Expression\Encoder 3\SDK。您還需要添加對 WindowsBase 的引用(您可以 在“添加引用”對話框的“.NET”選項卡中找到 WindowsBase)。用到的許多類位於 Microsoft.Expression.Encoder 命名空間中,所以要為其添加一條 using 語句。

要實例化的第一項是 MediaItem 對象。MediaItem 構造函數使用一個字符串作為構造函數 的唯一參數。該參數用於傳遞將在編碼項目中用作源的文件的路徑:

MediaItem src = new MediaItem (@"C:\WMdownloads\AdrenalineRush.wmv");

創建 MediaItem 對象僅需一兩秒鐘的時間,但 SDK 會在後台進行大量的工作:收集關於源 視頻的信息,例如高、寬、幀速率(在屏幕上顯示各幅圖像的頻率)和持續時間。同時還會收 集有關音頻流的信息。

接下來創建 Job 類的實例(僅包含一個無參數的構造函數),然後將您的 MediaItem 添加 到該實例的 MediaItems 列表中。Job 類充當了所需輸出格式(稱為配置文件)的管理器:

Job job = new Job();
job.MediaItems.Add(src);

現在您需要指示 Job 類在編碼過程中要使用哪些音頻和視頻配置文件,最簡單的方法是使 用在用戶界面中定義的某個配置文件。例如,若要為 Zune HD 創建視頻,可以使用 VC1ZuneHD 預設配置:

job.ApplyPreset(Presets.VC1ZuneHD);

最後,指定輸出目錄並開始編碼過程:

job.OutputDirectory = @"C:\EncodedFiles";
job.Encode();

您的 Program.cs 文件應當與圖 1 類似。

圖 1 為 Zune HD 創建視頻

using Microsoft.Expression.Encoder;

namespace TestApp
{
  class Program
  {
    static void Main(string[] args)
    {
      MediaItem src = new MediaItem 
        (@"C:\WMdownloads\AdrenalineRush.wmv");
      Job job = new Job();
      job.MediaItems.Add(src);
      job.ApplyPreset(Presets.VC1ZuneHD);
      job.OutputDirectory = @"C:\EncodedFiles";
      job.Encode();
    } 
  } 
}

在運行應用程序之前,還有最後一件事要做:如果您使用的是 64 位 Windows,您需要修改 項目,將其編譯目標設為 x86 平台。在 Visual Studio 菜單欄中,選擇“項目”和“(項目名 稱) 屬性”。在打開的對話框中,選擇“生成”選項卡並將“目標平台”的值由“任何 CPU” 改為“x86”。

現在您就可以運行應用程序,並創建可在 Zune HD 上播放的視頻了。編碼過程需要幾分鐘 的時間,而且極占 CPU 資源。作為並行計算任務運行,對於視頻編碼過程非常有益,所以多核 計算機在這裡非常有優勢。

Expression Encoder 還包含一些用於針對在線服務(例如 YouTube、Vimeo 和 Facebook) 進行編碼的預設配置。用我的 Panasonic Lumix DMC-ZS3 數碼攝像機拍攝的 720p 視頻每分鐘 大約要消耗 110MB 空間。而使用 YouTube HD 預設配置(同樣為 720p)轉換視頻,則可以把 視頻減小至僅僅 16MB。這極大地提高了上傳和本地存儲的效率。將視頻轉換為 .mp4 文件,還 能讓它與更多的視頻編輯程序兼容。

自定義設置

若要手動實現和 VC1ZuneHD 預設配置相同的效果,您需要使用與圖 2 中類似的代碼來設置 視頻和音頻配置文件。對於圖 2 中要編譯的代碼,您需要添加對 Microsoft.Expression.Encoder.Utilities 和 System.Drawing 的引用。還要為 Microsoft.Expression.Encoder.Profiles 和 System.Drawing 添加 using 語句。 OutputFormat 本質上用來指定輸出文件的容器。我提到“本質上”是因為 Silverlight 的編 碼原理只有少許不同(稍後我要談到這一點)。

圖 2 Zune HD 的視頻和音頻配置文件設置

MediaItem src = new MediaItem (@"C:\WMdownloads\AdrenalineRush.wmv");

src.OutputFormat = new WindowsMediaOutputFormat();

src.OutputFormat.VideoProfile = new AdvancedVC1VideoProfile();
src.OutputFormat.VideoProfile.Bitrate = new
   VariableConstrainedBitrate(1000, 1500);
src.OutputFormat.VideoProfile.Size = new Size(480, 272);
src.OutputFormat.VideoProfile.FrameRate = 30;
src.OutputFormat.VideoProfile.KeyFrameDistance = new TimeSpan(0, 0,  4);
src.OutputFormat.AudioProfile = new WmaAudioProfile();
src.OutputFormat.AudioProfile.Bitrate = new
   VariableConstrainedBitrate(128, 192);
src.OutputFormat.AudioProfile.Codec = AudioCodec.WmaProfessional;
src.OutputFormat.AudioProfile.BitsPerSample = 24;

 
Job job = new Job();
job.MediaItems.Add(src);
job.OutputDirectory = @"C:\EncodedFiles";
job.Encode();

VideoProfile 指定要使用的視頻編解碼器,以及編碼時要使用的詳細設置。同樣, AudioProfile 指定要使用的音頻編解碼器及其設置。構造 VariableConstrainedBitrate 時, 第一個參數用於指定平均比特率,第二個參數用於指定最高比特率。大小設置用於指定容納編 碼後的視頻的框。對於 Adrenaline Rush 視頻,正確的大小設置實際上應為 480x272 以維持 長寬比。但如果我輸入 480x480,得出的視頻依然是 480x272。 

圖 2 中的 KeyFrameDistance 屬性指的是一種視頻編碼概念,這個概念我還沒有談到。大 多數視頻編碼方式是只保存一幀到下一幀之間的變化,而不是保存每個視頻幀的整個畫面。關 鍵幀是包含整個畫面的幀。本代碼每四秒創建一個關鍵幀。每當視頻中有重大變化(例如場景 變化)時,就會自動創建關鍵幀,但是您還應當按照預定義的間隔創建關鍵幀,以方便在電影 播放時進行視頻檢索。

Silverlight Smooth Streaming

Silverlight Smooth Streaming 可以根據當前的網絡狀況動態切換正在播放的媒體文件的 比特率。Smooth Streaming 項目由存儲在 .ismv 文件、.ism 和 .ismc 元數據文件中的各個 視頻組成,後兩者支持 Smooth Streaming 播放。

若要創建 Silverlight Smooth Streaming 項目,必須進行多處更改。首先,將 KeyFrameDistance 改為兩秒。如果 KeyFrameDistance 保留為四秒,視頻仍可以播放,但是當 播放器切換比特率時,您會注意到播放時會出現停頓。Silverlight 播放器將請求視頻按照兩 秒鐘一個塊來播放,因此如果在每個請求開始的時候有一個關鍵幀,播放會更加流暢。您還需 要添加以下行:

src.OutputFormat.VideoProfile.SmoothStreaming = true;

將 SmoothStreaming 設為 true,可讓編碼器將視頻輸出為 .ismv 文件,並創建 .ism 和 ismc 文件。只具備一個比特率不是一個真正流暢的流項目,所以為了創建多個輸出比特率,您 需要向 VideoProfile 添加多個流。使用類似圖 3 中的代碼來實現這個目的。

圖 3 添加 Silverlight Smooth Streaming

MediaItem src = new MediaItem (@"C:\WMdownloads\AdrenalineRush.wmv");
src.OutputFormat = new WindowsMediaOutputFormat();

src.OutputFormat.VideoProfile = new AdvancedVC1VideoProfile();
src.OutputFormat.VideoProfile.KeyFrameDistance = new TimeSpan(0, 0, 2);
src.OutputFormat.VideoProfile.SmoothStreaming = true;
src.OutputFormat.VideoProfile.Streams.Clear();
src.OutputFormat.VideoProfile.Streams.Add(new StreamInfo(new
   VariableConstrainedBitrate(2000, 3000), new Size(1280, 720)));
src.OutputFormat.VideoProfile.Streams.Add(new StreamInfo(new
   VariableConstrainedBitrate(1400, 1834), new Size(848, 476)));
src.OutputFormat.VideoProfile.Streams.Add(new StreamInfo(new
   VariableConstrainedBitrate(660, 733), new Size(640, 360)));

src.OutputFormat.AudioProfile = new WmaAudioProfile();
src.OutputFormat.AudioProfile.Bitrate = new
   VariableConstrainedBitrate(128, 192);
src.OutputFormat.AudioProfile.Codec = AudioCodec.WmaProfessional;
src.OutputFormat.AudioProfile.BitsPerSample = 24;

Job job = new Job();
job.MediaItems.Add(src);
job.OutputDirectory = @"C:\EncodedFiles";
job.Encode();

這些代碼指定了三種不同的比特率和大小來進行編碼。為了獲得最佳效果,視頻大小需要隨 比特率的降低而縮小。指定自己的比特率時,您可以使用 Expression Encoder 3 UI 中的 IIS Smooth Streaming 設置。請注意,以高出源文件的分辨率來對視頻進行編碼,是不可能獲得更 高質量的。唯一有可能的是,如果使用較弱的壓縮方法,則可以以高出源文件的比特率來對視 頻進行編碼。如果 SDK 能夠確定源文件的比特率,將會顯示在 MediaItem 的 SourceVideo Profile 屬性中:

int bitrate = ((ConstantBitrate) src.SourceVideoProfile.Bitrate).Bitrate;

如果 SDK 無法獲得源文件的比特率,您可以根據文件大小估算出一個相當接近的值。這是 具體的估算公式:

以 kb/s 為單位的大概比特率 =(以千字節為單位的文件大小 * 8 / 以秒為單位的視頻持 續時間)- 以 kb/s 為單位的音頻比特率

您可以使用 System.IO.FileInfo 類來獲得源文件大小,用 SDK 來獲得持續時間 (MediaItem.FileDuration 屬性)以及可能的音頻比特率。如果您不知道音頻比特率,可以使 用 128 或 160 來估算(大多數的音頻比特率都介於 64 和 192 之間),您還可以通過 Windows Media Player 的“屬性”窗口(按 Alt 鍵顯示菜單,然後選擇“文件”|“屬性”) 獲得音頻比特率。

監視進度

因為一項編碼任務要花費數小時才能完成,能夠看到編碼進度是非常有幫助的。SDK 提供了 一種簡單的方法,即通過事件來監視編碼進度,您可以為該事件添加處理程序:

job.EncodeProgress += new EventHandler<EncodeProgressEventArgs> (OnProgress);

添加一個類似如下的方法來處理事件:

static void OnProgress(object sender, EncodeProgressEventArgs e)
{
  Console.Clear();
  Console.WriteLine((100 * (e.CurrentPass - 1) + e.Progress) /  e.TotalPasses + "%");
}

多通路編碼是一個與本代碼示例相關的新概念。使用可變比特率進行編碼時,過程分為兩步 ,稱為通路。在第一個通路中,分析源視頻以確定哪部分最復雜,並能夠通過提高比特率獲益 。在第二個通路中,使用在第一個通路中獲得的信息對視頻進行編碼。因此,如果您使用了恆 定比特率,就沒有必要使用 EncodeProgressEventArgs 類的 CurrentPass 或 TotalPasses 屬 性。

合並視頻

如果您只想對視頻的一部分進行編碼,或者要合並多個視頻,SDK 也提供了支持。若要修改 源媒體項的開始和結束時間,您可以修改 Clips 屬性。如果只想對視頻的前六秒進行編碼,可 以使用類似以下的代碼:

src.Sources[0].Clips[0].StartTime = new TimeSpan(0);
src.Sources[0].Clips[0].EndTime = new TimeSpan(0, 0, 6);

若要添加其他視頻作為源文件,您可以將其他視頻附加到 MediaItem 的 Sources 屬性中。 這會將源文件按順序編碼到單一輸出文件中:

MediaItem src = new MediaItem (@"C:\WMdownloads\AdrenalineRush.wmv");
src.Sources.Add(new Source(@"C:\WMdownloads\Video2.wmv"));

實時編碼

Expression Encoder 還支持對來自實時源(如網絡攝像頭)的內容進行編碼。這個概念( 和代碼)與對視頻文件進行編碼類似,但是您需要使用一組不同的類。這些類可以在 Microsoft.Expression.Encoder.Live 命名空間中找到。

首先要使用的類是 LiveJob。LiveJob 類似 Encoder.Job,也是用來處理視頻編碼工作的。 但在實時方案中,OutputFormat 是 LiveJob 的屬性,而不是 MediaItem 對象(已經不需要該 對象)。當 LiveJob 對象被實例化時,它會尋找與計算機連接的視頻輸入設備,並填充 VideoDevices 和 AudioDevices 屬性。您隨後便可以將其用作編碼器的輸入源。圖 4 顯示了 一個示例。

Figure 4 對實時視頻進行編碼

using (LiveJob job = new LiveJob())
{
  LiveDevice videoDevice = job.VideoDevices[0];
  LiveDevice audioDevice = job.AudioDevices[0];
  LiveDeviceSource liveSource = job.AddDeviceSource(videoDevice,
    audioDevice);
  job.ActivateSource(liveSource);
  WindowsMediaBroadcastOutputFormat outputFormat = new
    WindowsMediaBroadcastOutputFormat();
  outputFormat.BroadcastPort = 8080;
  job.OutputFormat = outputFormat;
  Console.WriteLine("Press enter to stop encoding...");
  job.StartEncoding();
  Console.ReadLine();
  Console.WriteLine("Stopping");
  job.StopEncoding();
}

這將使用網絡攝像頭(假設您已經連接)啟動一個實時編碼會話,並在您本地計算機的端口 8080 上進行廣播。若要查看實時編碼,請打開 Windows Media Player 並選擇“文件”|“打 開 URL”,然後輸入 mms://localhost:8080。經過短時間的緩沖後,您應當可以看到來自網絡 攝像頭的視頻,但是會存在一段 20 至 30 秒的延遲。存在這段延遲是因為編碼和傳輸視頻流 需要一段時間。您應該可以使用此視頻作為 Windows Media Services 或 IIS Media Services 的源,對外進行廣播。

其他工具

如果不確定您選擇的編碼設置是否可以帶來所需的輸出質量,可以使用 Expression Encoder 3 UI 提供的名為 A/B Compare 的方便功能。該功能使您可以對位於當前播放位置附 近五秒鐘的視頻進行編碼。編碼後的視頻將會與原始視頻分屏並列顯示出來(請參見圖 5), 這樣您就可以輕松比較編碼後的視頻和原始視頻的質量。

圖 5 Expression Encoder 3 的 A/B Compare 功能

您隨後可以將當前設置保存為用戶定義的預設配置,方法是單擊“編輯”|“將當前設置保 存為預設配置”。該預設配置將保存為一個 XML 文件,可供在 SDK 中使用:

job.ApplyPreset(@"C:\WMdownloads\NewPreset.xml");

如果您已經想象過,通過控制台應用程序自動執行視頻轉換過程是多麼簡單的一件事,請看 看 Expression Encoder 的 Convert-Media PowerShell 模塊:convertmedia.codeplex.com。 這個 PowerShell 模塊包含了 Expression Encoder SDK,提供了一個命令行編碼界面,無需編 寫任何代碼。就像所有 CodePlex 項目一樣,它是一個開源模塊。

現在,希望您已經了解與視頻編碼相關的核心術語,並且在考慮使用哪些編解碼器和比特率 時能夠做出明智的決定。您還知道如何使用 Expression Encoder 3 SDK 針對特定目標(例如 Xbox 360、iPhone 和 Silverlight,以及實時流式視頻)進行視頻碼。所以,不要等到像 Clark W. Griswold 一樣將自己困在閣樓上,才意識到家庭視頻和被遺忘的記憶有多麼重要。 將它們轉換成所有人都可以觀看的格式。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved