主要是< video >以及< audio >标签。支持这两个标签的媒体元素有ie9+、Firefox3.5+、Safari4+、opera10.5+、chrome、iOS版的Safari和Android版webkit。
用法:
<!-- 嵌入视频 -->
<video src = "xxx.mpg">video player not available.</video>
<!-- 嵌入音频 -->
<audio src = "xxx.mp3">audio player not available.</audio>
标签之间的信息在不支持该标签时显示
不是所有浏览器都支持所有媒体格式,所以可以通过< source >制定多个不同的媒体来源,如下所示:
<video id = "myvideo">
<source src = "xxx.webm" type = "video/webm; codecs = 'vp8, vorbis'">
<source src = "xxx.ogv" type = "video/ogg; codecs = 'theora, vorbis'">
<source src = "xxx.mpg" >
video player not available.
</video>
各个浏览器支持的视频格式有:
格式 | IE | Firefox | Opera | Chrome | Safari |
---|---|---|---|---|---|
Ogg | No | 3.5+ | 10.5+ | 5.0+ | No |
MPEG 4 | 9.0+ | No | No | 5.0+ | 3.0+ |
WebM | No | 4.0+ | 10.6+ | 6.0+ | No |
标签的属性
属性 | 数据类型 | 说明 |
---|---|---|
autoplay | 布尔值 | 取值或设置是否自动播放 |
buffered | 时间范围 | 已下载的缓冲时间范围对象 |
bufferedBytes | 字节范围 | 已下载的缓冲字节范围对象 |
bufferingRate | 整数 | 下载过程中每秒执行的位数 |
bufferingRate | 布尔值 | 浏览器是否对缓冲进行了节流 |
controls | 布尔值 | 取值或设置controls,隐藏或显示浏览器内置控件 |
currentLoop | 整数 | 媒体已经循环的次数 |
currentSrc | 字符串 | 播放的url |
currentTime | 浮点数 | 已经播放的秒数 |
defaultPlaybackRate | 浮点数 | 取值或设置默认播放速度,默认值为1s |
duration | 浮点数 | 总播放时间 |
ended | 布尔值 | 是否播放完 |
loop | 布尔值 | 取值或设置是否循环播放 |
muted | 布尔值 | 取值或设置是否静音 |
networkState | 整数 | 当前媒体网络连接状态:0空,1正在加载,2正在加载元数据,3已经加载第一帧,4加载完成 |
pause | 布尔值 | 是否停止 |
playbackRate | 浮点数 | 取值或设置当前速度,这个字用户可改变 |
played | 时间范围 | 到目前为止已经播放的时间范围 |
readyState | 整数 | 当前媒体是否准备就绪:0数据不可用,1可以显示当前帧,2可以开始播放,3可以从头到尾播放 |
seekable | 时间范围 | 目前已播放时间范围 |
seeking | 布尔值 | 播放器是否正移动到媒体文件新位置 |
src | 字符串 | 文件来源 |
start | 浮点数 | 取值或设置媒体开始位置,单位:S |
totalBytes | 整数 | 当前资源所需直接总数 |
volume | 浮点数 | 取值或设置音量,范围:0.0-1.0 |
videoHeight | 整数 | 返回视频高度,只适用< video > |
videoWidth | 整数 | 返回视频宽度,只适用< video > |
标签的事件
事件 | 触发时机 |
---|---|
abort | 下载中断 |
canplay | 可以播放;readyState值为2 |
canplaythrough | 播放可以继续,不会中断;readyState值为3 |
canshowcurrentframe | 当前帧已经下载完成;readyState值为1 |
durationchange | duration属性的值改变 |
emptied | 网络连接关闭 |
ended | 媒体已播放到末尾,播放停止 |
error | 下载期间发生网络错误 |
loadeddata | 第一帧加载完 |
loadedmetdata | 元数据加载完 |
loadstart | 下载已经开始 |
pause | 播放已暂停 |
play | 媒体接到指令开始播放 |
playing | 已实际开始播放 |
progress | 正在下载 |
ratechange | 播放速度改变 |
seek | 搜索结束 |
seeking | 正移动到新位置 |
stalled | 浏览器正尝试下载,但未接到数据 |
timeupdate | currentTime被一不合理或意外方式更新 |
volumechange | volume属性值或muted属性值已改变 |
wating | 播放暂停,等待下载更多数据 |
利用video标签写了一个播放器,兼容ie9及其以上,谷歌,火狐,其他浏览器没有测试。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>媒体元素</title>
<link rel="stylesheet" type="text/css" href="font-awesome-4.5.0\css\font-awesome.min.css" />
<link rel="stylesheet" type="text/css" href="media.css">
</head>
<body>
<div class="z-audio">
<!--[if !IE 8]><!-->
<span class="z-switch"><i class="fa fa-play"></i></span>
<span class="z-now-time">00:00</span>
<div class="z-progress-bar z-play-bar" _content = "play">
<div class="z-prog-line"></div>
<div class="z-prog-active-line"></div>
<i class="z-move-circle fa fa-circle"></i>
</div>
<span class="z-total-time">00:00</span>
<i class="z-volume fa fa-volume-up fa-volume-off"></i>
<div class="z-progress-bar z-volume-bar" _content = "volume">
<div class="z-prog-line"></div>
<div class="z-prog-active-line"></div>
<i class="z-move-circle fa fa-circle"></i>
</div>
<audio src="play.mp3" id="ZmyAudio" class="z-myAudio"></audio>
<!--<![endif]-->
<!--[if IE 8]>
<embed type="audio/mp3" id="ZmyAudio" src="play.mp3" autostart=false loop=false width ="200" height = "30"></embed>
<![endif]-->
</div>
<script type="text/javascript" src = "jquery.min.js"></script>
<script type="text/javascript" src = "media.js"></script>
<script type="text/javascript">
var audioNode = document.getElementById("ZmyAudio");
var med = new Media(audioNode);
med.init();
</script>
</body>
</html>
function Media(node) {
this.playState = false; //播放状态
this.currentTime = 0; //当前播放时间
this.duration = 0; //总播放时间
this.ended = false; //时候播放完成
this.volume = 0.5; //音量
this.prevVolume = 0; //静音前的音量
this.node = node; //音频节点
this.startflag = true; //初始化设置开始时间
this.b = true; //圆点移动完成
}
//事件初始化
Media.prototype.init = function() {
var that = this;
//播放结束
this.node.onended = function() {
that.pause();
};
//可以开始播放
this.node.oncanplay = function() {
if (that.startflag) {
that.node.currentTime = that.currentTime;
var startPer = that.currentTime/that.node.duration;
that.setTime();
that.setProgressBar(startPer, 'play');
that.setProgressBar(that.volume, 'volume');
that.startflag = false;
}
};
//播放和暂停
$(".z-audio").on("click", ".z-switch", function() {
if (that.playState) {
that.pause();
}
else {
that.play();
}
});
//声音是否静音
$(".z-audio").on("click", ".z-volume", function() {
if ($(this).hasClass("fa-volume-up")) {
that.prevVolume = that.node.volume;
that.setVolume(0);
$(this).removeClass("fa-volume-up");
}
else {
that.setVolume(that.prevVolume);
$(this).addClass("fa-volume-up");
}
});
//移动鼠标事件绑定
$(".z-progress-bar").on("mousedown", ".z-move-circle" , function() {
$(".z-audio").off("click", ".z-progress-bar");
that.moveCircle();
return false;
});
//移动鼠标事件解绑
$(".z-progress-bar").on("mouseup", ".z-move-circle", function() {
that.b = false;
that.barClick();
$(".z-audio").off("mousemove", ".z-progress-bar");
return false;
});
that.barClick();
};
Media.prototype.setVolume =function(per) {
this.node.volume = per;
this.volume = per;
};
//进度条位置移动
Media.prototype.barClick =function() {
var that = this;
$(".z-audio").on("click", ".z-progress-bar", function(event) {
if (that.b) {
var e = window.event||event;
var _content = $(this).attr("_content");
that.moveNewPos(e, _content);
}
else {
that.b = true;
}
});
}
//鼠标移动圆点绑定
Media.prototype.moveCircle = function() {
var that = this;
$(".z-audio").on("mousemove", ".z-progress-bar", function(event) {
var e = e||event;
if (that.b) {
var _content = $(this).attr("_content");
that.moveNewPos(e, _content);
return false;
}
})
}
//停止播放事件
Media.prototype.pause = function() {
$(".z-switch").find("i").removeClass("fa-pause");
this.playState = false;
this.node.pause();
}
//开始播放事件
Media.prototype.play = function() {
$(".z-switch").find("i").addClass("fa-pause");
this.playState = true;
this.node.play();
this.setTime();
}
//设置播放时间
Media.prototype.setTime = function() {
var that = this;
this.duration = parseInt(this.node.duration);
$(".z-total-time").text(formatTime(this.duration));
that.currentTime = parseInt(that.node.currentTime);
$(".z-now-time").text(formatTime(that.currentTime));
if (this.playState) { //设置已播放时间
clearInterval(this.timer);
this.timer = setInterval(function() {
that.currentTime = parseInt(that.node.currentTime);
var per = that.currentTime/that.duration;
$(".z-now-time").text(formatTime(that.currentTime));
that.setProgressBar (per, 'play');
},100);
}
}
//设置进度条和声音条
Media.prototype.setProgressBar = function(per, np) {
if (np == 'volume') {
this.setVolume(per);
}
var vp = per*$(".z-"+np+"-bar").width();
$(".z-"+np+"-bar .z-prog-active-line").width(vp);
$(".z-"+np+"-bar .z-move-circle").css({"margin-left":vp});
}
//进度条和声音条移动到新位置
Media.prototype.moveNewPos = function(event, np) {
if ($(event.target || event.srcElement).hasClass("z-progress-bar") || $(event.target || event.srcElement).hasClass("z-prog-line") || $(event.target || event.srcElement).hasClass("z-prog-active-line") ) {
var box = (event.target || event.srcElement).getBoundingClientRect();
var offsetX = event.clientX - box.left; //获取距离左边距离
var xper = offsetX/$(".z-"+np+"-bar").width();
this.setProgressBar(xper, np);
if (np == 'play') {
this.node.currentTime = parseInt(xper*this.duration);
this.setTime();
if (this.playState) {
this.play();
}
else {
this.pause();
}
}
}
}
//时间格式化
function formatTime(time) {
var hh = parseInt(time/3600);
var mm = parseInt((time - hh*3600)/60);
var ss = time - hh*3600 - mm*60;
hh = toTwo(hh, 1);
mm = toTwo(mm, 2);
ss = toTwo(ss, 3);
function toTwo(t, b) {
if (t == 0) {
t = (b == 1) ? '' : ((b == 2) ? '00:' : '00');
}
else if (t >0 && t<10) {
t = (b==1) ? '0'+t+':' : ((b == 2) ? '0'+t+':':'0'+t);
}
else {
t = (b==1) ? t+":" : ((b == 2) ? t + ':':t);
}
return t;
}
var timee = hh+mm+ss
return timee;
}
界面:
具体项目地址:https://github.com/yawenzou/media