HTML5 有两个很炫的元素,就是Audio和 Video,可以用他们在页面上创建音频播放器和视频播放器,制作一些效果很不错的应用。
无论是视屏还是音频,都是一个容器文件,包含了一些音频轨道,视频轨道和一些元数据,这些是和你的视频或者音频控件绑定到一块的,这样才形成了一个完整的播放组件。
浏览器支持情况:
浏览器 | 支持情况 | 编解码器 |
Chrome | 3.0 | Theora 、 Vorbis 、Ogg H.264 、 AAC 、MPEG4 |
FireFox | 3.5 | Theora 、 Vorbis 、Ogg |
IE | 不支持 | 无 |
Opera | 10.5 | Theora 、 Vorbis 、Ogg(10.5) VP8、Vorbis 、 WebM(10.6) |
Safari | 3.2 | H.264 、 ACC 、MPEG4 |
常用的控制函数:
函数 | 动作 |
load() | 加载音频、视频软件 |
play() | 加载并播放音频、视频文件或重新播放暂停的的音频、视频 |
pause() | 暂停出于播放状态的音频、视频文件 |
canPlayType(obj) | 测试是否支持给定的Mini类型的文件 |
只读的媒体属性:
只读属性 | 值 |
duration | 获取媒体文件的播放时长,以s为单位,如果无法获取,则为NaN |
paused | 如果媒体文件被暂停,则返回true,否则返回false |
ended | 如果媒体文件播放完毕,则返回true |
startTime | 返回起始播放时间 |
error | 返回错误代码 |
currentSrc | 以字符串形式返回正在播放或已加载的文件 |
可脚本控制的属性值:
属性 | 值 |
autoplay | 自动播放已经加载的的媒体文件 |
loop | 为true的时候则设定为自动播放 |
currentTime | 以s为单位返回从开始播放到目前所花的时间 |
controls | 显示或者隐藏用户控制界面 |
volume | 音量值,从0.0至1.0之间 |
muted | 设置是否静音 |
autobuffer | 是否进行缓冲加载 |
首先,我们在页面中添加一个音频元素:
<audio src="../Media/The sound of silence.mp3" controls="controls" autoplay="autoplay"></audio>
在谷歌Chrome浏览器中的效果如下:
controls指的是用户控制界面,所以我们可以在Web页面中看到上面这个操作面板,包括播放和暂停,播放进度条,音量进度条,和进度时间显示等。autoplay 指的是自动播发已加载的媒体文件,所以我们一打开页面就可以直接播放了
HTML5 Audio API 的界面很强大,功能也很完善,但是我们的Web应用会根据不同的需求、设计风格和界面颜色来要求不同的播放器样式和功能,这就要求我们能基于他们的API 设计出灵活的应用。
接下来,我们设计一款适合我们离线工作系统需要的播放器:
1 //在页面放置一个audio元素,因为我们使用自己设计的播放界面,所以这边不用他们的controls。 2 3 4 //这边放置一个隐藏域,他的作用是存放媒体文件暂停的时间点 5 6 7 //编写音乐盒的界面 89 10 //上一个媒体文件的控制图标11 //开始和暂停的控制图标12 //下一个媒体文件的控制图标13 1428 29 30//进度条1520 21 //静音图标22 //全音量进度条23 //当前音量进度条24 //全音量图标25 //显示或隐藏媒体文件列表图标26 27Ben's Music Box!//媒体文件标题1600:00 | 00:00//时间进度17 //全部时长的进度条18 //已播放时长的进度条19//媒体文件列表区域31 //当前媒体文件的32//媒体文件列表33 3439//单个媒体文件35 01.Fate3637 38
画好这个结构之后,我们就来写相应的CSS样式了:
1 //这是音乐盒整体框架 2 3 .MusicBox 4 5 { 6 7 font: 9px 'Lucida Sans Unicode', 'Trebuchet MS', Arial, Helvetica; 8 9 background-color: #212121; 10 11 12 13 //设置渐变的颜色,左上到左下,颜色从#1B1B1B 到 #212121。 14 15 background-image: -webkit-gradient(linear, left top, left bottom, from(#1B1B1B), to(#212121)); 16 17 background-image: -webkit-linear-gradient(top, #1B1B1B, #212121); 18 19 background-image: -moz-linear-gradient(top, #1B1B1B, #212121); 20 21 background-image: -ms-linear-gradient(top, #1B1B1B, #212121); 22 23 background-image: -o-linear-gradient(top, #1B1B1B, #212121); 24 25 background-image: linear-gradient(top, #1B1B1B, #212121); 26 27 28 29 //设置边框的弧度值,为3px 30 31 -moz-border-radius: 3px; 32 33 -webkit-border-radius: 3px; 34 35 border-radius: 3px; 36 37 38 39 40 41 42 43 44 45 /*阴影*/ 46 47 text-shadow: 0 1px 0 rgba(255,255,255,0.5); 48 49 -webkit-box-shadow: 10px 10px 25px #ccc; 50 51 -moz-box-shadow: 10px 10px 25px #ccc; 52 53 box-shadow: 10px 10px 25px #ccc; 54 55 56 57 /*透明度*/ 58 59 opacity:0.9; 60 61 62 63 /*基本属性*/ 64 65 border-width: 1px; 66 67 border-style: solid; 68 69 border-color: #488BF0 #488BF0 #488BF0 #488BF0; 70 71 width:810px; 72 73 height:40px; 74 75 padding:2px 5px; 76 77 position:absolute; 78 79 z-index:9; 80 81 } 82 83 84 85 //上一个媒体文件的控制图标 86 87 .LeftControl 88 89 { 90 91 width:0px; 92 93 padding: 10px 10px 10px 10px; 94 95 float:left; 96 97 height:20px; 98 99 background:url(../Images/sk-dark.png) left 2px no-repeat;100 101 margin-right:8px;102 103 margin-left:10px;104 105 } 106 107 .LeftControl:hover108 109 {110 111 background:url(../Images/sk-dark.png) left -30px no-repeat;112 113 }114 115 116 117 118 119 //下一个媒体文件的控制图标120 121 .RightControl122 123 {124 125 width:0px;126 127 padding: 10px 10px 10px 10px;128 129 float:left; 130 131 height:20px;132 133 background:url(../Images/sk-dark.png) left -62px no-repeat;134 135 margin-right:8px;136 137 }138 139 140 141 .RightControl:hover142 143 {144 145 background:url(../Images/sk-dark.png) left -93px no-repeat;146 147 }148 149 150 151 //音频进度控制152 153 (注意这边有两个高度为2px的div,一个是.Process 一个是.ProcessYet,用来显示音频播放的进度条,一个是显示全部的音频长度,长度是固定的;一个用来实时显示播放的进度的)154 155 .ProcessControl156 157 {158 159 width:500px;160 161 padding: 5px 10px 10px 10px;162 163 float:left; 164 165 height:20px;166 167 margin-right:12px;168 169 color:#ffffff;170 171 }172 173 174 175 .ProcessControl .SongName { float:left; }176 177 .ProcessControl .SongTime { float:right; } 178 179 .ProcessControl .Process180 181 {182 183 width: 500px;184 185 float: left;186 187 height: 2px;188 189 cursor: pointer;190 191 background-color:#000000; 192 193 margin-top:7px;194 195 }196 197 198 199 .ProcessControl .ProcessYet200 201 {202 203 width: 0px;204 205 position:absolute; 206 207 height: 2px;208 209 left:131px;210 211 top:30px;212 213 cursor: pointer;214 215 background-color:#7A8093; 216 217 }218 219 220 221 //静音图标222 223 .VoiceEmp224 225 {226 227 width:0px;228 229 padding: 10px 10px 10px 10px;230 231 float:left; 232 233 height:17px;234 235 background:url(../Images/sk-dark.png) -28px -180px no-repeat; 236 237 margin-right:2px; 238 239 } 240 241 .VoiceEmp:hover242 243 {244 245 background:url(../Images/sk-dark.png) -28px -212px no-repeat; 246 247 }248 249 250 251 //总音量进度条 252 253 .VoidProcess254 255 {256 257 width: 66px;258 259 height: 2px;260 261 cursor: pointer;262 263 background-color:#000; 264 265 float:left;266 267 margin-top:19px;268 269 margin-right:6px; 270 271 }272 273 274 275 //当前音量进度条276 277 .VoidProcessYet278 279 {280 281 width: 66px;282 283 position:absolute; 284 285 height: 2px;286 287 left:675px;288 289 top:21px;290 291 cursor: pointer;292 293 background-color:#7A8093; 294 295 }296 297 298 299 //全音量图标300 301 .VoiceFull302 303 { 304 305 width:0px;306 307 padding: 10px 10px 10px 10px;308 309 float:left; 310 311 height:17px;312 313 background:url(../Images/sk-dark.png) -28px -116px no-repeat; 314 315 }316 317 318 319 .VoiceFull:hover320 321 { 322 323 background:url(../Images/sk-dark.png) -28px -148px no-repeat; 324 325 }326 327 328 329 330 331 //呈现出播放图标332 333 .MainControl334 335 {336 337 width:25px;338 339 padding: 10px 15px 5px 10px;340 341 float:left; 342 343 height:20px;344 345 background:url(../Images/sk-dark.png) -80px -130px no-repeat; 346 347 } 348 349 350 351 .MainControl:hover352 353 {354 355 background:url(../Images/sk-dark.png) -80px -166px no-repeat;356 357 }358 359 360 361 //呈现出暂停或停止图标362 363 .StopControl364 365 {366 367 width:14px;368 369 padding: 10px 10px 5px 10px;370 371 float:left; 372 373 height:20px;374 375 background:url(../Images/sk-dark.png) -50px -130px no-repeat; 376 377 margin-right:16px; 378 379 }380 381 .StopControl:hover382 383 {384 385 background:url(../Images/sk-dark.png) -50px -165px no-repeat;386 387 }388 389 //显示多媒体文件列表的控制图标390 391 .ShowMusicList392 393 { 394 395 width:10px;396 397 padding: 10px 10px 5px 10px;398 399 float:left; 400 401 height:10px;402 403 background:url(../Images/sk-dark.png) -20px 0 no-repeat; 404 405 margin:5px 0 0 12px;406 407 cursor:pointer;408 409 }410 411 412 413 .ShowMusicList:hover414 415 { 416 417 background:url(../Images/sk-dark.png) -20px -29px no-repeat; 418 419 }420 421 422 423 //文件列表区域的样式代码424 425 .MusicList426 427 {428 429 font: 9px 'Lucida Sans Unicode', 'Trebuchet MS', Arial, Helvetica;430 431 background-color: #212121;432 433 background-image: -webkit-gradient(linear, left top, left bottom, from(#1B1B1B), to(#212121));434 435 background-image: -webkit-linear-gradient(top, #1B1B1B, #212121);436 437 background-image: -moz-linear-gradient(top, #1B1B1B, #212121);438 439 background-image: -ms-linear-gradient(top, #1B1B1B, #212121);440 441 background-image: -o-linear-gradient(top, #1B1B1B, #212121);442 443 background-image: linear-gradient(top, #1B1B1B, #212121);444 445 446 447 -moz-border-radius: 3px;448 449 -webkit-border-radius: 3px;450 451 border-radius: 3px;452 453 454 455 text-shadow: 0 1px 0 rgba(255,255,255,0.5);456 457 458 459 border-width: 1px;460 461 border-style: solid;462 463 border-color: #488BF0 #488BF0 #488BF0 #488BF0;464 465 466 467 width:600px;468 469 height:200px;470 471 472 473 /*阴影*/474 475 -webkit-box-shadow: 10px 10px 25px #ccc; 476 477 -moz-box-shadow: 10px 10px 25px #ccc; 478 479 box-shadow: 10px 10px 25px #ccc; 480 481 482 483 /*透明度*/484 485 opacity:0.9; 486 487 488 489 /*基本性质*/490 491 padding:2px 5px;492 493 position:absolute;494 495 z-index:1000;496 497 display:none;498 499 }500 501 502 503 .MusicList .Author504 505 {506 507 font: 9px 'Lucida Sans Unicode', 'Trebuchet MS', Arial, Helvetica;508 509 background-color: #212121;510 511 background-image:url(../Images/Eson.jpg);512 513 514 515 -moz-border-radius: 3px;516 517 -webkit-border-radius: 3px;518 519 border-radius: 3px;520 521 522 523 width:158px;524 525 height:200px;526 527 float:left;528 529 }530 531 532 533 .MusicList .List534 535 {536 537 font: 9px 'Lucida Sans Unicode', 'Trebuchet MS', Arial, Helvetica;538 539 background-color: #212121; 540 541 -moz-border-radius: 3px;542 543 -webkit-border-radius: 3px;544 545 border-radius: 3px;546 547 548 549 width:410px;550 551 height:180px;552 553 float:right;554 555 overflow:hidden;556 557 padding:10px 13px;558 559 color:#fff; 560 561 }562 563 564 565 .MusicList .List .Single566 567 {568 569 width:100%;570 571 float:left;572 573 overflow:hidden;574 575 height:15px;576 577 font-size:13px;578 579 cursor:pointer;580 581 margin-bottom:8px;582 583 }584 585 586 587 .MusicList .List .Single .SongName588 589 {590 591 width:90%;592 593 float:left;594 595 }
页面的元素和CSS样式写完之后,就可以看到一个漂亮的音乐播放器的模型了,如图:
只是现在的播放器上面的按钮都是空壳,没有任何功能。所以,现在我们就来添加这些功能 , 脚本的顶层框架就用Jquery。
1 $(document).ready(function () { 2 3 //获取音频工具 4 5 var audio = document.getElementById("myMusic"); 6 7 //开始,暂停按钮 8 9 $("#MainControl")._toggle(function () { 10 11 $(this).removeClass("MainControl").addClass("StopControl"); 12 13 if (audio.src == "") { 14 15 var Defaultsong = $(".Single .SongName").eq(0).attr("KV"); 16 17 $(".MusicBox .ProcessControl .SongName").text(Defaultsong); 18 19 $(".Single .SongName").eq(0).css("color", "#7A8093"); 20 21 audio.src = "../Media/" + Defaultsong + ".mp3"; 22 23 } 24 25 audio.play(); 26 27 TimeSpan(); 28 29 }, function () { 30 31 $(this).removeClass("StopControl").addClass("MainControl"); 32 33 audio.pause(); 34 35 }); 36 37 38 39 40 41 //歌曲列表的选择操作 42 43 $(".MusicList .List .Single .SongName").click(function () { 44 45 $(".MusicList .List .Single .SongName").css("color", "#fff"); 46 47 $("#MainControl").removeClass("MainControl").addClass("StopControl"); 48 49 $(this).css("color", "#7A8093"); 50 51 var SongName = $(this).attr("KV"); 52 53 $(".MusicBox .ProcessControl .SongName").text(SongName); 54 55 audio.src = "../Media/" + SongName + ".mp3"; 56 57 audio.play(); 58 59 TimeSpan(); 60 61 }); 62 63 64 65 //左前进按钮 66 67 $(".LeftControl").click(function () { 68 69 $(".MusicList .List .Single .SongName").each(function () { 70 71 if ($(this).css("color") == "rgb(122, 128, 147)") { 72 73 var IsTop = $(this).parent(".Single").prev(".Single").length == 0 ? true : false; //检查是否是最顶端的歌曲 74 75 var PrevSong; 76 77 if (IsTop) { 78 79 PrevSong = $(".Single").last().children(".SongName").attr("KV"); 80 81 $(".Single").last().children(".SongName").css("color", "#7A8093"); 82 83 } 84 85 else { 86 87 PrevSong = $(this).parent(".Single").prev(".Single").children(".SongName").attr("KV"); 88 89 $(this).parent(".Single").prev(".Single").children(".SongName").css("color", "#7A8093"); 90 91 } 92 93 94 95 audio.src = "../Media/" + PrevSong + ".mp3"; 96 97 $(".MusicBox .ProcessControl .SongName").text(PrevSong); 98 99 $(this).css("color", "#fff");100 101 audio.play();102 103 return false; //代表break104 105 }106 107 })108 109 });110 111 112 113 //右前进按钮114 115 $(".RightControl").click(function () {116 117 $(".MusicList .List .Single .SongName").each(function () {118 119 if ($(this).css("color") == "rgb(122, 128, 147)") {120 121 var IsBottom = $(this).parent(".Single").next(".Single").length == 0 ? true : false; //检查是否是最尾端的歌曲122 123 var NextSong;124 125 if (IsBottom) {126 127 NextSong = $(".Single").first().children(".SongName").attr("KV");128 129 $(".Single").first().children(".SongName").css("color", "#7A8093");130 131 }132 133 else {134 135 NextSong = $(this).parent(".Single").next(".Single").children(".SongName").attr("KV");136 137 $(this).parent(".Single").next(".Single").children(".SongName").css("color", "#7A8093");138 139 }140 141 142 143 audio.src = "../Media/" + NextSong + ".mp3";144 145 $(".MusicBox .ProcessControl .SongName").text(NextSong);146 147 $(this).css("color", "#fff");148 149 audio.play();150 151 return false; //代表break152 153 }154 155 })156 157 });158 159 160 161 //静音按钮162 163 $(".VoiceEmp").click(function () {164 165 $(".VoidProcessYet").css("width", "0");166 167 audio.volume = 0;168 169 });170 171 172 173 //满音量按钮174 175 $(".VoiceFull").click(function () {176 177 $(".VoidProcessYet").css("width", "66px");178 179 audio.volume = 1;180 181 });182 183 184 185 /*186 187 之前一直考虑进度条的原理,这边进度条的做法启发自腾讯一款播放器的做法,采用两个2px高度的div,重叠,188 189 上面那个与下面那个div的颜色不一样,用于区分进度,顶层div的width是根据播放的长度来调整的,width越长,说明播放越长,190 191 知道上层的div完全覆盖下面的div,达到长度的一致,说明播放完毕。我们的播放进度条和音量进度条都是这样做的192 193 */194 195 196 197 // 音频进度条事件(进度增加)198 199 $(".Process").click(function (e) {200 201 202 203 //播放进度条的基准参数204 205 var Process = $(".Process").offset();206 207 var ProcessStart = Process.left;208 209 var ProcessLength = $(".Process").width();210 211 212 213 214 215 var CurrentProces = e.clientX - ProcessStart;216 217 DurationProcessRange(CurrentProces / ProcessLength);218 219 $(".ProcessYet").css("width", CurrentProces);220 221 });222 223 224 225 //音频进度条事件(进度减少)226 227 $(".ProcessYet").click(function (e) {228 229 230 231 //播放进度条的基准参数232 233 var Process = $(".Process").offset();234 235 var ProcessStart = Process.left;236 237 var ProcessLength = $(".Process").width();238 239 240 241 var CurrentProces = e.clientX - ProcessStart;242 243 DurationProcessRange(CurrentProces / ProcessLength);244 245 $(".ProcessYet").css("width", CurrentProces);246 247 });248 249 250 251 //音量进度条事件(进度增加)252 253 $(".VoidProcess").click(function (e) {254 255 //音量进度条的基准参数256 257 var VoidProcess = $(".VoidProcess").offset();258 259 var VoidProcessStart = VoidProcess.left;260 261 var VoidProcessLength = $(".VoidProcess").width();262 263 264 265 var CurrentProces = e.clientX - VoidProcessStart;266 267 VolumeProcessRange(CurrentProces / VoidProcessLength);268 269 $(".VoidProcessYet").css("width", CurrentProces);270 271 });272 273 274 275 //音量进度条时间(进度减少)276 277 $(".VoidProcessYet").click(function (e) {278 279 //音量进度条的基准参数280 281 var VoidProcess = $(".VoidProcess").offset();282 283 var VoidProcessStart = VoidProcess.left;284 285 var VoidProcessLength = $(".VoidProcess").width();286 287 288 289 var CurrentProces = e.clientX - VoidProcessStart;290 291 VolumeProcessRange(CurrentProces / VoidProcessLength);292 293 $(".VoidProcessYet").css("width", CurrentProces);294 295 });296 297 298 299 //显示或隐藏多媒体文件列表事件300 301 $(".ShowMusicList").toggle(function () {302 303 $(".MusicList").show();304 305 306 307 var MusicBoxRight = $(".MusicBox").offset().left + $(".MusicBox").width();308 309 var MusicBoxBottom = $(".MusicBox").offset().top + $(".MusicBox").height();310 311 $(".MusicList").css("left", MusicBoxRight - $(".MusicList").width());312 313 $(".MusicList").css("top", MusicBoxBottom + 15);314 315 }, function () {316 317 $(".MusicList").hide();318 319 });320 321 322 323 324 325 //监听媒体文件结束的事件(ended),这边一首歌曲结束就读取下一首歌曲,实现播放上的循环播放326 327 audio.addEventListener('ended', function () {328 329 $(".MusicList .List .Single .SongName").each(function () {330 331 if ($(this).css("color") == "rgb(122, 128, 147)") {332 333 var IsBottom = $(this).parent(".Single").next(".Single").length == 0 ? true : false; //检查是否是最尾端的歌曲334 335 var NextSong;336 337 if (IsBottom) {338 339 NextSong = $(".Single").first().children(".SongName").attr("KV");340 341 $(".Single").first().children(".SongName").css("color", "#7A8093");342 343 }344 345 else {346 347 NextSong = $(this).parent(".Single").next(".Single").children(".SongName").attr("KV");348 349 $(this).parent(".Single").next(".Single").children(".SongName").css("color", "#7A8093");350 351 }352 353 354 355 audio.src = "../Media/" + NextSong + ".mp3";356 357 $(".MusicBox .ProcessControl .SongName").text(NextSong);358 359 $(this).css("color", "#fff");360 361 audio.play();362 363 return false; //代表break364 365 }366 367 });368 369 }, false);370 371 372 373 374 375 });376 377 378 379 //音量进度条的转变事件380 381 function VolumeProcessRange(rangeVal) {382 383 var audio = document.getElementById("myMusic");384 385 audio.volume = parseFloat(rangeVal);386 387 }388 389 390 391 //播放进度条的转变事件392 393 function DurationProcessRange(rangeVal) {394 395 var audio = document.getElementById("myMusic");396 397 audio.currentTime = rangeVal * audio.duration;398 399 audio.play();400 401 }402 403 404 405 //播放事件406 407 function Play(obj) {408 409 var SongUrl = obj.getAttribute("SongUrl");410 411 var audio = document.getElementById("myMusic");412 413 audio.src = "../Media/" + SongUrl + ".mp3";414 415 audio.play();416 417 TimeSpan();418 419 }420 421 422 423 //暂停事件424 425 function Pause() {426 427 var audio = document.getElementById("myMusic");428 429 $("#PauseTime").val(audio.currentTime);430 431 audio.pause();432 433 }434 435 436 437 //继续播放事件438 439 function Continue() {440 441 var audio = document.getElementById("myMusic");442 443 audio.startTime = $("PauseTime").val();444 445 audio.play();446 447 }448 449 450 451 //时间进度处理程序452 453 function TimeSpan() {454 455 var audio = document.getElementById("myMusic");456 457 var ProcessYet = 0;458 459 setInterval(function () {460 461 var ProcessYet = (audio.currentTime / audio.duration) * 500;462 463 $(".ProcessYet").css("width", ProcessYet);464 465 var currentTime = timeDispose(audio.currentTime);466 467 var timeAll = timeDispose(TimeAll());468 469 $(".SongTime").html(currentTime + " | " + timeAll);470 471 }, 1000);472 473 }474 475 476 477 //时间处理,因为时间是以为单位算的,所以这边执行格式处理一下478 479 function timeDispose(number) {480 481 var minute = parseInt(number / 60);482 483 var second = parseInt(number % 60);484 485 minute = minute >= 10 ? minute : "0" + minute;486 487 second = second >= 10 ? second : "0" + second;488 489 return minute + ":" + second;490 491 }492 493 494 495 //当前歌曲的总时间496 497 function TimeAll() {498 499 var audio = document.getElementById("myMusic");500 501 return audio.duration;502 503 }
至此,一款播放器做完了,默认执行的是列表循环播放,包含了上一首,下一首,播放,暂停,播放进度条调整,音量调进度条整,列表选择等功能。播放的歌曲是固定的写在列表里面的,我喜欢的ESON的照片也是贴上去的,这些都可以做成动态获取或则与服务器交互,有兴趣的可以去试一下,扩展一下。
本来准备在我们的离线工作系统中添加音频播放器,后来需求变更,放弃了,所以这个版本不是完善的版本。视频播放器的功能大同小异,也可以自己试试。
本文源码下载: