Windows 10 UWP 18 of N: Use FFMPEG codec in UWP

  • 466
  • 0
  • UAP
  • 2018-01-21

介紹如何在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的檔案就是如下

  1. 刪除Link.exe
  2. 放入yasm.exe
  3. 放入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

這邊會遇到Master的Interop版本會因為ffmpeg更新了API所以會Build sample app會失敗!所以要先跳到Branch 3.0.1。

這樣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 的新技術拉~