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 {// Attributesreadonly 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 methodvoid sendInfo(in DOMString type, in DOMString value);// Default markup binding methodsvoid addGrammarFrom(in Element inputElement, optional float weight, optional boolean modal);void outputToElement(in Element outputElement);// methods to drive the speech interactionvoid 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 attributesattribute 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 methodsvoid 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 interactionvoid 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 interactionvoid 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&nbsp;|&nbsp;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的照片也是贴上去的,这些都可以做成动态获取或则与服务器交互,有兴趣的可以去试一下,扩展一下。

本来准备在我们的离线工作系统中添加音频播放器,后来需求变更,放弃了,所以这个版本不是完善的版本。视频播放器的功能大同小异,也可以自己试试。

HTML5 Speech API和Audio API相关推荐

  1. html5学习笔记(audio)

    来源于<HTML5高级程序设计> audio api <audio controls> controls告诉浏览器显示播放控件 不指定 type 浏览器自解 ogg MP3 t ...

  2. 开大你的音响,感受HTML5 Audio API带来的视听盛宴

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 话说HTML5的炫酷真的是让我爱不释手,即使在这个提到IE就伤心不完的年代.但话又说回来,追求卓越W ...

  3. 利用HTML5 Web Audio API给网页JS交互增加声音

    转自张鑫旭老师博客 原文地址 一.庞然的HTML5 Web Audio API 首先务必要弄清这一点,本文这里所说的HTML5 Web Audio API和HTML5 元素完全不是一个东西,其体量也完 ...

  4. HTML5 Audio API

    话说HTML5的炫酷真的是让我爱不释手,即使在这个提到IE就伤心不完的年代.但话又说回来,追求卓越Web创造更美世界这样高的追求什么时候又与IE沾过边儿呢?所以当你在看本文并且我们开始讨论HTML5等 ...

  5. 感受HTML5 Audio API带来的视听盛宴

    开大你的音响,感受HTML5 Audio API带来的视听盛宴 话说HTML5的炫酷真的是让我爱不释手,即使在这个提到IE就伤心不完的年代.但话又说回来,追求卓越Web创造更美世界这样高的追求什么时候 ...

  6. HTML5 Web Audio Api-2 发声oscillator

    (Web Audio Api基础信息整理中,到时候补上) oscillator的意思是振荡器,众所周知,声音就是物体振动产生的声波. 在Web Audio Api中,官方给我们提供了一个振荡器 需要用 ...

  7. ASP.NET Core环境Web Audio API+SingalR+微软语音服务实现web实时语音识别

    处于项目需要,我研究了一下web端的语音识别实现.目前市场上语音服务已经非常成熟了,国内的科大讯飞或是国外的微软在这块都可以提供足够优质的服务,对于我们工程应用来说只需要花钱调用接口就行了,难点在于整 ...

  8. 一段简单的html 5 音频,5个用于处理HTML5音频的库和API

    在过去的几个月中,我遇到了许多不同的库,它们利用了相对较新的HTML5 Audio API以及更著名的HTML5 Audio Element及其更简单的API. 我以为我会在本文中分享这些库中的一小部 ...

  9. 【Web】1326- 深入浅出 Web Audio API

    前言 2011被提出,同年草案被Google Chrome和Mozilla Firefox实现 在此之前Web音频较为原始,无法应付较为复杂的应用场景,例如Web游戏或互动应用 旨在提供全套Web音频 ...

最新文章

  1. 投了3遍都被毙的论文,终于中了
  2. SAE上安装第三方模块
  3. 前端html继承的方式,好程序员web前端教程之JS继承实现方式解析
  4. matlab练习程序(点云下采样)
  5. ip, tcp, udp, icmp header
  6. mysql入门到跑路_MySQL 24小时入门笔记(3),插入和删除,删库到跑路
  7. 【Xamarin 跨平台机制原理剖析】
  8. 实战演习(九)——用python分析科比生涯数据
  9. Python数据库操作-pyodbc
  10. Entersekt欢迎Nicolas Huss加入董事会
  11. Hugepages详解
  12. 直线拟合fitLine函数的用法
  13. 遍历指定文件夹下的所有文件名
  14. 解决one-stage目标检测正负样本不均衡的另类方法--Gradient Harmonized
  15. VCC、VDD、VSS、GND区别
  16. 《香帅金融学讲义》读书笔记
  17. 肥胖与高血压有什么关系?
  18. webrtc学习笔记二:webrtc介绍
  19. 重装系统时不小心全盘分区了的文件恢复办法
  20. Windows下部署Swagger Edit、Swagger UI

热门文章

  1. 利用命令激活未激活的Windows10专业版系统的技巧 2018/9/9亲测有效
  2. tableau 常识积累
  3. 空手道及主要流派简介
  4. Android Studio项目手机模拟测试(华为荣耀系列)
  5. python time计时_python中的计时器timeit的使用方法
  6. Oracle插入数据每5000条提交一次
  7. mysql区间统计函数
  8. C语言的正则表达式--入门
  9. AirPods无法正常工作怎么回事?
  10. vimplus安装出现git clone失败的解决方案