[Windows 8 App]多媒體-----【音頻與視頻的剪輯】

[Windows 8 App]多媒體-----【音頻與視頻的剪輯】

在應用中提供剪輯文件的功能,可以方便用戶進行簡單的剪輯處理

剪輯的意思是擷取一段的音頻或視頻後,並儲存起來做為新的文件,這就是剪輯

對文件剪輯時,需要設置兩個剪輯點,一個起始點、一個結束點

這兩個點指定了輸出後的文件起始點和結束點

下面是設置剪輯點的程式碼:

 


public MainPage()
        {
            this.InitializeComponent();
            TranscodeVideoFile();
            //執行轉碼操作
            MediaTranscoder transcoder = new MediaTranscoder();
            //建立一個MediaTranscoder對象

            transcoder.TrimStartTime = new TimeSpan(0, 0, 1);
            //設置起始的剪輯點

            transcoder.TrimStopTime = new TimeSpan(0, 0, 9);
            //設置結束的剪輯點
            
        }

 

上面的程式碼是先建立MediaTranscoder的對象transcoder

接著使用transcoder的TrimStartTime屬性來設置剪輯文件的起始點

使用TrimStopTime屬性來設置文件的結束剪輯點

然後就可以根據這兩個剪輯點重新編碼文件

來達到剪輯文件的功能

 

我們根據之前介紹的轉碼的範例做些修改就能達到文件的剪輯操作

只需要在TranscoderFile方法中添加剪輯點的程式碼即可

 


async void TranscodeFile(StorageFile srcFile, StorageFile destFile)
        {
            MediaEncodingProfile profile = MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD720p);
            //創建編碼配置文件

            MediaTranscoder transcoder = new MediaTranscoder();
            //建立一個MediaTranscoder用於媒體文件的轉碼

            transcoder.TrimStartTime = new TimeSpan(0, 0, 1);
            //設置起始的剪輯點

            transcoder.TrimStopTime = new TimeSpan(0, 0, 9);
            //設置結束的剪輯點

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

 

在上方的TranscoderFile方法程式碼中

主要是新增前面兩行剪輯的程式碼

transcoder.TrimStartTime = new TimeSpan(0, 0, 1); //設置起始的剪輯點

transcoder.TrimStopTime = new TimeSpan(0, 0, 9); //設置結束的剪輯點

 

執行的結果應該是和轉碼的畫面一樣

但是,可以仔細的看一下剪輯後的影片時間已經是程式碼所設定的時間了

 

剪輯前的設計畫面:

97

 

 

剪輯後的設計畫面:

98

 

完整程式碼【MainPage.xaml】:


<Page
    x:Class="MediaTrans.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MediaTrans"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock x:Name="txtDisplay" HorizontalAlignment="Left" Height="114" Margin="260,260,0,0" TextWrapping="Wrap" Text="正在轉碼..." VerticalAlignment="Top" Width="912" FontSize="72" TextAlignment="Center" />
        <TextBlock x:Name="txtProgress" HorizontalAlignment="Left" Height="114" Margin="260,500,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="912" FontSize="72" TextAlignment="Center" />
    </Grid>
</Page>

 

完整程式碼【MainPage.xaml.cs】:


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;

// 空白頁項目範本已記錄在 http://go.microsoft.com/fwlink/?LinkId=234238

namespace MediaTrans
{
    /// <summary>
    /// 可以在本身使用或巡覽至框架內的空白頁面。
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            TranscodeVideoFile();
            //執行轉碼操作
            MediaTranscoder transcoder = new MediaTranscoder();
            //建立一個MediaTranscoder對象

            transcoder.TrimStartTime = new TimeSpan(0, 0, 1);
            //設置起始的剪輯點

            transcoder.TrimStopTime = new TimeSpan(0, 0, 9);
            //設置結束的剪輯點
            
        }

        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用於媒體文件的轉碼

            transcoder.TrimStartTime = new TimeSpan(0, 0, 1);
            //設置起始的剪輯點

            transcoder.TrimStopTime = new TimeSpan(0, 0, 9);
            //設置結束的剪輯點

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