=====================================================

最简单的基于FFmpeg的移动端样例系列文章列表:

最简单的基于FFmpeg的移动端样例:Android HelloWorld

最简单的基于FFmpeg的移动端样例:Android 视频解码器

最简单的基于FFmpeg的移动端样例:Android 视频解码器-单个库版

最简单的基于FFmpeg的移动端样例:Android 推流器

最简单的基于FFmpeg的移动端样例:Android 视频转码器

最简单的基于FFmpeg的移动端样例附件:Android 自带播放器

最简单的基于FFmpeg的移动端样例附件:SDL Android HelloWorld

最简单的基于FFmpeg的移动端样例:IOS HelloWorld

最简单的基于FFmpeg的移动端样例:IOS 视频解码器

最简单的基于FFmpeg的移动端样例:IOS 推流器

最简单的基于FFmpeg的移动端样例:IOS 视频转码器

最简单的基于FFmpeg的移动端样例附件:IOS自带播放器

最简单的基于FFmpeg的移动端样例:Windows Phone HelloWorld

=====================================================

本文记录Windows Phone平台下基于FFmpeg的HelloWorld程序。该演示样例C语言的源码来自于《最简单的基于FFMPEG的Helloworld程序》。相关的概念就不再反复记录了。

因为在FFmpeg移动端开发方面仅仅有Android和IOS的实战经验。所以我一開始的时候仅仅做了Android和IOS的演示样例程序。

前两天要參加微软的Windows 10发布会,会前浏览信息的时候发现Windows 10在视音频处理方面已经加入了对FFmpeg的原生支持。同一时候微软还发布了一个开源项目FFmpegInterop。专门用于给Windows 8.1/10 App编译包括FFmpeg功能的类库。出于好奇我便下载并捣鼓了一下FFmpegInterop这个project,终于总结了一个FFmpeg在Windows Phone 平台的 HelloWorld的演示样例程序。

Windows Phone平台下使用FFmpeg类库的说明

Windows Phone平台(Windows App Store。Windows应用商店)使用FFmpeg类库的流程例如以下所看到的。

1. 编译FFmpeg类库

(1)前提须要安装VS2013和MSYS2(最好已经能够成功使用这两个工具编译PC上使用的FFmpeg)。

(2)获得FFmpegInteropproject(该project位于Github上面,地址为https://github.com/Microsoft/FFmpegInterop)。

(3)加入FFmpeg源码。

从官网上下载源码后,将源码解压到FFmpegInterop的ffmpeg文件夹下。

(4)以管理员的身份启动“VS2013 开发者命令提示”控制台。切换到FFmpegInterop文件夹。

(5)配置MSYS2。执行以下命令设置MSYS2_BIN环境变量(这里依据MSYS2的安装路径不同而不同):

set MSYS2_BIN="E:\msys64\usr\bin\bash.exe"

(6)处理一个小Bug。须要把MSYS2中的link.exe改个名字(随便改一个就可以,比如“link_msys.exe”)。因为MSYS2中的link.exe和VS2013中的link.exe重名了,假设不改名字的话会系统就会错误地使用MSYS2的link.exe(而不是VS2013的link.exe)。从而导致编译失败。不知道是不是全部的机子都有这个问题,当时确实卡了我一段时间。

(7)执行命令编译类库。

直接执行BuildFFmpeg.bat会打印帮助菜单。执行以下这条语句就能够编译Windows8.1 x86平台的类库。编译成功后的类库位于“ffmpeg\Build\Windows8.1\x86”文件夹下。

BuildFFmpeg win8.1 x86

执行以下的语句会同一时候编译Windows8.1 x86和x64平台的类库。

BuildFFmpeg win8.1 x86 x64

其他的编译命令不再详述,能够查看帮助菜单。本步骤获得的FFmpeg类库就能够用于Windows App Store程序的开发了。

PS:这里生成的dll与平时用于控制台或者MFC程序中的dll是不一样的。这里的dll是加了AppContainer 的flag的dll。假设使用普通的控制台程序调用这里生成的dll。就会报错“0xc000a200”:
Error 0xc000a200: shows up when regular process (not inside an AppContainer) tries to load DLL that was marked with AppContainer flag。

(8)打开samples文件夹下的sln解决方式[可选]。这一步sln解决方式中包括了FFmpegInterop库源码project以及一些演示样例程序。这部分的源码还没有细看(本文暂不涉及这部分代码的内容)。

2. 编写Windows Phone平台下的程序

(1)新建一个“Windows应用商店”程序。位于“文件->新建->项目->Visual C++->Windows应用商店->空白应用程序(XAML)”。

(2)将编译后的类库拷贝至该项目文件夹下(注意x86、x64等这些平台要相应)。

新建include文件夹存储头文件(*.h)。lib文件夹存储导入库文件(*.lib);并将动态库文件(*.dll)直接拷贝至文件夹下。

(3)配置类库。分成以下3步:

a) 头文件配置
解决方式资源管理器->右键单击项目->属性面板
属性面板->C/C++->常规->附加包括文件夹。输入“include”(刚才拷贝头文件的文件夹)
b) 导入库配置
属性面板->链接器->常规->附加库文件夹,输入“lib”(刚才拷贝库文件的文件夹)
属性面板->链接器->输入->附加依赖项,输入“avcodec.lib; avformat.lib; avutil.lib; avdevice.lib; avfilter.lib; swresample.lib; swscale.lib”(导入库的文件名称)
c) 动态库配置(重要而有特色的一步)
解决方式资源管理器->右键单击项目->加入->现有项,将dll文件加入进来
选中每一个dll文件->右键单击->属性->常规->内容,设定为“是”

(4) 測试

a) 编辑界面
在MainPage.xaml中加入一个Buttonbutton,并加入一个“Button_Clicked()”响应函数。

<Page
x:Class="testApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:testApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <StackPanel Margin="120,30,0,0">
<TextBlock HorizontalAlignment="Left" Text="My FFmpeg test" FontSize="36"/>
<Button Content="Configure Info" Click="Button_Clicked"/>
<TextBlock x:Name="greetingOutput"/>
</StackPanel>
</Page>

b) 编辑代码
在MainPage.xaml.cpp中加入一个Button_Clicked()的代码。例如以下所看到的。

void MainPage::Button_Clicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
{
//greetingOutput->Text = "Hello, Lei"; USES_CONVERSION;
String ^info = ref new String(A2W(avcodec_configuration()));
Windows::UI::Popups::MessageDialog(info).ShowAsync();
}

该代码调用了avcodec_configuration()获取FFmpeg类库的配置信息。然后调用MessageDialog()弹出一个对话框显示这些信息。注意当中使用了atlconv.h中的一个A2W()的宏。用于把char *转换为Platform::String。

在MainPage.xaml.cpp头部加入用到的头文件,例如以下所看到的。

#include <atlconv.h>

extern "C"{
#include "libavcodec/avcodec.h"
}

在MainPage.xaml.h加入响应函数的声明,例如以下所看到的。

	public ref class MainPage sealed
{
public:
MainPage();
void Button_Clicked(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
};

假设一切配置都没有问题的话。Windows App的执行结果例如以下图所看到的。单击左上角的button就会弹出FFmpeg类库的配置信息。

(5) 其他资源
有关Windows App C++开发的具体资源能够參考MSDN上的《使用 C++ 创建你的第一个通用 Windows 应用》相关的文章。

源码

Simplest FFmpeg WinPhone HelloWorld项目的文件夹结构如图所看到的。C++源码位于MainPage.xaml.cpp中。界面布局文件为MainPage.xaml。

MainPage.xaml是界面布局文件。内容例如以下所看到的。

<!-- Simplest FFmpeg WinPhone HelloWorld -->
<Page
x:Class="simplest_ffmpeg_winphone_helloworld.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:simplest_ffmpeg_winphone_helloworld"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <StackPanel Margin="120,30,0,0">
<TextBlock HorizontalAlignment="Left" Text="Simplest FFmpeg WinPhone HelloWorld" FontSize="36"/>
<TextBlock Text="Click button to see FFmpeg lib's information"/>
<StackPanel Orientation="Horizontal" Margin="0,20,0,20">
<Button Content="Protocol" Click="click_protocol" Width="120" HorizontalAlignment="Left"/>
<Button Content="AVFormat" Click="click_avformat" Width="120" HorizontalAlignment="Left"/>
<Button Content="AVCodec" Click="click_avcodec" Width="120" HorizontalAlignment="Left"/>
<Button Content="AVFilter" Click="click_avfilter" Width="120" HorizontalAlignment="Left"/>
<Button Content="Configuration" Click="click_configuration" Width="120" HorizontalAlignment="Left"/>
</StackPanel>
<TextBlock x:Name="information" Margin="0,20,0,20"/>
</StackPanel>
</Page>

MainPage.xaml.cpp是C++函数实现文件。内容例如以下所看到的。

/**
* 最简单的Windows Phone平台下FFmpeg的HelloWorld样例
* Simplest FFmpeg WinPhone HelloWorld
*
* 雷霄骅 Lei Xiaohua
* leixiaohua1020@126.com
* 中国传媒大学/数字电视技术
* Communication University of China / Digital TV Technology
* http://blog.csdn.net/leixiaohua1020
*
* 本程序是移植FFmpeg到Windows App平台的最简单程序。它能够打印出FFmpeg类库的下列信息:
* Protocol: FFmpeg类库支持的协议
* AVFormat: FFmpeg类库支持的封装格式
* AVCodec: FFmpeg类库支持的编解码器
* AVFilter: FFmpeg类库支持的滤镜
* Configure: FFmpeg类库的配置信息
*
* This is the simplest program based on FFmpeg in Windows App Platform. It can show following
* informations about FFmpeg library:
* Protocol: Protocols supported by FFmpeg.
* AVFormat: Container format supported by FFmpeg.
* AVCodec: Encoder/Decoder supported by FFmpeg.
* AVFilter: Filters supported by FFmpeg.
* Configure: configure information of FFmpeg.
*
*/ #include "pch.h"
#include "MainPage.xaml.h"
#include <atlconv.h> #define __STDC_CONSTANT_MACROS
extern "C"
{
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavfilter/avfilter.h"
}; using namespace simplest_ffmpeg_winphone_helloworld; using namespace Platform;
using namespace Windows::Foundation;
using namespace Windows::Foundation::Collections;
using namespace Windows::UI::Xaml;
using namespace Windows::UI::Xaml::Controls;
using namespace Windows::UI::Xaml::Controls::Primitives;
using namespace Windows::UI::Xaml::Data;
using namespace Windows::UI::Xaml::Input;
using namespace Windows::UI::Xaml::Media;
using namespace Windows::UI::Xaml::Navigation;
using namespace Windows::UI::Popups; MainPage::MainPage()
{
InitializeComponent();
} /**
* Protocol Support Information
*/
void MainPage::click_protocol(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e){ //FIX
struct URLProtocol; char info[40000] = {0};
av_register_all(); struct URLProtocol *pup = NULL;
//Input
struct URLProtocol **p_temp = &pup;
avio_enum_protocols((void **)p_temp, 0);
while ((*p_temp) != NULL){
sprintf_s(info, sizeof(info), "%s[In ][%10s]\n", info, avio_enum_protocols((void **)p_temp, 0));
}
pup = NULL;
//Output
avio_enum_protocols((void **)p_temp, 1);
while ((*p_temp) != NULL){
sprintf_s(info, sizeof(info), "%s[Out][%10s]\n", info, avio_enum_protocols((void **)p_temp, 1));
} USES_CONVERSION;
String ^infostr = ref new String(A2W(info));
information->Text = infostr; } /**
* AVFormat Support Information
*/ void MainPage::click_avformat(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e){ char info[40000] = { 0 }; av_register_all(); AVInputFormat *if_temp = av_iformat_next(NULL);
AVOutputFormat *of_temp = av_oformat_next(NULL);
//Input
while (if_temp != NULL){
sprintf_s(info, sizeof(info), "%s[In ] %10s\n", info, if_temp->name);
if_temp = if_temp->next;
}
//Output
while (of_temp != NULL){
sprintf_s(info, sizeof(info), "%s[Out] %10s\n", info, of_temp->name);
of_temp = of_temp->next;
} USES_CONVERSION;
String ^infostr = ref new String(A2W(info));
information->Text = infostr; } /**
* AVCodec Support Information
*/
void MainPage::click_avcodec(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e){ char info[40000] = { 0 }; av_register_all(); AVCodec *c_temp = av_codec_next(NULL); while (c_temp != NULL){
if (c_temp->decode != NULL){
sprintf_s(info, sizeof(info), "%s[Dec]", info);
}
else{
sprintf_s(info, sizeof(info), "%s[Enc]", info);
}
switch (c_temp->type){
case AVMEDIA_TYPE_VIDEO:
sprintf_s(info, sizeof(info), "%s[Video]", info);
break;
case AVMEDIA_TYPE_AUDIO:
sprintf_s(info, sizeof(info), "%s[Audio]", info);
break;
default:
sprintf_s(info, sizeof(info), "%s[Other]", info);
break;
} sprintf_s(info, sizeof(info), "%s %10s\n", info, c_temp->name); c_temp = c_temp->next;
} USES_CONVERSION;
String ^infostr = ref new String(A2W(info));
information->Text = infostr; } /**
* AVFilter Support Information
*/
void MainPage::click_avfilter(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e){ char info[40000] = { 0 };
avfilter_register_all();
AVFilter *f_temp = (AVFilter *)avfilter_next(NULL);
while (f_temp != NULL){
sprintf_s(info, sizeof(info), "%s[%10s]\n", info, f_temp->name);
} USES_CONVERSION;
String ^infostr = ref new String(A2W(info));
information->Text = infostr; } /**
* Configuration Information
*/
void MainPage::click_configuration(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e){ char info[10000] = { 0 };
av_register_all(); sprintf_s(info, sizeof(info), "%s\n", avcodec_configuration()); USES_CONVERSION;
String ^infostr = ref new String(A2W(avcodec_configuration()));
//information->Text = infostr; MessageDialog(infostr).ShowAsync(); }

执行结果

程序执行后界面例如以下图所看到的。单击不同的button会显示FFmpeg类库不同方面的信息。

单击“Configure”button的时候会以消息框的形式打印配置信息。

下载

simplest ffmpeg mobile
项目主页

Github:https://github.com/leixiaohua1020/simplest_ffmpeg_mobile

开源中国:https://git.oschina.net/leixiaohua1020/simplest_ffmpeg_mobile

SourceForge:https://sourceforge.net/projects/simplestffmpegmobile/

本解决方式包括了使用FFmpeg在移动端处理多媒体的各种样例:

[Android]
simplest_android_player: 基于安卓接口的视频播放器
simplest_ffmpeg_android_helloworld: 安卓平台下基于FFmpeg的HelloWorld程序
simplest_ffmpeg_android_decoder: 安卓平台下最简单的基于FFmpeg的视频解码器
simplest_ffmpeg_android_decoder_onelib: 安卓平台下最简单的基于FFmpeg的视频解码器-单库版
simplest_ffmpeg_android_streamer: 安卓平台下最简单的基于FFmpeg的推流器
simplest_ffmpeg_android_transcoder: 安卓平台下移植的FFmpeg命令行工具
simplest_sdl_android_helloworld: 移植SDL到安卓平台的最简单程序
[IOS]
simplest_ios_player: 基于IOS接口的视频播放器
simplest_ffmpeg_ios_helloworld: IOS平台下基于FFmpeg的HelloWorld程序
simplest_ffmpeg_ios_decoder: IOS平台下最简单的基于FFmpeg的视频解码器
simplest_ffmpeg_ios_streamer: IOS平台下最简单的基于FFmpeg的推流器
simplest_ffmpeg_ios_transcoder: IOS平台下移植的ffmpeg.c命令行工具
simplest_sdl_ios_helloworld: 移植SDL到IOS平台的最简单程序
[Windows]
simplest_ffmpeg_windowsphone_helloworld: Windows Phone平台下基于FFmpeg的HelloWorld程序

最简单的基于FFmpeg的移动端样例:Windows Phone HelloWorld的更多相关文章

  1. 最简单的基于FFmpeg的移动端样例:Android HelloWorld

    ===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...

  2. 最简单的基于FFmpeg的移动端样例:IOS HelloWorld

    ===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...

  3. 最简单的基于FFmpeg的移动端样例:Android 视频解码器-单个库版

    ===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...

  4. 最简单的基于FFmpeg的移动端样例:IOS 视频解码器

    ===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...

  5. 最简单的基于FFmpeg的移动端样例附件:Android 自带播放器

    ===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...

  6. 最简单的基于FFmpeg的移动端样例附件:SDL Android HelloWorld

    ===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...

  7. 最简单的基于FFmpeg的移动端样例:IOS 视频转码器

    ===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...

  8. 最简单的基于FFmpeg的移动端样例:IOS 推流器

    ===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...

  9. 最简单的基于FFmpeg的移动端样例:Android 视频转码器

    ===================================================== 最简单的基于FFmpeg的移动端样例系列文章列表: 最简单的基于FFmpeg的移动端样例:A ...

随机推荐

  1. phonegap在eclipse上的安装

    1.首先安装好eclipse 2.下载安装好sdk 3.下载安装好adt 4.在这个地方下载好phonegap的包,https://codeload.github.com/phonegap/phone ...

  2. 【洛谷4770/UOJ395】[NOI2018]你的名字(后缀数组_线段树合并)

    题目: 洛谷4770 UOJ395 分析: 一个很好的SAM应用题-- 一句话题意:给定一个字符串\(S\).每次询问给定字符串\(T\)和两个整数\(l\).\(r\),求\(T\)有多少个本质不同 ...

  3. 微信接口本地调试(IIS服务器)

    1.下载ngrok,并注册获得token.官网下载地址:https://ngrok.com/ 如果你是在官网下载的,到后面映射域名的时候会要求购买他们的服务. 这里我们用一个国内免费的ngrok服务器 ...

  4. 6.10---mybatis中两张表查询数据dao层

  5. 【转】Java 集合系列12之 TreeMap详细介绍(源码解析)和使用示例

    概要 这一章,我们对TreeMap进行学习.我们先对TreeMap有个整体认识,然后再学习它的源码,最后再通过实例来学会使用TreeMap.内容包括:第1部分 TreeMap介绍第2部分 TreeMa ...

  6. [ BZOJ 3038 & 3211 / SPOJ GSS4 ] 上帝造题七分钟2 / 花神游历各国

    \(\\\) \(Description\) 给出一个长度为\(N\)的数列,共进行\(M\)次操作: \(1\ L\ R\):查询\([L,R]\)区间和. \(2\ L\ R\):对\([L,R] ...

  7. 关于编辑器对<input>标签报错提示“表单输入没有相关label”的问题

    相信很多朋友在制作表单的时候,我们的编辑器会有下图的相关提示吧 我们发现虽然这样并不影响我们的正常使用,但是看着这样的报错提示总是很让人心烦,那么这到底是为什么呢? 其实,这是因为编辑器建议我们在使用 ...

  8. 在Mac安装Scheme

    我也不知道安装的是Scheme这门语言还是编程环境还是其他的什么东西,反正能在控制台运行Scheme代码了.... 谁能告诉我怎么在sublime使用scheme.... 原地址 首先下载安装MIT- ...

  9. dubbo之路由规则

    向注册中心写入路由规则:(通常由监控中心或治理中心的页面完成) RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader ...

  10. utf-8与unicode是什么关系

    简单来说: Unicode  is a charset. ------Unicode 他就是一个字符集 UTF-8 is encoding style. --------UTF-8他就是一种编码方式, ...