您的位置:首页 > Web前端 > HTML5

HTML5 Speech API和Audio API

2016-04-20 14:44 537 查看
http://item.congci.com/item/html5-speech-api-and-audio-api

浏览器提供语音搜索已经不是什么新鲜事,在google上搜索了一下speech api相关内容,发现存在三个不同的标准规范,分别是:

HTML Speech Web API
Speech Input API Specification
Speech JavaScript API Specification


HTML Speech Web API

HTML Speech Web API是由微软、google、mozilla等公司的人提出,目前最近的版本是2011年10月29日。

该规范提出了一个reco标记用来进行语音识别,该标记在用户界面上表示一个语音输入,可以将另一个表单元素与之进行关联,从而将识别结果呈献给用户。此外规范还提供了tts标记完成语音合成功能。



[NamedConstructor=Reco(),
NamedConstructor=Reco(in DOMString for)]
interface HTMLRecoElement : HTMLElement {
// Attributes
readonly attribute HTMLFormElement? form;
attribute DOMString htmlFor;
readonly attribute HTMLElement? control;
attribute SpeechInputRequest request;

attribute DOMString grammar;

// From the SpeechInputRequest
integer maxNBest;
DOMString language;
boolean saveForRereco;
boolean endpointDetection;
boolean finalizeBeforeEnd;
integer interimResults;
float confidenceThreshold;
float sensitivity;
float speedVsAccuracy;
integer completeTimeout;
integer incompleteTimeout;
integer maxSpeechTimeout;
DOMString inputWaveformURI;
attribute DOMString serviceURI;
attribute boolean continuous;

// event handlers
attribute Function onaudiostart;
attribute Function onsoundstart;
attribute Function onspeechstart;
attribute Function onspeechend;
attribute Function onsoundend;
attribute Function onaudioend;
attribute Function onresult;
attribute Function onnomatch;
attribute Function onerror;
attribute Function onauthorizationchange;
attribute Function onopen;
attribute Function onstart;
};




TTS定义如下:

[NamedConstructor=TTS(),
NamedConstructor=TTS(in DOMString src)]
interface HTMLTTSElement : HTMLMediaElement {
attribute DOMString serviceURI;
attribute DOMString lastMark;
};


在JS方面,规范定义了SpeechInputRequest接口可以独立发起语音识别并将结果通过回调返回给浏览器。



[Constructor]
interface SpeechInputRequest {
// recognition parameters
SpeechGrammars[] grammars;

// misc parameter attributes
integer maxNBest;
DOMString language;
boolean saveForRereco;
boolean endpointDetection;
boolean finalizeBeforeEnd;
integer interimResults;
float confidenceThreshold;
float sensitivity;
float speedVsAccuracy;
integer completeTimeout;
integer incompleteTimeout;
integer maxSpeechTimeout;
DOMString inputWaveformURI;

// the generic set of parameters
SpeechParameter[] parameters;

// other attributes
attribute DOMString serviceURI;
attribute MediaStream input;
const unsigned short SPEECH_AUTHORIZATION_UNKNOWN = 0;
const unsigned short SPEECH_AUTHORIZATION_AUTHROIZED = 1;
const unsigned short SPEECH_AUTHORIZATION_NOT_AUTHORIZED = 2;
readonly attribute unsigned short authorizationState;
attribute boolean continuous;

// the generic send info method
void sendInfo(in DOMString type, in DOMString value);

// Default markup binding methods
void addGrammarFrom(in Element inputElement, optional float weight, optional boolean modal);
void outputToElement(in Element outputElement);

// methods to drive the speech interaction
void open();
void start();
void stop();
void abort();
void interpret(in DOMString text);

// event methods
attribute Function onaudiostart;
attribute Function onsoundstart;
attribute Function onspeechstart;
attribute Function onspeechend;
attribute Function onsoundend;
attribute Function onaudioend;
attribute Function onresult;
attribute Function onnomatch;
attribute Function onerror;
attribute Function onauthorizationchange;
attribute Function onopen;
attribute Function onstart;
attribute Function onend;
};
SpeechInputRequest implements EventTarget;

interface SpeechInputNomatchEvent : Event {
readonly attribute SpeechInputResult result;
};

interface SpeechInputErrorEvent : Event {
readonly attribute SpeechInputError error;
};

interface SpeechInputError {
const unsigned short SPEECH_INPUT_ERR_OTHER = 0;
const unsigned short SPEECH_INPUT_ERR_NO_SPEECH = 1;
const unsigned short SPEECH_INPUT_ERR_ABORTED = 2;
const unsigned short SPEECH_INPUT_ERR_AUDIO_CAPTURE = 3;
const unsigned short SPEECH_INPUT_ERR_NETWORK = 4;
const unsigned short SPEECH_INPUT_ERR_NOT_ALLOWED = 5;
const unsigned short SPEECH_INPUT_ERR_SERVICE_NOT_ALLOWED = 6;
const unsigned short SPEECH_INPUT_ERR_BAD_GRAMMAR = 7;
const unsigned short SPEECH_INPUT_ERR_LANGUAGE_NOT_SUPPORTED = 8;

readonly attribute unsigned short code;
readonly attribute DOMString message;
};

// Item in N-best list
interface SpeechInputAlternative {
readonly attribute DOMString utterance;
readonly attribute float confidence;
readonly attribute any interpretation;
};

// A complete one-shot simple response
interface SpeechInputResult {
readonly attribute Document resultEMMAXML;
readonly attribute DOMString resultEMMAText;
readonly attribute unsigned long length;
getter SpeechInputAlternative item(in unsigned long index);
readonly attribute boolean final;
};

// A full response, which could be interim or final, part of a continuous response or not
interface SpeechInputResultEvent : Event {
readonly attribute SpeechInputResult result;
readonly attribute short resultIndex;
readonly attribute SpeechInputResult[] results;
readonly attribute DOMString sessionId;
};

// The object representing a speech grammar
[Constructor]
interface SpeechGrammar {
attribute DOMString src;
attribute float weight;
attribute boolean modal;
};

// The object representing a speech parameter
[Constructor]
interface SpeechParameter {
attribute DOMString name;
attribute DOMString value;
};





Speech Input API Specification

Speech Input API Specification这一份是2个google的员工提交的方案,时间也比较早,为2010年10月18日,不知道现在是否还在维护,Latest Editor's Draft的链接都没有了。该文档提供的语音输入方案为在现有的input标签上增加speech属性,另外通过给input元素增加相应事件来获取语音输入的状态。具体扩展的方案如下:



interface HTMLInputElement : HTMLElement {
...

// speech input attributes
attribute boolean speech;
attribute DOMString grammar;
attribute short maxresults;
attribute long nospeechtimeout;

// speech input event handler IDL attributes
attribute Function oncapturestart();
attribute Function onspeechstart();
attribute Function onspeechchange(in SpeechInputEvent event);
attribute Function onspeechend();
attribute Function onspeecherror(in SpeechInputError error);

// speech input methods
void startSpeechInput();
void stopSpeechInput();
void cancelSpeechInput();
};




该规范还提出同一时刻只允许有一个speech input sesseion存在。


Speech JavaScript API Specification

该规范最新版本为2011年12月22日,也是由google工程师提交的,目前处于非正式提案的状态,该规范可以和Speech Input API Specification一起看(工程师基本是同一拨人),一个是针对input元素的扩展,一个是针对js层面的扩展。

该规范仅涉及JS的API,提供了两个接口:SpeechReco和TTS,其中SpeechReco与HTML Speech Web API的SpeechInputRequest功能类似,可以发起语音识别,并通过事件获取结果。



[Constructor]
interface SpeechReco {
// recognition parameters
SpeechGrammarList grammars;

DOMString lang;
attribute boolean continuous;
// methods to drive the speech interaction
void start();
void stop();
void abort();

// event methods
attribute Function onaudiostart;
attribute Function onsoundstart;
attribute Function onspeechstart;
attribute Function onspeechend;
attribute Function onsoundend;
attribute Function onaudioend;
attribute Function onresult;
attribute Function onnomatch;
attribute Function onresultdeleted;
attribute Function onerror;
attribute Function onstart;
attribute Function onend;
};

SpeechReco implements EventTarget;
interface SpeechInputError {
const unsigned short OTHER = 0;
const unsigned short NO_SPEECH = 1;
const unsigned short ABORTED = 2;
const unsigned short AUDIO_CAPTURE = 3;
const unsigned short NETWORK = 4;
const unsigned short NOT_ALLOWED = 5;
const unsigned short SERVICE_NOT_ALLOWED = 6;
const unsigned short BAD_GRAMMAR = 7;
const unsigned short LANGUAGE_NOT_SUPPORTED = 8;

readonly attribute unsigned short code;
readonly attribute DOMString message;
};

// Item in N-best list
interface SpeechInputAlternative {
readonly attribute DOMString transcript;
readonly attribute float confidence;
readonly attribute any interpretation;
};

// A complete one-shot simple response
interface SpeechInputResult {
readonly attribute unsigned long length;
getter SpeechInputAlternative item(in unsigned long index);
readonly attribute boolean final;
};

// A collection of responses (used in continuous mode)
interface SpeechInputResultList {
readonly attribute unsigned long length;
getter SpeechInputResult item(in unsigned long index);
};

// A full response, which could be interim or final, part of a continuous response or not
interface SpeechInputResultEvent : Event {
readonly attribute SpeechInputResult result;
readonly attribute SpeechInputError error;
readonly attribute short resultIndex;
readonly attribute SpeechInputResultList resultHistory;
};

// The object representing a speech grammar
[Constructor]
interface SpeechGrammar {
attribute DOMString src;
attribute float weight;
};

// The object representing a speech grammar collection
[Constructor]
interface SpeechGrammarList {
readonly attribute unsigned long length;
getter SpeechGrammar item(in unsigned long index);
void addFromUri(in DOMString src,
optional float weight);
void addFromString(in DOMString string,
optional float weight);
};






[Constructor]
interface TTS {
attribute DOMString text;
attribute DOMString lang;
readonly attribute boolean paused;
readonly attribute boolean ended;

// methods to drive the speech interaction
void play();
void pause();
void stop();

attribute Function onstart;
attribute Function onend;
};





小结

HTML Speech Web API方案为增加reco元素负责提供语音输入的UI,tts元素负责提供text-to-speech功能,JS的SpeechInputRequest可作为独立的接口调用获取语音识别结果。Speech Input API Specification和Speech Javascript API Specification可以一起来看,它的方案是在原有的input元素上扩展,在界面上提供语音输入入口,同时提供SpeechReco的JS接口来单独发起语音识别并获取结果。


HTML5项目笔记4:使用Audio
API设计HTML5音乐播放器

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 设计出灵活的应用。

接下来,我们设计一款适合我们离线工作系统需要的播放器:


View
Code



1 //在页面放置一个audio元素,因为我们使用自己设计的播放界面,所以这边不用他们的controls。
2 <audio id="myMusic" > </audio>
3
4 //这边放置一个隐藏域,他的作用是存放媒体文件暂停的时间点
5 <input id="PauseTime"  type="hidden" />
6
7     //编写音乐盒的界面
8     <div class="MusicBox" >
9
10     <div class="LeftControl" ></div> //上一个媒体文件的控制图标
11     <div id="MainControl" class="MainControl" ></div>  //开始和暂停的控制图标
12     <div class="RightControl" ></div> //下一个媒体文件的控制图标
13
14     <div class="ProcessControl">//进度条
15     <div class="SongName">Ben's Music Box!</div> //媒体文件标题
16     <div class="SongTime">00:00 | 00:00</div> //时间进度
17     <div class="Process" ></div> //全部时长的进度条
18     <div class="ProcessYet"></div> //已播放时长的进度条
19     </div>
20
21     <div class="VoiceEmp"></div> //静音图标
22     <div class="VoidProcess" ></div> //全音量进度条
23     <div class="VoidProcessYet" ></div> //当前音量进度条
24     <div class="VoiceFull" ></div>//全音量图标
25     <div class="ShowMusicList" ></div> //显示或隐藏媒体文件列表图标
26
27     </div>
28
29
30     <div class="MusicList">  //媒体文件列表区域
31     <div class="Author"></div> //当前媒体文件的
32     <div class="List"> //媒体文件列表
33
34     <div class="Single" > //单个媒体文件
35     <span class="SongName"  KV="Fate" >01.Fate</span>
36     </div>
37
38     </div>
39     </div>




画好这个结构之后,我们就来写相应的CSS样式了:


View
Code



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:hover
108
109   {
110
111       background:url(../Images/sk-dark.png) left -30px no-repeat;
112
113   }
114
115
116
117
118
119   //下一个媒体文件的控制图标
120
121   .RightControl
122
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:hover
142
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  .ProcessControl
156
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 .Process
180
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 .ProcessYet
200
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    .VoiceEmp
224
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:hover
242
243    {
244
245       background:url(../Images/sk-dark.png) -28px -212px no-repeat;
246
247    }
248
249
250
251 //总音量进度条
252
253     .VoidProcess
254
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    .VoidProcessYet
278
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    .VoiceFull
302
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:hover
320
321    {
322
323       background:url(../Images/sk-dark.png) -28px -148px no-repeat;
324
325    }
326
327
328
329
330
331  //呈现出播放图标
332
333  .MainControl
334
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:hover
352
353    {
354
355       background:url(../Images/sk-dark.png) -80px -166px no-repeat;
356
357    }
358
359
360
361    //呈现出暂停或停止图标
362
363    .StopControl
364
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:hover
382
383    {
384
385       background:url(../Images/sk-dark.png) -50px -165px no-repeat;
386
387    }
388
389      //显示多媒体文件列表的控制图标
390
391      .ShowMusicList
392
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:hover
414
415      {
416
417       background:url(../Images/sk-dark.png) -20px -29px no-repeat;
418
419      }
420
421
422
423    //文件列表区域的样式代码
424
425    .MusicList
426
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 .Author
504
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 .List
534
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 .Single
566
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 .SongName
588
589      {
590
591        width:90%;
592
593        float:left;
594
595      }




页面的元素和CSS样式写完之后,就可以看到一个漂亮的音乐播放器的模型了,如图:



只是现在的播放器上面的按钮都是空壳,没有任何功能。所以,现在我们就来添加这些功能 , 脚本的顶层框架就用Jquery。


View
Code



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; //代表break
104
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; //代表break
152
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; //代表break
364
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的照片也是贴上去的,这些都可以做成动态获取或则与服务器交互,有兴趣的可以去试一下,扩展一下。
本来准备在我们的离线工作系统中添加音频播放器,后来需求变更,放弃了,所以这个版本不是完善的版本。视频播放器的功能大同小异,也可以自己试试。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: