求助:声音采样播放问题
本帖最后由 wgq341 于 2018-12-24 19:46 编辑如题:声音不能跨域采样播放;
代码是根据以前一个网络上的SWF文件反编修改的
//所有注释是我自己的理解,也不知道对否
var SAMPLE_SIZE:int = 8192;//声音样本的数目
var SOUND_RATE:int = 44100;//声音的频率44100
var sound:Sound;//声音对象
var sampler:Sound;//采集样本的声音对象
var soundChannel:SoundChannel = new SoundChannel();//声音通道对象
var startPos:uint = 0;//采样开始点
var seekpoint:uint;//记录采样的位置
var bufferTime:int = 3000;//缓冲区的时间(毫秒)
var bufferInterval:Number;//缓冲记时器
/********播放*****************/
//http://image.hnol.net/c/swf/2018-12/24/18/201812241810585961-2768212.swf是一个mp3声音地址
initPlay("http://image.hnol.net/c/swf/2018-12/24/18/201812241810585961-2768212.swf");
function initPlay(url:String):void
{
sound=new Sound();
sound.load(new URLRequest(url));
sampler=new Sound();
sampler.addEventListener(SampleDataEvent.SAMPLE_DATA,sampleDataHandler);
start();
}
/************取样***********************/
//好像这个方法不能用了(采集不到声音数据)
function sampleDataHandler(event:SampleDataEvent):void
{
var bytes:ByteArray = new ByteArray;
var length:int = startPos + SAMPLE_SIZE > sampleTotal ? sampleTotal - startPos:SAMPLE_SIZE;
/*提取其声音数据:从bytes的0开始,读取length个字节放到byteArray里,byteArray从byteArray.position开始放. (bytes的position不变, byteArray的position增加)*/
sound.extract(bytes,length,startPos);
event.data.writeBytes(bytes);
startPos +=length;
}
/*******sampler播放************/
function start():void
{
startPos = seekpoint;
if (soundChannel)
{
soundChannel.stop();
soundChannel.removeEventListener(Event.SOUND_COMPLETE,soundCompleteHandler);
}
soundChannel = sampler.play();
soundChannel.addEventListener(Event.SOUND_COMPLETE,soundCompleteHandler);
}
/*************播放完毕*************/
function soundCompleteHandler(event:Event):void
{
if (isComplete)
{
trace("*** complete ***")
initPlay("http://image.hnol.net/c/swf/2018-12/24/18/201812241810585961-2768212.swf");
}
else
{
if (buffering)
{
bufferInterval = setInterval(bufferUpdate,30);
}
else
{
start();
}
}
}
/*************缓冲************/
function bufferUpdate():void
{
if (! buffering)
{
clearInterval(bufferInterval);
start();
}
}
/*************采样的方法**********************/
/*采样的位置*/
function get samplePosition():Number
{
return soundChannel.position/1000*SOUND_RATE;
}
/*样本总数*/
function get sampleTotal():uint
{
return duration/1000*SOUND_RATE;
}
/*播放时间*/
function get playheadTime():uint
{
return Math.ceil(samplePosition+seekpoint)/SOUND_RATE*1000;
}
/*************总时间************/
function get duration():Number
{
return sound.length/(sound.bytesLoaded/sound.bytesTotal);
}
/*缓冲条件的布尔值*/
function get buffering():Boolean
{
var buffer:Boolean;
var cachedTime:int = duration - bufferTime;
if (sound.length <= cachedTime)
{
buffer = sound.length < playheadTime + bufferTime;
}
return buffer;
}
/*播放整个文件完毕布尔值*/
function get isComplete():Boolean
{
var complete:Boolean=Math.ceil(playheadTime/1000)>0&&Math.ceil(playheadTime/1000)>=Math.floor(duration/1000);
return complete;
}
本帖最后由 心羽 于 2018-12-26 17:45 编辑
wgq341 发表于 2018-12-25 13:25
本地测试没有问题(不存在跨域);上传网络就不行了。
以前的晨风播放器就是用的这方法可以跨域访问(提 ...
学习到了,我这边复现的情况和你描述的一样!
定位到sound.extract在网页中会报错,没数据,然后就直接channel stop了。报错是SecurityError #2122 安全沙箱冲突
也就是跨域的情况下,又没有cross_domain一类的配置,是不能用这个方法随意播放音频了。
跨域是,本身因为安全限制会某些信息读取不到 本帖最后由 心羽 于 2018-12-25 11:56 编辑
头一次看到采样播放的方式,具体我想自己做点实验再说
好像没什么问题啊,发布设置里调整成访问网络文件就可以了
TKCB 发表于 2018-12-25 07:48
跨域是,本身因为安全限制会某些信息读取不到
问好T大,此方法以前是可以跨域提取数据数据的,现在不知道 什么原因不行了。 wgq341 发表于 2018-12-25 13:20
问好T大,此方法以前是可以跨域提取数据数据的,现在不知道 什么原因不行了。 ...
那可能是FP升级了限制导致的吧,或许是没配置好XML之类的问题 心羽 发表于 2018-12-25 11:37
头一次看到采样播放的方式,具体我想自己做点实验再说
本地测试没有问题(不存在跨域);上传网络就不行了。
以前的晨风播放器就是用的这方法可以跨域访问(提取数据);
问好! 我试了下,把文件的类型设为为android类播放的即air类的就可以了,先用flash的是不可以的 心羽 发表于 2018-12-25 11:37
头一次看到采样播放的方式,具体我想自己做点实验再说
可能真是T大说的FP升级导自的(感谢你的测试解决了心中疑惑)
页:
[1]