声音示例:Podcast PlayerFlash Player 9 和更高版本,Adobe AIR 1.0 和更高版本 播客是通过 Internet 以按需方式或订阅方式分发的声音文件。播客通常是作为系列的一部分发布的,此系列也称为播客频道。由于播客节目的持续时间从一分钟到数小时不等,因此,通常在播放的同时对其进行流式传输。播客节目(也称为项目)通常是以 mp3 文件格式提供的。视频播客也非常受欢迎,但此范例应用程序仅播放使用 mp3 文件的音频播客。 此示例并不是一个功能完备的播客聚合器应用程序。例如,它不能管理对特定播客的订阅,或在下次运行应用程序时记住用户已收听的播客。它可用作功能更完备的播客聚合器的起点。 Podcast Player 示例说明了以下 ActionScript 编程方法:
若要获取此范例的应用程序文件,请参阅 www.adobe.com/go/learn_programmingAS3samples_flash_cn。Podcast Player 应用程序文件位于文件夹 Samples/PodcastPlayer 中。该应用程序包含以下文件:
读取播客频道的 RSS 数据Podcast Player 应用程序先读取一些播客频道及其节目的相关信息: 1. 首先,应用程序读取包含播客频道列表的 XML 配置文件,并向用户显示该频道列表。 2. 当用户选择其中的一个播客频道时,应用程序会读取该频道的 RSS 新闻频道并显示频道节目列表。 此示例使用 URLLoader 实用程序类,从远程位置或本地文件检索基于文本的数据。Podcast Player 先创建一个 URLLoader 对象,以便从 playerconfig.xml 文件中获取采用 XML 格式的 RSS 新闻频道列表。接下来,当用户从列表中选择特定新闻频道时,将创建一个新的 URLLoader 对象以从该新闻频道的 URL 中读取 RSS 数据。 使用 SoundFacade 类简化声音加载和播放ActionScript 3.0 声音体系结构功能强大,但非常复杂。如果应用程序只需要基本的声音加载和播放功能,可使用通过提供一组更简单的方法调用和事件来隐藏某些复杂性的类。在软件设计模式领域中,这样的类称为“外观”。 SoundFacade 类表示用于执行以下任务的单个接口:
SoundFacade 类尝试以更简化的方式提供 ActionScript Sound 类的大部分功能。 以下代码显示了类声明、类属性以及 SoundFacade() 构造函数方法: public class SoundFacade extends EventDispatcher { public var s:Sound; public var sc:SoundChannel; public var url:String; public var bufferTime:int = 1000; public var isLoaded:Boolean = false; public var isReadyToPlay:Boolean = false; public var isPlaying:Boolean = false; public var isStreaming:Boolean = true; public var autoLoad:Boolean = true; public var autoPlay:Boolean = true; public var pausePosition:int = 0; public static const PLAY_PROGRESS:String = "playProgress"; public var progressInterval:int = 1000; public var playTimer:Timer; public function SoundFacade(soundUrl:String, autoLoad:Boolean = true, autoPlay:Boolean = true, streaming:Boolean = true, bufferTime:int = -1):void { this.url = soundUrl; // Sets Boolean values that determine the behavior of this object this.autoLoad = autoLoad; this.autoPlay = autoPlay; this.isStreaming = streaming; // Defaults to the global bufferTime value if (bufferTime < 0) { bufferTime = SoundMixer.bufferTime; } // Keeps buffer time reasonable, between 0 and 30 seconds this.bufferTime = Math.min(Math.max(0, bufferTime), 30000); if (autoLoad) { load(); } } SoundFacade 类扩展了 EventDispatcher 类,以使其能够调度自己的事件。类代码先声明 Sound 对象和 SoundChannel 对象的属性。该类还会存储声音文件 URL 的值以及对声音进行流式传输时使用的 bufferTime 属性。此外,它还接受某些影响加载和播放行为的布尔参数值:
bufferTime 参数的默认值为 -1。如果构造函数方法在 bufferTime 参数中检测到负值,它会将 bufferTime 属性设置为 SoundMixer.bufferTime 的值。这样,应用程序便可根据需要默认使用全局 SoundMixer.bufferTime 值。 如果将 autoLoad 参数设置为 true,构造函数方法将立即调用以下 load() 方法来开始加载声音文件: public function load():void { if (this.isPlaying) { this.stop(); this.s.close(); } this.isLoaded = false; this.s = new Sound(); this.s.addEventListener(ProgressEvent.PROGRESS, onLoadProgress); this.s.addEventListener(Event.OPEN, onLoadOpen); this.s.addEventListener(Event.COMPLETE, onLoadComplete); this.s.addEventListener(Event.ID3, onID3); this.s.addEventListener(IOErrorEvent.IO_ERROR, onIOError); this.s.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onIOError); var req:URLRequest = new URLRequest(this.url); var context:SoundLoaderContext = new SoundLoaderContext(this.bufferTime, true); this.s.load(req, context); } load() 方法创建一个新的 Sound 对象,然后为所有重要的声音事件添加侦听器。接下来,它通知 Sound 对象使用 SoundLoaderContext 对象传入 bufferTime 值以加载声音文件。 由于可以更改 url 属性,因此,可以使用 SoundFacade 实例来连续播放不同的声音文件:只需更改 url 属性并调用 load() 方法,即可加载新的声音文件。 以下三个事件侦听器方法说明了 SoundFacade 对象如何跟踪加载进度并确定何时开始播放声音: public function onLoadOpen(event:Event):void { if (this.isStreaming) { this.isReadyToPlay = true; if (autoPlay) { this.play(); } } this.dispatchEvent(event.clone()); } public function onLoadProgress(event:ProgressEvent):void { this.dispatchEvent(event.clone()); } public function onLoadComplete(event:Event):void { this.isReadyToPlay = true; this.isLoaded = true; this.dispatchEvent(evt.clone()); if (autoPlay && !isPlaying) { play(); } } 在开始加载声音时,将执行 onLoadOpen() 方法。如果可以使用流模式播放声音,onLoadComplete() 方法会立即将 isReadyToPlay 标志设置为 true。isReadyToPlay 标志确定应用程序能否开始播放声音,这可能为了响应用户动作,如单击“播放”按钮。SoundChannel 类管理声音数据的缓冲,因此在调用 play() 方法之前,不需要显式地检查是否加载了足够多的数据。 在加载过程中,将定期执行 onLoadProgress() 方法。它仅调度其 ProgressEvent 对象的克隆,该对象由使用此 SoundFacade 对象的代码使用。 当完全加载了声音数据后,将执行 onLoadComplete() 方法,以便为非声音流调用 play() 方法(如果需要)。下面显示了 play() 方法本身。 public function play(pos:int = 0):void { if (!this.isPlaying) { if (this.isReadyToPlay) { this.sc = this.s.play(pos); this.sc.addEventListener(Event.SOUND_COMPLETE, onPlayComplete); this.isPlaying = true; this.playTimer = new Timer(this.progressInterval); this.playTimer.addEventListener(TimerEvent.TIMER, onPlayTimer); this.playTimer.start(); } } } 如果已准备好播放声音,play() 方法将调用 Sound.play() 方法。生成的 SoundChannel 对象存储在 sc 属性中。play() 方法随后创建一个 Timer 对象,该对象用于按固定间隔调度播放进度事件。 显示播放进度创建 Timer 对象以实现播放监视是一个很复杂的操作,您只需对其编码一次。通过在可重用的类(如 SoundFacade 类)中封装此 Timer 逻辑,应用程序可以在加载和播放声音时侦听相同类型的进度事件。 由 SoundFacade.play() 方法创建的 Timer 对象每秒调度一个 TimerEvent 实例。每当新的 TimerEvent 到达时,就会执行以下 onPlayTimer() 方法: public function onPlayTimer(event:TimerEvent):void { var estimatedLength:int = Math.ceil(this.s.length / (this.s.bytesLoaded / this.s.bytesTotal)); var progEvent:ProgressEvent = new ProgressEvent(PLAY_PROGRESS, false, false, this.sc.position, estimatedLength); this.dispatchEvent(progEvent); } onPlayTimer() 方法可实现在监视播放一节中介绍的大小估计技术。然后,它创建一个事件类型为 SoundFacade.PLAY_PROGRESS 的新 ProgressEvent 实例,并将 bytesLoaded 属性设置 SoundChannel 对象的当前位置,而将 bytesTotal 属性设置为估计的声音数据长度。 暂停和恢复播放以前显示的 SoundFacade.play() 方法接受 pos 参数,该参数与声音数据中的起始位置相对应。如果 pos 值为零,则从开头开始播放声音。 SoundFacade.stop() 方法也接受 pos 参数,如下所示: public function stop(pos:int = 0):void { if (this.isPlaying) { this.pausePosition = pos; this.sc.stop(); this.playTimer.stop(); this.isPlaying = false; } } 每当调用 SoundFacade.stop() 方法时,它都会设置 pausePosition 属性,以便当用户要恢复播放相同的声音时应用程序知道将播放头放置在什么位置。 下面显示的 SoundFacade.pause() 和 SoundFacade.resume() 方法分别调用 SoundFacade.stop() 和 SoundFacade.play() 方法,以便每次传递 pos 参数值。 public function pause():void { stop(this.sc.position); } public function resume():void { play(this.pausePosition); } pause() 方法将当前的 SoundChannel.position 值传递给 play() 方法,后者将该值存储在 pausePosition 属性中。resume() 方法通过使用 pausePosition 值作为起点再次开始播放相同的声音。 扩展 Podcast Player 示例此示例呈示了一个框架 Podcast Player,用于说明如何使用可重用的 SoundFacade 类。您可以添加其他功能以改进此应用程序的用途,其中包括以下功能:
|
|