介紹如何在UWP中使用FFMPEG的Codec
正好最近有使用到FFMPEG的Codec,而這個骨董級的Codec真的是非常強大!
今天重點將會是在如何建置基礎的MediaPlayer並使用FFmpeg的Codec。
架設環境
Windows 10 x64
Windows 10 SDK 10586.212
Visual studio 2015 Update 2
接者開始來建立能夠Build C語言撰寫的ffmpeg的Source拉!
先從Github連結抓取新版的ffmpeg ( https://github.com/FFmpeg/FFmpeg )
下載好之後先安裝MSYS2(http://msys2.github.io/),需要安裝的版本i686是給32位元,x86_64是給64位元。
接者腦殘安裝法一直下一步就好~跑到 Completing the MSYS2 Wizard的時候執行起來能夠跳出視窗(如下圖)就是正常了!
接者安裝個別的Package
pacman -S make
pacman -S gcc
安裝好GCC之後記得把安裝路徑bin資料夾裡面的Link.exe刪除掉(C:\msys64\usr\bin\link.exe)
pacman -S perl
pacman -S diffutils
以上都安裝好之後就準備下個安裝流程YASM(http://yasm.tortall.net/Download.html)下載選擇Win64.exe或是Win32.exe版本,千萬別選用有VS2010為結尾的版本。
下載好的檔案重新命名成yasm.exe並且放在安裝目錄的bin資料夾下(C:\msys64\usr\bin\)
接者在下載 gas-preprocessor (https://github.com/FFmpeg/gas-preprocessor)把裡面的gas-preprocessor.pl檔案下載下來一樣放置在bin資料夾下(C:\msys64\usr\bin\)
所以會變更到的檔案在MSYS2內的bin的檔案就是如下
- 刪除Link.exe
 - 放入yasm.exe
 - 放入gas-preprocessor.pl
 
這樣就算是建立完成環境,接者來驗證環境是否設定正確。
開啟 VS2015的ARM Cross tool的命令提示字元。
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio 2015\Visual Studio Tools\Windows Desktop Command Prompts\VS2015 x86 ARM Cross Tools Command Prompt
分別驗證以下指令識別到的路徑是否正確!
$ which cl /c/Program Files (x86)/Microsoft Visual Studio 14.0/VC/BIN/x86_ARM/cl $ which link /c/Program Files (x86)/Microsoft Visual Studio 14.0/VC/BIN/x86_ARM/link $ which armasm /c/Program Files (x86)/Microsoft Visual Studio 14.0/VC/BIN/x86_ARM/armasm $ which yasm /usr/bin/yasm $ which cpp /usr/bin/cpp $ which gas-preprocessor.pl /usr/bin/gas-preprocessor.pl
成功如下
接者就可以正式開始Build ffmpeg的Code了!(Build的時間超久阿
Windows 10 x86 要使用 VS2015 x86 Native Tools Command Prompt 來設定以下三個變數
SET LIB=%VSINSTALLDIR%VC\lib\store;%VSINSTALLDIR%VC\atlmfc\lib;%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x86;;%UniversalCRTSdkDir%lib\%UCRTVersion%\um\x86;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\lib\um\x86;;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\Lib\um\x86 SET LIBPATH=%VSINSTALLDIR%VC\atlmfc\lib;%VSINSTALLDIR%VC\lib; SET INCLUDE=%VSINSTALLDIR%VC\include;%VSINSTALLDIR%VC\atlmfc\include;%UniversalCRTSdkDir%Include\%UCRTVersion%\ucrt;%UniversalCRTSdkDir%Include\%UCRTVersion%\um;%UniversalCRTSdkDir%Include\%UCRTVersion%\shared;%UniversalCRTSdkDir%Include\%UCRTVersion%\winrt;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\Include\um;
Windows 10 x64 要使用 VS2015 x64 Native Tools Command Prompt 來設定以下三個變數
SET LIB=%VSINSTALLDIR%VC\lib\store\amd64;%VSINSTALLDIR%VC\atlmfc\lib\amd64;%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\x64;;%UniversalCRTSdkDir%lib\%UCRTVersion%\um\x64;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\lib\um\x64;;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\Lib\um\x64 SET LIBPATH=%VSINSTALLDIR%VC\atlmfc\lib\amd64;%VSINSTALLDIR%VC\lib\amd64; SET INCLUDE=%VSINSTALLDIR%VC\include;%VSINSTALLDIR%VC\atlmfc\include;%UniversalCRTSdkDir%Include\%UCRTVersion%\ucrt;%UniversalCRTSdkDir%Include\%UCRTVersion%\um;%UniversalCRTSdkD ir%Include\%UCRTVersion%\shared;%UniversalCRTSdkDir%Include\%UCRTVersion%\winrt;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\Include\um;
Windows 10 Arm要使用 VS2015 ARM Cross Tools Command Prompt 來設定以下三個變數
SET LIB=%VSINSTALLDIR%VC\lib\store\ARM;%VSINSTALLDIR%VC\atlmfc\lib\ARM;%UniversalCRTSdkDir%lib\%UCRTVersion%\ucrt\arm;;%UniversalCRTSdkDir%lib\%UCRTVersion%\um\arm;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\lib\um\arm;;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\Lib\um\arm SET LIBPATH=%VSINSTALLDIR%VC\atlmfc\lib\ARM;%VSINSTALLDIR%VC\lib\ARM; SET INCLUDE=%VSINSTALLDIR%VC\include;%VSINSTALLDIR%VC\atlmfc\include;%UniversalCRTSdkDir%Include\%UCRTVersion%\ucrt;%UniversalCRTSdkDir%Include\%UCRTVersion%\um;%UniversalCRTSdkDir%Include\%UCRTVersion%\shared;%UniversalCRTSdkDir%Include\%UCRTVersion%\winrt;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.6\Include\um;
接者不管CPU的架構都是一樣的流程,先到MSYS2的安裝目錄下並Call msys2_shell.bat檔案,然後切換目錄到Git clone的ffmpeg目錄路徑。
接者再以不同CPU架構輸入不同的Command
Windwos 10 x86
mkdir -p Output/Windows10/x86 cd Output/Windows10/x86 ../../../configure \ --toolchain=msvc \ --disable-programs \ --disable-d3d11va \ --disable-dxva2 \ --arch=x86 \ --enable-shared \ --enable-cross-compile \ --target-os=win32 \ --extra-cflags="-MD -DWINAPI_FAMILY=WINAPI_FAMILY_APP -D_WIN32_WINNT=0x0A00" \ --extra-ldflags="-APPCONTAINER WindowsApp.lib" \ --prefix=../../../Build/Windows10/x86 make make install
Windows 10 x64
mkdir -p Output/Windows10/x64 cd Output/Windows10/x64 ../../../configure \ --toolchain=msvc \ --disable-programs \ --disable-d3d11va \ --disable-dxva2 \ --arch=x86_64 \ --enable-shared \ --enable-cross-compile \ --target-os=win32 \ --extra-cflags="-MD -DWINAPI_FAMILY=WINAPI_FAMILY_APP -D_WIN32_WINNT=0x0A00" \ --extra-ldflags="-APPCONTAINER WindowsApp.lib" \ --prefix=../../../Build/Windows10/x64 make make install
Windows 10 ARM
mkdir -p Output/Windows10/ARM cd Output/Windows10/ARM ../../../configure \ --toolchain=msvc \ --disable-programs \ --disable-d3d11va \ --disable-dxva2 \ --arch=arm \ --as=armasm \ --cpu=armv7 \ --enable-thumb \ --enable-shared \ --enable-cross-compile \ --target-os=win32 \ --extra-cflags="-MD -DWINAPI_FAMILY=WINAPI_FAMILY_APP -D_WIN32_WINNT=0x0A00 -D__ARM_PCS_VFP" \ --extra-ldflags="-APPCONTAINER WindowsApp.lib" \ --prefix=../../../Build/Windows10/ARM make make install
Build好之後都Source檔案會在Build/Windows 10 / { CPU型別 }
另外一個提供給UWP的開發人員的好方法,先去GitHub clone下來MSFT的 FFmpegInterop ( https://github.com/Microsoft/FFmpegInterop ) ,使用裡面寫好的BuildFFmpeg.bat就可以幫你輸入好指令並且將適當的DLL放置在Sample中。需要把原始的FFmpeg的Git放在ffmpeg的資料夾下!
BuildFFmpeg.bat 有如下的指令
BuildFFmpeg.bat win10                     - Build for Windows 10 ARM, x64, and x86
BuildFFmpeg.bat phone8.1 ARM              - Build for Windows Phone 8.1 ARM only
BuildFFmpeg.bat win8.1 x86 x64            - Build for Windows 8.1 x86 and x64 only
BuildFFmpeg.bat phone8.1 win10 ARM        - Build for Windows 10 and Windows Phone 8.1 ARM only
BuildFFmpeg.bat win8.1 phone8.1 win10     - Build all architecture for all target platform
這樣Build Sample就不會出現錯誤了!接者開啟UWP的Sample,會有以下Windows Runtime Component 的專案目錄!
接者在新增一APP並且參考FFmpegInterop的專案以及加入ffmpeg build好的DLL 路徑大致上會是(\FFmpegInterop\ffmpeg\Build\Windows10\x86\bin)需要根據UWP的Debug CPU型別進行調整
接者在MainPage.xaml的變更如下
<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <MediaElement x:Name="mediaPlayer" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
    </Grid>
    <Page.BottomAppBar>
        <CommandBar>
            <CommandBar.PrimaryCommands>
                <AppBarButton Label="pick" Icon="Upload" Click="AppBarButton_Click"/>
            </CommandBar.PrimaryCommands>
        </CommandBar>
    </Page.BottomAppBar>
</Page>
然後在 AppBatButton_Click的Event寫下如下的Code
private async Task OpenLocalFileAsync()
        {
            var picker = new FileOpenPicker();
            picker.ViewMode = PickerViewMode.Thumbnail;
            picker.SuggestedStartLocation = PickerLocationId.VideosLibrary;
            picker.FileTypeFilter.Add("*");
            var file = await picker.PickSingleFileAsync();
            if (file != null)
            {
                using (var fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read))
                {
                    try
                    {
                        ffmpegMss = FFmpegInteropMSS.CreateFFmpegInteropMSSFromStream(fileStream, false, false);
                        var mediaSrc = ffmpegMss.GetMediaStreamSource();
                        if (mediaSrc != null)
                            mediaPlayer.SetMediaStreamSource(mediaSrc);
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.WriteLine(ex.Message);
                    }
                }
            }
        }
        private async void AppBarButton_Click(object sender, RoutedEventArgs e)
        {
            await OpenLocalFileAsync();
        }
這樣就可以選擇FFmpeg所支援Codec的影音檔案了!
總結:Codec這塊使用FFmpeg真的能夠支援到非常廣泛的影音格式!如果想自己打造自己Style的Media player app可以參考這個Codec。
***以上Code以及說明都有可能隨著Windows 10 的版本以及Visual Studio 2015版本有所調整!***
參考資料 MSDN, Github
下次再分享Windows 10 的新技術拉~