WM Format SDK 简介

Windows Media Format SDKWindows Media SDK中的一部分。是WM SDK中最底层的组件。WM Format SDK的主要目的是使开发者能播放、编写、修改、加密、发行ASF文件。

 

 

ASF文件的创建

       ASF文件的创建是个高层的、比较简单的。文件创建是由一个writer对象来管理。你可以通过指定一个profile对象来告诉writer对象需要创建文件的种类。

在内部,writer对象主要做三件事:首先,如果一个sample所在的stream是被压缩的,writer就需要联系编解码器(codec)去解压(MSDN有误)它。其次,一旦sample符合被profile所定义的形式,writersample分割为适当的大小并入包(packet)中,以便在网络中流通。最后,来自各种流的数据是多路复用或交错的,所以具有类似呈现时间的样品(sample)在ASF文件的数据部分是写在相近的位置的。

并不是writer完全自己去写一个文件,它需要和一些对象合作,这些对象称作接收端(sink)。它们是用来分发来自writer的数据到目的点。在写本地文件的情况下,一个文件接收端管理向本地文件写入数据。你也可以配置网络接收端在网上分发ASF数据。通常使用不止一个接收端。比如,一个程序能够收集网上的数据产生一个本地文件。通过使用推(push)接收端,你可以将你的程序所写的内容广播给一个或多个运行着Windows Media Services的服务端,然后这些服务端会向用户发布内容。

 

ASF文件的编辑

       编译一个ASF文件的内容必须重写文件。WM Format SDK并不提供任何操作数据部分的接口。对于一些简单的编辑,比如合并两个文件,从一个文件中截取一部分内容,你可以读取未解压的样本,然后将它们写入一个新的具有相同头信息的文件里。更复杂的编辑涉及到修改一个新文件的配置文件。

 

ASF文件的读取

       WM Format SDK提供两个读取文件的对象:reader对象和synchronous reader对象。后者必须在WMFSDK 9及以后的版本才能使用。它们主要的区别是:reader向你的程序分发样本是通过产生消息来调用callback方法,而synchronous reader是直接通过函数调用。

 

 

 

ASF 文件

ASF是一个可扩展性的文件格式,它主要是用来存储、播放同步的数字媒体流,并将他们在网上传播。

ASF格式的主要目的是:

<1> 支持来自媒体服务器、HTTP服务器以及本地存储设备的高效率的回放

<2> 支持诸如音频和视频可伸缩的媒体类型

<3> 允许将一个单一的多媒体组合在一个广泛的带宽上展现出来

<4> 允许作者控制媒体流的环境,特别是在一个限制带宽的环境中

<5> 与任何多媒体组合系统、操作系统或数据交流协议无关

 

ASF是由一些叫做对象(object)的部分组成。有三个最高顶层的对象:头部对象(Header object)、数据对象(Data object)、索引对象(Index object)。前两者是必须的,第三个是可选的。

头部对象(Header object) 包括了基本的文件信息,如文件大小、流的数目、错误校正方法、使用的编码器、元数据(Metadata)也存储在这里。

数据对象(Data object) 包括组织成包(packet)的流数据。

索引对象(Index object) 包括一个相关的时间戳与关键帧对列表。用于让程序能高效地在文件中查找。

每个对象开始与一个全球唯一标识符(GUID)和一个大小值。这使得文件读取器能在可辨认的对象中分析信息。下图显示一个ASF文件的组成:

 

 

 

 

 

 

 

Profile文件

 

 

 

 

 

 

开发环境配置

 

 

 

 

 

包含目录:

 

库目录:

 

代码设置:

#include <wmsdk.h>

#pragma comment( lib, "Wmvcore.lib" )

 

 

配置文件是一个用来描述ASF文件的数据集合。一个配置文件至少必须包括一个流的配置。配置文件中的流信息包括:位率(bit rate)、缓冲窗口(buffer window)、媒体属性(media properties)、编码器(codec)等。除此之外,配置文件中也可以包含ASF文件各种特性信息,比如互斥(Mutual Exclusion)、流优化(Stream Prioritization)、带宽共享(Bandwidth Sharing)、数据单元扩展(Data Unit Extensions)

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以通过以下代码获取当前最顶层的Window对象: ```java WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); Window topWindow = null; if (wm != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { topWindow = wm.getCurrentWindowMetrics().getWindow(); } else { List<WindowManager.LayoutParams> paramsList = new ArrayList<>(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); // 重复获取多次,确保获取到最顶层的Window wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); wm.getDefaultDisplay().getRealMetrics(new DisplayMetrics()); for (WindowManager.LayoutParams params : wm.getDefaultDisplay().getRealSize().getWindowLayoutInDisplayCutout().getMaxSizeParams()) { paramsList.add(params); } } else { for (int i = 0; i < wm.getDefaultDisplay().getWidth(); i += 10) { for (int j = 0; j < wm.getDefaultDisplay().getHeight(); j += 10) { View view = new View(this); WindowManager.LayoutParams params = new WindowManager.LayoutParams(); params.width = 10; params.height = 10; params.x = i; params.y = j; params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE; params.format = PixelFormat.TRANSLUCENT; wm.addView(view, params); paramsList.add(params); } } } if (!paramsList.isEmpty()) { Collections.sort(paramsList, new Comparator<WindowManager.LayoutParams>() { @Override public int compare(WindowManager.LayoutParams o1, WindowManager.LayoutParams o2) { return o1.token == null ? -1 : (o2.token == null ? 1 : Integer.compare(o1.token.hashCode(), o2.token.hashCode())); } }); WindowManager.LayoutParams topParams = paramsList.get(paramsList.size() - 1); topWindow = new PhoneWindow(this); topWindow.setAttributes(topParams); } } } ``` 需要注意的是,该方法在 Android 11 及以上版本中使用 `WindowManager#getCurrentWindowMetrics()` 获取最顶层的Window对象,而在 Android 10 及以下版本中则使用遍历所有Window的方式获取最顶层的Window对象,这种方式可能会导致性能问题。因此,建议在 Android 11 及以上版本中使用 `WindowManager#getCurrentWindowMetrics()` 获取最顶层的Window对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值