使用Flash无缝播放来自不同文件的音轨?

时间:2012-01-01 17:29:03

标签: flash actionscript-3 networking audio

我的http服务器上有一些音频文件,我想在ActionScript3中编写一个Flash客户端来加载这些音频文件并顺利播放。当然,我可以创建一个Sound对象,并通过URL请求加载.load()。但是为了节省带宽,我更喜欢按需加载音频文件块。例如,有一个音频文件,比方说100MB。如果我们尝试在用户打开页面时尽快加载

<--------- 100MB ----------->

下载可能会在几分钟内完成,但是,如果用户中途停止听众,那么首先要加载整个音轨是浪费。

<--------- 100MB ----------->
   ^--- user may stop here

为了解决这个问题,我认为最好将大音频文件分成小块,根据需要加载和播放它们。

<--- 10MB ---><--- 10MB ---><--- 10MB ---> ...
                                     ^--- user current position

我想设计播放器,让它按块加载音频块,只在接近当前块的末尾加载它。

问题出现了 - 如何加载这些块并顺利播放?我可以为每个块创建Sound对象。但是如何无缝地发挥它们呢?

1 个答案:

答案 0 :(得分:1)

您可能希望使用SoundChannel,并查看exampletutorial。一旦你收到声音,你就可以播放声音,存储位置,并获得长度以找出剩余的时间。从那里,可能会发送一个事件来加载下一个声音。源于第二个例子(你必须把它作为你的类结构):

// Note that you will need some type of sound management 
// class to listen to events and to play the series of sounds.  
// That is not documented here.

import flash.events.Event; 
import flash.media.Sound; 
import flash.net.URLRequest; 

var snd:Sound = new Sound(); 
var req:URLRequest = new URLRequest("sound1.mp3"); 
snd.load(req); 

var channel:SoundChannel; 
channel = snd.play(); 
addEventListener(Event.ENTER_FRAME, onEnterFrame); 
channel.addEventListener(Event.SOUND_COMPLETE, onPlaybackComplete); 

function onEnterFrame(event:Event):void 
{ 
    var estimatedLength:int =  
        Math.ceil(snd.length / (snd.bytesLoaded / snd.bytesTotal)); 
    var playbackPercent:uint =  
        Math.round(100 * (channel.position / estimatedLength)); 
    if( playbackPercent > 75) 
        loadNextSound();
    trace("Sound playback is " + playbackPercent + "% complete."); 
} 

function loadNextSound() 
{
    // In whatever sound manager class you create, 
    // listen for this "loadNextSound" event, 
    // and start the next sound loading when it occurs.
    dispatchEvent(new Event("loadNextSound"));

}


function onPlaybackComplete(event:Event) 
{ 
    trace("The sound has finished playing."); 
    removeEventListener(Event.ENTER_FRAME, onEnterFrame); 
}