[Windows 8 App]多媒體-----【音頻與視頻的轉碼】(下)
前台設計完畢後,我們開啟【MainPage.xaml.cs】來寫後台的程式碼
後台的程式碼有點多,請慢慢看
首先在應用程式的構造方法中使用 TranscodeVideoFile 方法,以便完成轉碼的操作
public MainPage()
{
this.InitializeComponent();
TranscodeVideoFile();
//執行轉碼操作
}
接下來寫 TranscodeVideoFile 方法,程式碼如下
這是轉碼操作的程式碼
async void TranscodeVideoFile()
{
Windows.Storage.StorageFile sourcce;
Windows.Storage.StorageFile destination;
//建立FileOpenPicker的對象
var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
//設置初始選取文件的位置
openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
//設置選取文件的類型
openPicker.FileTypeFilter.Add(".mp4");
openPicker.FileTypeFilter.Add(".avi");
//啟動選擇器並取得文件
sourcce = await openPicker.PickSingleFileAsync();
//建立 FileSavePicker 的對象
var savePicker = new Windows.Storage.Pickers.FileSavePicker();
//設置文件儲存位置
savePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
//設置文件
savePicker.DefaultFileExtension = ".mp4";
//設置文件名
savePicker.SuggestedFileName = "New Video";
//設置可儲存的文件類型
savePicker.FileTypeChoices.Add("MPEG4", new string[] { ".mp4" });
//啟動文件的保存器
destination = await savePicker.PickSaveFileAsync();
//執行轉碼的TranscoderFile方法
TranscodeFile(sourcce, destination);
}
在上面的代碼中,先建立一個FileOpenPicker的對象OpenPicker,是用來選取要轉碼的文件
再來看到OpenPicker的SuggestedStartLocation屬性,這是用來選取文件的位置
OpenPicker的FileTypeFilter屬性,是用來篩選文件的類型
之後就使用PickSingleFileAsync來啟動文件的選擇器
並將選擇的文件儲存在StorageFile的Source對象中
再來建立一個FileSavePicker的對象SavePicker,這是要用來儲存轉碼完成後的媒體文件
然後,並設定SuggestedStartLocation屬性來指定儲存的位置
使用DefaultFileExtension屬性,來設定文件轉碼後的格式
SuggestedFileName屬性,是設定轉碼後文件的名稱
再使用FileTypeChoices屬性,來設定可儲存的文件類型
這時使用savePicker的PickSaveFileAsync方法來啟動文件保存器
並將文件儲存在StorageFile的destination對象中
這些是上面程式碼的部分
下面是TranscodeVideoFile()中的TranscodeFile方法程式碼
這個方法中有兩個StorageFile的參數,分別是轉碼操作的來源文件和目標文件
程式碼如下:
async void TranscodeFile(StorageFile srcFile, StorageFile destFile)
{
MediaEncodingProfile profile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD720p);
//創建編碼配置文件
MediaTranscoder transcoder = new MediaTranscoder();
//建立一個MediaTranscoder用於媒體文件的轉碼
PrepareTranscodeResult prepareOp = await transcoder.PrepareFileTranscodeAsync(srcFile, destFile, profile);
//PrepareFileTranscodeAsync方法是非同步的,轉碼的動作在後台,應用程式介面能可以正常反應
if (prepareOp.CanTranscode)
{
var transcodeOp = prepareOp.TranscodeAsync();
transcodeOp.Progress += new AsyncActionProgressHandler<double>(TranscodeProgress);
//新增TranscodeProgress方法,在應用程式介面顯示轉碼的進度
transcodeOp.Completed += new AsyncActionWithProgressCompletedHandler<double>(TranscodeComplete);
//新增TranscodeComplete方法,在應用程式介面顯示晚誠、取消的訊息
}
else
{
//向應用程式介面顯示錯誤訊息
switch (prepareOp.FailureReason)
{
case TranscodeFailureReason.CodecNotFound:
txtDisplay.Text = "未找到解碼器! ";
break;
case TranscodeFailureReason.InvalidProfile:
txtDisplay.Text = "無效的編碼文件! ";
break;
default:
txtDisplay.Text = "未知錯誤! ";
break;
}
}
}
VideoEncodingQuality.HD720p 這是設置轉碼的目標分辨率
HD720p 表示 1280x720 像素
建立一個MediaTranscoder類型的對象transcoder,用來文件的轉碼
用transcoder對象PrepareFileTranscodeAsync的方法
並對方法傳入來源文件srcFile、目標文件destFile、編碼配置的文件對象profile
將這方法傳回的值儲存在PrepareTranscodeResult的prepareOp中
然後prepareOp的CanTranscode屬性,是判斷是否可以進行轉碼操作
如果可以轉碼的話,則使用prepareOp的TranscodeAsync()方法來進行轉碼
並將轉碼的值傳回給transcodeOp
接著對transcodeOp的Progress和Completed事件添加TranscodeProgress和TranscodeComplete的事件處理方法
這兩個方法是用來向應用程式界面顯示轉碼的進度和轉碼完成、取消的訊息
接下來是transcodeOp的Progress事件的事件處理方法TranscodeProgress() 之程式碼:
async void TranscodeProgress(IAsyncActionWithProgress<double> asyncInfo, double percent)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
txtProgress.Text = "轉碼進度:" + percent.ToString().Split('.')[0] + "%";
});
}
上面是轉碼進度的訊息
下面是transcodeOp的Completed事件的事件處理方法TranscodeComplete() 之程式碼:
async void TranscodeComplete(IAsyncActionWithProgress<double> asyncInfo, AsyncStatus status)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
if (asyncInfo.Status == AsyncStatus.Completed)
{
txtDisplay.Text = "轉碼操作已完成.";
}
else if (asyncInfo.Status == AsyncStatus.Canceled)
{
txtDisplay.Text = "轉碼操作已取消.";
}
else
{
txtDisplay.Text = asyncInfo.ErrorCode.Message;
}
});
}
上面是顯示轉碼的完成、取消訊息
我們把所有程式碼做個整合:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Media.MediaProperties;
using Windows.Media.Transcoding;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Storage;
// 空白頁項目範本已記錄在 http://go.microsoft.com/fwlink/?LinkId=234238
namespace MediaTrans
{
/// <summary>
/// 可以在本身使用或巡覽至框架內的空白頁面。
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
TranscodeVideoFile();
//執行轉碼操作
}
async void TranscodeVideoFile()
{
Windows.Storage.StorageFile sourcce;
Windows.Storage.StorageFile destination;
//建立FileOpenPicker的對象
var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
//設置初始選取文件的位置
openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
//設置選取文件的類型
openPicker.FileTypeFilter.Add(".mp4");
openPicker.FileTypeFilter.Add(".avi");
//啟動選擇器並取得文件
sourcce = await openPicker.PickSingleFileAsync();
//建立 FileSavePicker 的對象
var savePicker = new Windows.Storage.Pickers.FileSavePicker();
//設置文件儲存位置
savePicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
//設置文件
savePicker.DefaultFileExtension = ".mp4";
//設置文件名
savePicker.SuggestedFileName = "New Video";
//設置可儲存的文件類型
savePicker.FileTypeChoices.Add("MPEG4", new string[] { ".mp4" });
//啟動文件的保存器
destination = await savePicker.PickSaveFileAsync();
//執行轉碼的TranscoderFile方法
TranscodeFile(sourcce, destination);
}
async void TranscodeFile(StorageFile srcFile, StorageFile destFile)
{
MediaEncodingProfile profile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD720p);
//創建編碼配置文件
MediaTranscoder transcoder = new MediaTranscoder();
//建立一個MediaTranscoder用於媒體文件的轉碼
PrepareTranscodeResult prepareOp = await transcoder.PrepareFileTranscodeAsync(srcFile, destFile, profile);
//PrepareFileTranscodeAsync方法是非同步的,轉碼的動作在後台,應用程式介面能可以正常反應
if (prepareOp.CanTranscode)
{
var transcodeOp = prepareOp.TranscodeAsync();
transcodeOp.Progress += new AsyncActionProgressHandler<double>(TranscodeProgress);
//新增TranscodeProgress方法,在應用程式介面顯示轉碼的進度
transcodeOp.Completed += new AsyncActionWithProgressCompletedHandler<double>(TranscodeComplete);
//新增TranscodeComplete方法,在應用程式介面顯示晚誠、取消的訊息
}
else
{
//向應用程式介面顯示錯誤訊息
switch (prepareOp.FailureReason)
{
case TranscodeFailureReason.CodecNotFound:
txtDisplay.Text = "未找到解碼器! ";
break;
case TranscodeFailureReason.InvalidProfile:
txtDisplay.Text = "無效的編碼文件! ";
break;
default:
txtDisplay.Text = "未知錯誤! ";
break;
}
}
}
//下面是顯示轉碼進度的訊息
async void TranscodeProgress(IAsyncActionWithProgress<double> asyncInfo, double percent)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
txtProgress.Text = "轉碼進度:" + percent.ToString().Split('.')[0] + "%";
});
}
//下面是顯示轉碼完成、取消的訊息
async void TranscodeComplete(IAsyncActionWithProgress<double> asyncInfo, AsyncStatus status)
{
await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{
if (asyncInfo.Status == AsyncStatus.Completed)
{
txtDisplay.Text = "轉碼操作已完成.";
}
else if (asyncInfo.Status == AsyncStatus.Canceled)
{
txtDisplay.Text = "轉碼操作已取消.";
}
else
{
txtDisplay.Text = asyncInfo.ErrorCode.Message;
}
});
}
/// <summary>
/// 在此頁面即將顯示在框架中時叫用。
/// </summary>
/// <param name="e">描述如何到達此頁面的事件資料。Parameter
/// 屬性通常用來設定頁面。</param>
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
}
}
這是轉碼的畫面:
轉碼中
轉碼完畢