Adobe
产品
Acrobat
Creative Cloud
创意套装
Digital Marketing Suite
Digital Publishing Suite
Elements
Photoshop
Touch Apps
更多产品
解决方案
数字营销
数字媒体
教育
金融服务业
政府部门
网页体验管理
更多解决方案
学习帮助下载公司
商店
在线商店
批量许可
查找经销商
搜索
 
信息 登录
欢迎,我的支持
我的帐户
注销
为何登录?登录后可以管理您的帐户,访问试用版下载、产品扩展和社区区域等。
Adobe
产品 分类 购买   搜索  
解決方案 公司
学习
登录 注销 我的货物 我的支持
Date Date
Qty:
Subtotal
Checkout
Adobe 开发者中心 / Adobe AIR 开发人员中心 /

使用 AIR 2 NativeProcess API 创建屏幕记录软件

作者 Benjamin Dobler

Benjamin Dobler
  • www.richapps.de

创建日期

10 June 2010

页面工具

在 Facebook 上共享
在 Twitter 上共享
在 LinkedIn 上共享
书签
打印

Tags

要求

必备知识

一定的 ActionScript 经验会有所帮助。

用户级别

中级

必需产品

  • Flash Builder (下载试用版)

范例文件

  • screenrecording.zip (11 KB)

其他要求

VLC

  • 了解更多信息

FFmpeg

  • 了解更多信息

设置项目

按照这些步骤在 Flash Builder 中设置项目:

  1. 下载并解压本文附带的范例文件。
  2. 在 Flash Builder 中,选择“文件”>“导入 Flex 项目 FXP ”。
  3. 导航并选择刚才解压缩的 screenrecording.fxp 文件。
  4. 单击“完成”。
    要构建项目,您还需要安装 AIR 2 SDK。
  5. 从 Adobe 实验室下载 AIR 2 SDK。
  6. 根据发行说明中的指示了解如何使用 Flex SDK 叠加 Adobe AIR SDK。
    接下来,您需要更新编译器设置以使用新的 SDK。
  7. 在包资源管理器中右键单击项目,然后选择“属性”。
  8. 依次选择“Flex 编译器”,“使用特定 SDK”和“新 SDK”。
  9. 运行“项目”>“清理”。

您可以在项目中找到两个应用程序(Screenrecording_VideoOnly.mxml 和 Screenrecording_VideoSound.mxml)。第一个应用程序说明如何只记录屏幕。第二个应用程序以第一个为构建基础,并增加了记录声音的功能。

使用 VLC 记录屏幕

您可能知道 VLC 是一个可播放几乎所有音频和视频文件的媒体播放器,但它的功能远不止这些。它是一个全面的媒体框架,可用于对各种类型的数据、甚至流媒体进行代码转换。它不太知名的功能之一是能够记录用户的屏幕。

VLC 屏幕记录功能的一个缺点是无法同时记录屏幕和音频。在本文中,我们将使用 AIR 2 中的另一个新增功能(记录麦克风输入的能力)修复这个问题。

将应用程序作为本机应用程序进行准备

为了在您的应用程序中使用新的 NativeProcess 类,您需要在应用程序描述符文件中添加一行内容:

<supportedProfiles>extendedDesktop</supportedProfiles>

您可以在 Screenrecording_VideoOnly-app.xml 和 Screenrecording_VideoSound-app.xml 中找到上面这一行。

它告诉编译器您创建的不是普通的 AIR 文件,而是本机应用程序,它有访问外部应用程序等扩展权限。

屏幕记录代码在类 de.benz.exec.ScreenRecorder 中。要使用这个类,将它传递给要用作 File 对象的命令行应用程序。在实际应用程序中,您需要处理不同平台上的不同文件路径。例如,在 Mac OS X 上,VLC 程序的默认路径是 /Applications/VLC.app/Contents/MacOS/VLC 在 Windows 上,它通常为 C:\Program Files\VideoLAN\VLC\vlc.exe。一个解决方案是将外部应用程序与本机安装程序一起打包,然后使用 File 类的常量独立于用户的平台访问二进制文件。另一个解决方案是在应用程序第一次启动时由用户选择路径。为了简便起见,本示例中对路径进行了硬编码;您可能需要根据系统情况调整它们。

要在 AIR 中创建本机进程,您需要将一个 NativeProcessStartupInfo 对象实例化,它将存储实际启动该进程的所有必需信息;例如:

var startupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo(); startupInfo.executable = vlcFile;

将 NativeProcessStartupInfo 对象实例化后,您将指向 VLC 可执行文件的 File 对象传递给它。

设置命令行参数

现在,您需要提供命令行参数。NativeProcessStartupInfo 对象有一个属性 arguments,它是一个包含所有必要参数的 Vector。

可以通过命令行完全控制 VLC。但是,您在大多数情况下通过 VLC 提供的界面使用它,因此决定要使用哪些参数有点困难。经过一番研究,我得出以下组合:

-I rc --rc-fake-tty screen:// :screen-fps=15 :screen-caching=100 :sout=#transcode{venc=x264{bframes=0,nocabac,ref=1,nf,level=13,crf=24,partitions=none},vcodec=h264,fps=15,vb=3000, width=1024,height=740,acodec=none}:duplicate{dst=std{mux=mp4,access=file, dst='Set target file path here'}}

要测试这些参数,您可以直接在命令行试用它们。

包装在 Vector 对象中的该命令如下:

var processArgs:Vector.<String> = new Vector.<String>(); processArgs.push("-I"); processArgs.push("rc"); processArgs.push("--rc-fake-tty"); processArgs.push("screen://"); processArgs.push(":screen-fps=15"); processArgs.push(":screen-caching=100"); processArgs.push(":sout=#transcode{venc=x264{bframes=0,nocabac,ref=1,nf,level=13,crf=24,partitions=none},vcodec=h264,fps=15,vb=3000,width=1024,height=740,acodec=none}:duplicate{dst=std{mux=mp4,access=file,dst='"+targetFile.nativePath+"'}}"); startupInfo.arguments = processArgs;

主要参数为:

  • -I rc 它告诉 VLC 不应使用标准 VLC 界面启动,而应作为一个不可见进程。rc 代表远程控制,允许您与运行的进程交互。
  • --rc-fake-tty 它告诉 VLC 将通过标准输入 (STDIN) 和标准输出 (STDOUT) 控制它。
  • screen:// 它告诉 VLC 您要将计算机屏幕用作输入信号。
  • :screen-fps=15 它设置 VLC 尝试截屏的帧频。应当谨慎选择,因为它对性能的影响很大。屏幕记录通常是一项处理器密集型操作。过高的帧频可能令系统无法响应。在我的系统中,帧频 15 效果良好并且对于大多数屏幕记录任务应当足够了。
  • :sout 该参数用于设置屏幕记录编码的所有参数,包括最终视频的编解码器选项、帧频、比特率和尺寸。您可以通过各种组合设置这些选项。对于此例,只要确保它编码为 Flash Player 支持的视频文件即可。提供的示例使用 H.264 对屏幕记录进行编码。请注意,我将音频选项设置为 none ( acodec=none ),这是因为 VLC 不支持同时记录屏幕和音频。
  • :duplicate 它设置容器格式(对于 mp4)以及所生成视频的目标。它还告诉 VLC 生成一个物理文件 (access=file)。

NativeProcessStartupInfo 对象现已完成,您可以通过新建一个 NativeProcess 对象创建实际流程,为标准输出、错误和退出事件添加事件监听器:

p = new NativeProcess(); p.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData); p.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, onErrorData); p.addEventListener(NativeProcessExitEvent.EXIT, onExit);

错误和输出事件处理函数只是将结果跟踪到控制台。

private function onOutputData(evt:ProgressEvent):void{ var outputData:String = p.standardOutput.readUTFBytes(p.standardOutput.bytesAvailable); trace(outputData); } private function onErrorData(evt:ProgressEvent):void{ var errorData:String = p.standardError.readUTFBytes(p.standardError.bytesAvailable); trace(errorData); }

要启动进程,调用 NativeProcess 对象的 start() 方法,并将 NativeProcessStartupInfo 对象作为一个参数进行传递。

p.start(startupInfo);

与运行的进程通信

现在,进程正在运行并且 VLC 正在记录屏幕。要停止记录,只杀死进程还不够,因为这会导致视频文件受损。您必须与运行的进程通信,此处通过标准输入 (STDIN) 进行通信。在 AIR 2 中,您可以使用 NativeProcess 类的 standardInput 属性,将数据发送到一个运行的进程管道。standardInput 属性的类型为 IDataOutput,所以您可以像 ByteArray 一样写入它。在 ScreenRecorder.as 中,stopRecording() 用于停止记录进程:

public function stopRecording():void{ p.standardInput.writeUTFBytes("stop" + "\n"); setTimeout(kill,4000); }

此方法编写一个停止命令,后跟一个换行符。换行符与在终端窗口中按回车键发出命令的效果相同。

该命令触发 VLC 正确关闭记录视频的文件流。随后,即可安全退出 VLC。但是,由于编写实际文件所需的时间稍长,代码通过一个超时延迟这一任务,使 VLC 能首先完成编写操作并关闭文件。

要退出进程,kill() 方法发出一个退出命令,如下:

private function kill():void{ p.standardInput.writeUTFBytes("quit" + "\n"); isRecording = false; dispatchEvent(new Event(Event.COMPLETE)); }

此时,视频已创建,它将载入 Screenrecording_VideoOnly.mxml 的 WindowedApplication 的 onComplete 处理函数中的 VideoDisplay 对象。

private function onComplete(evt:Event):void{ vPlayer.source = screenRecorder.targetFile.url; }

第一部分到此结束。您现在有了一个可记录用户屏幕的工具。目前,文件只包含视频数据,没有音频数据。在下一部分中,您将使用 AIR 的本机麦克风记录功能记录麦克风声音。

使用 AIR 2 记录音频

在上一部分中,您学会了如何使用 VLC 记录没有声音的视频数据。幸运的是,AIR 2 引入了从连接的麦克风访问原始 PCM 声音数据的功能。在 AIR 2 之前,从线路输入记录声音的唯一方法是将记录的字节通过 NetConnection 发送到 Flash Media Server 实例,而 NetConnection 对于大多数桌面应用程序并不是最佳的。

在 AIR 2 中,开发人员可以通过新的 SampleDataEvent.SAMPLE_DATA 事件直接访问麦克风,该事件由 Microphone 类的一个实例引发。

首先,您希望用户有机会为记录选择一个已连接设备。您可以通过为用户界面添加一个 ComboBox 做到这一点,该界面有一个已连接麦克风的列表:

<s:ComboBox id="mic_cb" dataProvider="{new ArrayCollection(Microphone.names)}" selectedIndex="0" />

这只需要在主应用程序类中添加一行 MXML。以上代码添加一个 ComboBox,其中数据提供程序设置为包装在 ArrayCollection 中的 Microphone 类的静态属性 names。

实际记录逻辑在类 de.benz.screenrecording.AudioRecorder 中。AudioRecorder.as 中的 startRecording 方法将两个参数作为参数。第一个是输入设备的选定索引,第二个是对将存储所记录的声音数据的文件的引用。

要开始记录,您首先必须配置麦克风。通过调用 Microphone 类的静态函数 getMicrophone(),获得一个麦克风实例。

microphone = Microphone.getMicrophone(micIndex); microphone.setSilenceLevel(0); microphone.rate = 44; microphone.addEventListener(SampleDataEvent.SAMPLE_DATA, onMicData);

为了确保麦克风即使在没有声音时也持续记录,请将静音级别设置为零。microphone.rate = 44; 用于设置声音采样率,它决定了每秒从输入信号采样的数量(本例中为 44100)。

最后一步中,需要为 SampleDataEvent.SAMPLE_DATA 添加一个事件监听器,用于调用 onMicData 函数。

下一步是创建用于编写声音字节的流。文件流以 APPEND 模式打开,这样记录过程中每次写入文件时,将新字节添加到文件最后。为此,您还需要确保在打开流之前删除目标文件;否则,字节将添加到之前的记录部分。

if(targetFile.exists){ targetFile.deleteFile(); } outputStream = new FileStream(); outputStream.open(targetFile, FileMode.APPEND); soundBytes = new ByteArray();

声音字节的实际编写在 onMicData 方法中进行,SampleDataEvent.SAMPLE_DATA 事件在记录过程中将反复调用它。该事件有一个 data 属性,此属性是一个包含已记录声音样本的 ByteArray。每个声音样本是一个正常值在 -1 和 1 之间的 32 位浮点数,可使用 readFloat() 方法从字节数组读取它。

protected function onMicData(sampleData:SampleDataEvent):void { while(sampleData.data.bytesAvailable){ sample = sampleData.data.readFloat(); outputStream.writeShort(sample*32767); // normalize for bitrate 16 } }

要在之后使用这些字节,需要将值转换为 16 位签名整数,它们可以包含 -32768 和 +32767 之间的值。要执行转换,只需将运算值乘以 32767。随即使用 writeShort() 将样本写入文件流。

要停止记录,将删除 SampleDataEvent.SAMPLE_DATA 事件监听器并关闭文件流。

public function stopRecording():void { microphone.removeEventListener(SampleDataEvent.SAMPLE_DATA, onMicData); outputStream.close(); }

如果运行应用程序,它将生成两个文件:无声的 H.264 视频文件以及一个包含声音原始字节的文件。在下一部分和最后一个部分中,您将使用 FFmpeg 合并这两个文件并生成一个包含视频和音轨的文件。

使用 FFmpeg 合并音频和视频

FFmpeg 是一个用于处理各种媒体文件的跨平台应用程序。它可以通过命令行实现完全控制,并且理解现在的大多数常用视频和音频编解码器和文件格式。它的命令行使用方式及跨平台性质使它成为 AIR 应用程序的理想之选。在本部分中,您将了解如何将 FFmpeg 用作一个外部进程,将视频轨道与原始声音字节合并起来。

VideoSoundMerger 类的一般设置与 ScreenRecorder 类十分相似,因为它也运行本机进程。传递到 NativeProcessStartupInfo 对象的进程参数不同。并且,不必与运行的进程交互,因为它只处理命令并且在完成时自动关闭。以下是使用 FFmpeg 合并声音和视频轨道所使用的命令行参数:

-isync -f s16be -i <PATH TO SOUND FILE> -i <PATH TO VIDEO FILE> -acodec libfaac -ab 128 -vcodec copy
  • -isync 它告诉 FFmpeg 将视频与音轨同步。
  • -f s16be 它告诉 FFmpeg 音轨的样本是按大端法作为 16 位整数编码的。
  • -i <PATH TO SOUND FILE> 它用于传递声音文件的路径。
  • -i <PATH TO VIDEO FILE> 它用于传递视频文件的路径。
  • -acodec libfaac 它告诉 FFmpeg 为视频轨道使用高级音频编码 (aac) 编码器。
  • -ab 128 它告诉 FFmpeg 以比特率 128 对声音进行编码。
  • -vcodeccopy 它告诉 FFmpeg 使用输入视频的编解码器。这很实用,因为视频无需再次编码,不仅节省了时间,还能生成质量更高的视频。

在 ActionScript 中,这些参数如下:

var processArgs:Vector.<String> = new Vector.<String>(); processArgs.push("-isync"); processArgs.push("-f"); processArgs.push("s16be"); processArgs.push("-i"); processArgs.push(soundFile.nativePath); processArgs.push("-i"); processArgs.push(videoFile.nativePath); processArgs.push("-acodec"); processArgs.push("libfaac"); processArgs.push("-ab"); processArgs.push("128"); processArgs.push("-vcodec"); processArgs.push("copy"); processArgs.push(targetFile.nativePath);

调用 p.start startupInfo 启动 FFmpeg 后,它将生成屏幕记录的最终视频文件。

后续工作

本文涵盖 AIR 2 中的新 NativeProcess API 和麦克风功能的基础知识。NativeProcess API 为扩展 AIR 应用程序带来许多机会。您可能已经想到它令人兴奋的一些用途。

要获得更多灵感,请访问 Adobe AIR 开发人员中心或观看 Adobe AIR 2 新增功能视频。

 

Tutorials & Samples

Tutorials

  • Retrieving a list of network interfaces in Adobe AIR 2
  • Writing multiscreen AIR apps
  • Using the AIR 2 NativeProcess API to create a screen recorder
  • Resolving DNS records in Adobe AIR 2

Samples

  • Using the Salesbuilder Adobe AIR sample application

Adobe AIR Forums

More
04/11/2012 Surround sound 5.1 with Air 3.2 on desktop app?
12/12/2011 Live Streaming H.264 Video on iOS using AIR
04/17/2012 HTMLLoader - Google Maps?
04/12/2012 Tabindex in forms on mobile?

Adobe AIR Blog

More
05/15/2012 What’s New in Flash Player 11.2 and Adobe AIR 3.2 Slides and...
05/14/2012 Adobe Flash Platform Runtime and SDK Archives
05/14/2012 Monster’s Socks on the iPad with Adobe AIR
05/10/2012 What’s New in Flash Player 11.2 and Adobe AIR 3.2

产品

  • Acrobat
  • Creative Cloud
  • Creative Suite
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Elements
  • 移动应用程序
  • Photoshop
  • Touch Apps

解决方案

  • 数字营销
  • 数字媒体
  • 网页体验管理

行业

  • 教育
  • 金融服务业
  • 政府部门

帮助

  • 产品帮助中心
  • 订货和退货
  • 下载和安装
  • 我的 Adobe

学习

  • Adobe 开发人员连接
  • Adobe TV
  • 培训和认证
  • 论坛
  • 设计中心

购买方式

  • 在线商店
  • 批量许可
  • 查找经销商

下载

  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR
  • Adobe Shockwave Player

公司

  • 新闻编辑室
  • 合作伙伴计划
  • 公司社会责任
  • 工作机会
  • 投资者关系
  • 事件
  • 法律
  • 安全
  • 联系 Adobe
选择您的地区 中国(更改)
选择您的地区 关闭

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Österreich - Deutsch
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Hrvatska
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • Suomi
  • France
  • Deutschland
  • Magyarország
  • Ireland
  • Israel - English
  • ישראל - עברית
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • الشرق الأوسط وشمال أفريقيا - اللغة العربية
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Polska
  • Portugal
  • România
  • Россия
  • Srbija
  • Slovensko
  • Slovenija
  • España
  • Sverige
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2012 Adobe Systems Incorporated. All rights reserved.

使用条款 | 隐私政策和 Cookies (更新)

京 ICP 备 10217899 号 京公网安备 110105010404