前端开发项目职责 前端实战项目开发 web前端小型开发项目流程
一、MP3文件在各浏览器中支持情况
1.1 HTML5 Audio大家可能都知道,在HTML5中有一个标签:audio,他的作用就是播放音频文件,那么对MP3格式文件支持情况如何呢?
据度娘告诉我的,大概是酱紫情况:
Chrome, IE9+, Safari
但是还是有点担心,万一漏了,肿么办呢?
所以第一步,我们需要检测MP3文件的播放情况。
如下代码所示,我们可以通过Audio对象的创建、canPlayType方法,监听[backcolor=rgb(247, 247, 247)]canPlaythrough、error事件来判断MP3是否可以播放。[/bgcolor]使用代码检测后,发现度娘的描述中确实漏掉了几个浏览器:Opera,Edge,还有各式各样的使用webkit内核的PC/Mobile浏览器,可见这一番功夫并没有白费!
[code]//默认可以播放
var audioMp3Flag = true;
//执行检查方法
canPlayAudioMP3(function(flag){audioMp3Flag = flag;})
/**
- 检测浏览器是否能使用Audio对象播放mp3文件
*/
function canPlayAudioMP3(callback){
try {
var audio = new Audio();//1、利用canPlayType方法,检测浏览器是否有MP3解码器,回调true if(audio.canPlayType('audio/mpeg') == "probably") callback(true); //2、利用canPlaythrough事件,监听音频是否可以加载成功,回调true audio.addEventListener('canplaythrough', function(e){ callback(true); }, false); //3、利用error事件,监听音频播放是否会出现异常,回调false audio.addEventListener('error', function(e){ callback(false); }, false); //base64编码最小的MP3文件 audio.src = "data:audio/mpeg;base64,/+MYxAAAAANIAAAAAExBTUUzLjk4LjIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; audio.load();
}
catch(e){
4、Audio对象异常,回调false
callback(false);
}
}[/code]
1.2 再谈谈Flash
由于flash的安全漏洞,放弃flash的声音越来越多了。
但是作为一个功能研究,还是希望能够兼容尽可能多的浏览器的,优雅降级、渐进增强是每个开发者都想做到的事情吧!
尽管网页上嵌入flash有很多现成的js文件,比方说swfobject.js等,但作为一个小demo,还是自己练习一下嵌入flash所需的html!
1.2.1 object与embed
网上同类的科普文章有很多,如OBJECT和EMBED标签
OBJECT 标签是用于windows IE3.0及以后浏览器或者其它支持Activex控件的浏览器。
EMBED标签是用于Netscape Navigator2.0及以后的浏览器或其它支持Netscape插件的浏览器。
下面分享一下我的方法[code]/*
- 生成嵌入网页的flash代码
- @param {Object} movieName 元素Id
- @param {Object} src swf文件
- @param {Object} data 需要传入的参数
/
function flashHtml(movieName, src, data) {
var attr = {
width: 1,
height: 1,
quality: ‘high’,
style: ”,
wmode: ‘opaque’ /window|transparent|opaque/
};
if (exports.name == “ie” && exports.version<=7) {
//旧版IE加载flash需要添加随机数,随机数取值0-999
src += ‘?rnd=’ + Math.floor(Math.random() 1000);
}
/* 1、IE6-10: object标签 + classid + codebase- 2、IE11浏览器:object标签 + type=application/x-shockwave-flash
- 3、其他浏览器(Chrome|Firefox|Opera)等:embed标签 + type=application/x-shockwave-flash
*/
return exports.name == “ie” && exports.version<11 ? [
‘<object id=”‘, movieName, ‘” name=”‘, movieName, ‘” width=”‘, attr.width, ‘” height=”‘, attr.height, ‘” style=”‘, attr.style, ‘” classid=”clsid:D27CDB6E-AE6D-11cf-96B8-444553540000″ codebase=”https://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28″>’,
‘<param name=”wmode” value=”‘, attr.wmode, ‘” />’,
‘<param name=”movie” value=”‘, src, ‘” />’,
‘<param name=”allowscriptaccess” value=”always” />’,
‘<param name=”flashvars” value=”‘, data , ‘” />’,
‘</object>’
].join(”) :
exports.name == “ie” && exports.version==11 ? [
‘<object id=”‘, movieName, ‘” name=”‘, movieName, ‘” data=”‘, src, ‘” width=”‘, attr.width, ‘” height=”‘, attr.height, ‘” style=”‘, attr.style, ‘” type=”application/x-shockwave-flash”>’,
‘<param name=”wmode” value=”‘, attr.wmode, ‘”/>’,
‘<param name=”movie” value=”‘, src, ‘”/>’,
‘<param name=”quality” value=”‘,attr.quality,'”/>’,
‘<param name=”allowscriptaccess” value=”always”/>’,
‘<param name=”flashvars” value=”‘, data , ‘”/>’,
‘</object>’
].join(”) : [
‘<embed id=”‘, movieName, ‘” name=”‘, movieName, ‘” src=”‘ + src + ‘” width=”‘, attr.width, ‘” height=”‘, attr.height, ‘” style=”‘, attr.style, ‘” flashvars=”‘,data, ‘” wmode=”‘, attr.wmode, ‘” allowscriptaccess=”always” pluginspage=”https://www.macromedia.com/go/getflashplayer” type=”application/x-shockwave-flash” >’,
‘</embed>’
].join(”);
}[/code][color=#666666]1.2.2 编写as脚本,用于和js交互[/color]
下面脚本借鉴了这位大神的代码 https://github.com/breily/jquery.player.js/blob/master/version_0.2/music.as
同时吸取了记ie8及以下版本ie的flash的addCallback的一坑这位大哥的as脚本编写的经验,减少了addcallback的数量,成功消灭了IE8以下版本的bug
编写好as文件后,可以利mtasc编译为swf文件,
[code]import flash.external.ExternalInterface;
class Music {
static var app:Music;
var sound:Sound;
var paused:Number;
// Constructor, plus adds all the js callbacks
function Music() {
this.sound = new Sound();
paused = 0;
ExternalInterface.addCallback("emit", this, emit);
ExternalInterface.addCallback("getPaused", this, getPaused);
}
public function emit(action:String, arg:String) {
switch(action){
case 'load':
this.load(arg);
break;
case 'play':
this.play();
break;
case 'stop':
this.stop();
break;
}
}
public function getPaused() {
return paused;
}
private function load(url:String) {
this.sound.loadSound(url, true);
this.sound.onSoundComplete = function() {
this.paused = 0;
ExternalInterface.call("v_stop");
};
}
private function play() {
this.paused = 1;
this.sound.start(0);
}
private function stop() {
this.paused = 0;
this.sound.stop();
}
static function main(mc:MovieClip) {
app = new Music();
}
}[/code]
####二、Music对象的编写
捋顺了外部依赖,下面可以编写Music对象了,我的思路大概是:
Music: 1、构造函数
2、init 初始化方法
3、emit (根据音乐状态play或stop音乐)
为了实现播放逻辑与视图显示的分离,在初始化方法中传入了逻辑层完成后需要回调的方法。
2.1 构造函数
[code]/**
- Music对象的构造函数
- @param {Object} url 音乐文件地址
- @param {Object} type 音乐类型、暂时只支持audio/mpeg,加一个参数便于拓展
- @param {Object} viewCallback 音乐初始化、播放逻辑完成后的视图回调
- @param {Object} eventCallback 音乐初始化、播放逻辑完成后的事件回调
*/
function Music(url, type, viewCallback, eventCallback){
this.url = url;
this.type = type;
this.viewCallback = viewCallback;
this.eventCallback = eventCallback;
this.isSupportAudio = isSupportAudio(this.type);
}[/code]
2.2 init初始化方法
分别调用了createAudioPlayer()和createSwfPlayer()来创建音乐播放的载体
[code]/**
- init初始化方法
- 在支持audio标签且能正常解码MP3的情况下创建audio标签
- 否则使用flash的方式
- 完成后,进行初始化方法的视图及事件回调
*/
Music.prototype.init = function(){
var self = this;
if (this.isSupportAudio) {
this.createAudioPlayer();
} else {
try{this.createSwfPlayer()}catch(e){};
}
this.viewCallback[‘init’].call(this);
this.eventCallback[‘init’].call(this);
}[/code]
createAudioPlayer和createSwfPlayer的目的只有一个,封装一个this.musicEl对象,让对象在audio|flash的模式下,都能支持play(播放)、stop(停止),getPaused(获取音乐状态)
createSwfPlayer的实现方式中有一点要注意:IE6,7需要使用window[id]才能获取到object对象,其他浏览器可以使用document[id][code]Music.prototype.createAudioPlayer = function(){
var self = this;
this.musicEl = document.createElement(‘audio’);
this.musicEl.src = this.url;
this.musicEl.type = this.type;
this.musicEl.stop = function(){
this.pause();
this.currentTime = 0.0;
}
addEvent(this.musicEl, ‘ended’, function(){
m_console(‘播放结束停止MP3’);
self.viewCallback[‘stop’].call();
});
this.musicEl.getPaused = function(){
return this.paused;
}
}
Music.prototype.createSwfPlayer = function(){
var self =this;
var musicId = ‘swfPlayer’;
var id = ‘player_hidden’;
var swf = ‘music.swf’;
var html = flashHtml(id, swf, ‘id=’+id);
this.musicEl = document.createElement(‘div’);
this.musicEl.innerHTML += html;
this.musicEl.id = musicId;
document.body.innerHTML += this.musicEl.outerHTML;
var flashEl = (exports.name == 'ie' && exports.version <= 7) ? window[id] : document[id];
setTimeout(function(){
flashEl.emit('load', self.url);
flashEl.emit('stop');
self.musicEl.play = function(){
flashEl.emit('play');
}
self.musicEl.stop = function(){
flashEl.emit('stop');
}
self.musicEl.getPaused = function(){
return flashEl.getPaused() == 0;
}
}, 250);
}[/code]
2.3 emit播放控制方法
emit的作用就是在音乐停止状态下,执行播放。播放状态下,执行停止。
play、stop,getPaused方法的具体实现原理(在createAudioPlayer和createSwfPlayer有代码说明)
HTML5 Audio
play方法:调用Audio对象的play方法
stop方法:调用Audio对象的pause方法,并将currentTime设为0
getPaused方法:调用Audio对象的paused属性
Flash
play方法:调用flash Sound类的start方法
stop方法:######调用flash Sound类的stop方法
getPaused方法:在as代码中设置了一个变量paused,在播放时设为1,停止时设为0,js中调用flash接口读取此变量判断是否为0
[code]Music.prototype.play = function(){
m_console(‘播放MP3’);
this.musicEl.play();
this.viewCallback[‘play’].call();
}[/code][code]Music.prototype.stop = function(){
m_console(‘手动停止MP3’);
this.musicEl.stop();
this.viewCallback[‘stop’].call();
}[/code][code]Music.prototype.emit = function(){
if (this.musicEl.getPaused()) {
this.play();
} else {
this.stop();
}
}[/code]
前端开发项目架构 前端开发项目功能描述 前端开发项目经验描述
评论前必须登录!
注册