1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
|
---
title: Доставка аудио и видео контента
slug: Web/Guide/Audio_and_video_delivery
tags:
- Audio
- HTML5
- Media
- NeedsTranslation
- TopicStub
- Video
translation_of: Web/Guide/Audio_and_video_delivery
---
<div class="summary">
<p>Мы можем доставлять аудио и видео контент различными способами. Это могут быть как статичные медиа файлы, так и потоковые данные. Эта статья является отправной точкой в изучении различных механизмов доставки медиа ресурсов и совместимости работы с популярными браузерами.</p>
</div>
<h2 id="Аудио_и_видео_элементы">Аудио и видео элементы</h2>
<p>Whether we are dealing with pre-recorded audio files or live streams, the mechanism for making them available through the browser's {{ htmlelement("audio")}} and {{ htmlelement("video")}} elements remains pretty much the same. Currently, to support all browsers we need to specify two formats, although with the adoption of MP3 and MP4 formats in Firefox and Opera, this is changing fast. You can find compatibility information in the following places:</p>
<ul>
<li><a href="/en-US/Apps/Build/Manipulating_media/Cross-browser_audio_basics#Audio_Codec_Support">Audio Codec Compatibility Table</a></li>
<li><a href="/en-US/docs/Web/HTML/Supported_media_formats#Browser_compatibility">Audio/Video Codec Compatibility Table</a></li>
</ul>
<p>To deliver video and audio, the general workflow is usually something like this:</p>
<ol>
<li>Check what format the browser supports via feature detection (usually a choice of two, as stated above.)</li>
<li>If the browser doesn't support playback of any of the provided formats natively, provide a fallback (such as a Flash movie.)</li>
<li>Identify how you want to play/instantiate the media (e.g. a {{ htmlelement("video") }} element, or <code>document.createElement('video')</code> perhaps?)</li>
<li>Deliver the media file to the player.</li>
</ol>
<h3 id="HTML_Audio">HTML Audio</h3>
<pre class="brush: html"><audio controls preload="auto">
<source src="audiofile.mp3" type="audio/mpeg">
<!-- fallback for browsers that don't suppport mp3 -->
<source src="audiofile.ogg" type="audio/ogg">
<!-- fallback for browsers that don't support audio tag -->
<a href="audiofile.mp3">download audio</a>
</audio></pre>
<p>The code above will create an audio player that attempts to preload as much audio as possible for smooth playback.</p>
<div class="note">
<p><strong>Note</strong>: The preload attribute may be ignored by some mobile browsers.</p>
</div>
<p>For further info see <a href="/en-US/Apps/Build/Manipulating_media/Cross-browser_audio_basics#HTML5_audio_in_detail">Cross Browser Audio Basics (HTML5 Audio In Detail)</a></p>
<h3 id="HTML_Video">HTML Video</h3>
<pre class="brush: html"><video controls width="640" height="480" poster="initialimage.png" autoplay muted>
<source src="videofile.mp4" type="video/mp4">
<!-- fallback for browsers that don't suppport mp4 -->
<source src="videofile.webm" type="video/webm">
<!-- specifying subtitle files -->
<track src="subtitles_en.vtt" kind="subtitles" srclang="en" label="English">
<track src="subtitles_no.vtt" kind="subtitles" srclang="no" label="Norwegian">
<!-- fallback for browsers that don't support video tag -->
<a href="videofile.mp4">download video</a>
</video></pre>
<p>The code above creates a video player of dimensions 640x480 pixels, displaying a poster image until the video is played. We instruct the video to autoplay but to be muted by default.</p>
<div class="note">
<p><strong>Note</strong>: The autoplay attribute may be ignored by some mobile browsers.</p>
</div>
<p>For further info see <a href="https://developer.mozilla.org/en/docs/Web/HTML/Element/video"><video> element</a> and <a href="/en-US/Apps/Build/Manipulating_media/cross_browser_video_player">Creating a cross-browser video player</a>.</p>
<h3 id="Audio_and_Video_Fallback">Audio and Video Fallback</h3>
<p>You can create a more comprehensive Fallback using Flash. <a href="https://github.com/johndyer/mediaelement/blob/master/build/flashmediaelement.swf">Using flashmediaelement.swf</a> is one way.</p>
<pre class="brush: html"><audio controls>
<source src="audiofile.mp3" type="audio/mpeg">
<source src="audiofile.ogg" type="audio/ogg">
<!-- fallback for non supporting browsers goes here -->
<a href="audiofile.mp3">download audio</a>
<object width="320" height="30" type="application/x-shockwave-flash" data="flashmediaelement.swf">
<param name="movie" value="flashmediaelement.swf" />
<param name="flashvars" value="controls=true&isvideo=false&file=audiofile.mp3" />
</object>
</audio></pre>
<p>The process is very similar with video — just remember to set <code>isvideo=true</code> in the <code>flashvars value</code> parameters.<br>
<br>
<a href="/en-US/Apps/Build/Manipulating_media/Cross-browser_audio_basics#Fallbacks">More options for Fallbacks</a>.</p>
<h3 id="JavaScript_Audio">JavaScript Audio</h3>
<pre class="brush: js">var myAudio = document.createElement('audio');
if (myAudio.canPlayType('audio/mpeg')) {
myAudio.setAttribute('src','audiofile.mp3');
} else if (myAudio.canPlayType('audio/ogg')) {
myAudio.setAttribute('src','audiofile.ogg');
}
myAudio.currentTime = 5;
myAudio.play();</pre>
<p>We set the source of the audio depending on the type of audio file the browser supports, then set the play-head 5 seconds in and attempt to play it.</p>
<div class="note">
<p><strong>Note</strong>: Play will be ignored by some mobile browsers unless issued by a user-initiated event.</p>
</div>
<p>It's also possible to feed an {{ htmlelement("audio") }} element a base64 encoded WAV file, allowing to generate audio on the fly:</p>
<pre class="brush: html"><audio id="player" src="data:audio/x-wav;base64,UklGRvC..."></audio></pre>
<p><a href="https://github.com/kripken/speak.js/">Speak.js</a> employs this technique. <a href="http://speak-demo.herokuapp.com">Try the demo</a>.</p>
<h3 id="JavaScript_Video">JavaScript Video</h3>
<pre class="brush: js">var myVideo = document.createElement('video');
if (myVideo.canPlayType('video/mp4')) {
myVideo.setAttribute('src','videofile.mp4');
} else if (myVideo.canPlayType('video/webm')) {
myVideo.setAttribute('src','videofile.webm');
}
myVideo.width = 480;
myVideo.height = 320;</pre>
<p>We set the source of the video depending on the type of video file the browser supports we then set the width and height of the video.</p>
<h2 id="Web_Audio_API">Web Audio API</h2>
<pre class="brush: js"> var context;
var request;
var source;
try {
context = new AudioContext();
request = new XMLHttpRequest();
request.open("GET","http://jplayer.org/audio/mp3/RioMez-01-Sleep_together.mp3",true);
request.responseType = "arraybuffer";
request.onload = function() {
context.decodeAudioData(request.response, function(buffer) {
source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
// auto play
source.start(0); // start was previously noteOn
});
};
request.send();
} catch(e) {
alert('web audio api not supported');
}</pre>
<p>In this example we retrieve an MP3 file via XHR, load it into a source and play it (<a href="http://jsbin.com/facutone/1/edit?js">Try it for yourself</a>). Find more about Web Audio API basics in <a href="/en-US/docs/Web/API/Web_Audio_API/Using_Web_Audio_API">Using the Web Audio API</a>.</p>
<h2 id="getUserMedia_Stream_API">getUserMedia / Stream API</h2>
<p>It's also possible to retrieve a live stream from a webcam and/or microphone using <code>getUserMedia</code> and the Stream API. This makes up part of a wider technology known as WebRTC (Web Real-Time Communications) and is compatible with the latest versions of Chrome, Firefox and Opera.</p>
<p>To grab the stream from your webcam, first set up a {{htmlelement("video")}} element:</p>
<pre class="brush: html"><video id="webcam" width="480" height="360"></video></pre>
<p>Next, if supported connect the webcam source to the video element:</p>
<pre class="brush: js">if (navigator.mediaDevices) {
navigator.mediaDevices.getUserMedia({ video: true, audio: false })
.then(function onSuccess(stream) {
var video = document.getElementById('webcam');
video.autoplay = true;
video.srcObject = stream;
})
.catch(function onError() {
alert('There has been a problem retreiving the streams - are you running on file:/// or did you disallow access?');
});
} else {
alert('getUserMedia is not supported in this browser.');
}
</pre>
<p>To find out more, read our {{domxref("MediaDevices.getUserMedia")}} page.</p>
<h2 id="Mediastream_Recording">Mediastream Recording</h2>
<p>New standards are being rolled out to allow your browser to grab media from your mic or camera using <code>getUserMedia</code> and record it instantly using the new MediaRecorder API. You take the stream you receive from <code>getUserMedia</code>, pass it to a <code>MediaRecorder</code> object, take the resulting output and feed it to your audio or video source*.<br>
<br>
The main mechanism is outlined below:</p>
<pre class="brush: js">navigator.mediaDevices.getUserMedia({audio:true})
.then(function onSuccess(stream) {
var recorder = new MediaRecorder(stream);
var data = [];
recorder.ondataavailable = function(e) {
data.push(e.data);
};
recorder.start();
recorder.onerror = function(e) {
throw e.error || new Error(e.name); // e.name is FF non-spec
}
recorder.onstop = function(e) {
var audio = document.createElement('audio');
audio.src = window.URL.createObjectURL(new Blob(data));
}
setTimeout(function() {
rec.stop();
}, 5000);
})
.catch(function onError(error) {
console.log(error.message);
});
</pre>
<p>See <a href="/en-US/docs/Web/API/MediaRecorder_API">MediaRecorder API</a> for more details.</p>
<h2 id="Media_Source_Extensions_(MSE)">Media Source Extensions (MSE)</h2>
<p><a href="https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html">Media Source Extensions</a> is a W3C working draft that plans to extend {{domxref("HTMLMediaElement")}} to allow JavaScript to generate media streams for playback. Allowing JavaScript to generate streams facilitates a variety of use cases like adaptive streaming and time shifting live streams.</p>
<h3 id="Encrypted_Media_Extensions_(EME)">Encrypted Media Extensions (EME)</h3>
<p><a href="https://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/encrypted-media.html">Encrypted Media Extensions</a> is a W3C proposal to extend <code>HTMLMediaElement</code>, providing APIs to control playback of protected content.<br>
<br>
The API supports use cases ranging from simple clear key decryption to high value video (given an appropriate user agent implementation). License/key exchange is controlled by the application, facilitating the development of robust playback applications supporting a range of content decryption and protection technologies.<br>
<br>
One of the principle uses of EME is to allow browsers to implement DRM (<a href="http://en.wikipedia.org/wiki/Digital_rights_management">Digital Rights Management</a>), which helps to prevent web-based content (especially video) from being copied.</p>
<h3 id="Adaptive_Streaming">Adaptive Streaming</h3>
<p>New formats and protocols are being rolled out to facilitate adaptive streaming. Adaptive streaming media means that the bandwidth and typically quality of the stream can change in real-time in reaction to the user's available bandwidth. Adaptive streaming is often used in conjunction with live streaming where smooth delivery of audio or video is paramount.</p>
<p>The main formats used for adaptive streaming are <a href="/en-US/Apps/Build/Manipulating_media/Live_streaming_web_audio_and_video#HLS">HLS</a> and <a href="/en-US/Apps/Build/Manipulating_media/Live_streaming_web_audio_and_video#MPEG-DASH">MPEG-DASH</a>. MSE has been designed with DASH in mind. MSE defines byte streams according to <a href="https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/isobmff-byte-stream-format.html">ISOBMFF</a> and <a href="http://en.wikipedia.org/wiki/M2ts">M2TS</a> (both supported in DASH, the latter supported in HLS). Generally speaking, if you are interested in standards, are looking for flexibility, or wish to support most modern browsers, you are probably better off with DASH.</p>
<div class="note">
<p><strong>Note</strong>: Currently Safari does not support DASH although dash.js will work on newer versions of Safari scheduled for release with OSX Yosemite.</p>
</div>
<p>DASH also provides a number of profiles including simple onDemand profiles that no preprocessing and splitting up of media files. There are also a number of cloud based services that will convert your media to both HLS and DASH.<br>
<br>
For further information see <a href="/en-US/Apps/Build/Manipulating_media/Live_streaming_web_audio_and_video">Live streaming web audio and video</a>.</p>
<ul>
</ul>
<h2 id="Customising_Your_Media_Player">Customising Your Media Player</h2>
<p>You may decide that you want your audio or video player to have a consistent look across browsers, or just wish to tweak it to match your site. The general technique for achieving this is to omit the <code>controls</code> attribute so that the default browser controls are not displayed, create custom controls using HTML and CSS, then use JavaScript to link your controls to the audio/video API.</p>
<p>If you need something extra, it's possible to add features that are not currently present in default players, such as playback rate, quality stream switches or even audio spectrums. You can also choose how to make your player responsive — for example you might remove the progress bar under certain conditions.</p>
<p>You may detect click, touch and/or keyboard events to trigger actions such as play, pause and scrubbing. It's often important to remember keyboard controls for user convenience and accessibility.</p>
<p>A quick example — first set up your audio and custom controls in HTML:</p>
<pre class="brush: html"> <audio id="my-audio" src="http://jPlayer.org/audio/mp3/Miaow-01-Tempered-song.mp3"></audio>
<button id="my-control">play</button></pre>
<p>add a bit of JavaScript to detect events to play and pause the audio:</p>
<pre class="brush: js">window.onload = function() {
var myAudio = document.getElementById('my-audio');
var myControl = document.getElementById('my-control');
function switchState() {
if (myAudio.paused == true) {
myAudio.play();
myControl.innerHTML = "pause";
} else {
myAudio.pause();
myControl.innerHTML = "play";
}
}
function checkKey(e) {
if (e.keycode == 32 ) { //spacebar
switchState();
}
}
myControl.addEventListener('click', function() {
switchState();
}, false);
window.addEventListener( "keypress", checkKey, false );
}</pre>
<p>You can <a href="http://jsbin.com/jujeladu/2/edit">try this example out here</a>. For more information, see <a href="https://developer.mozilla.org/en-US/Apps/Build/Manipulating_media/Cross-browser_audio_basics#Creating_your_own_custom_audio_player">Creating your own custom audio player</a>.</p>
<h2 id="Other_tips_for_audiovideo">Other tips for audio/video</h2>
<h3 id="Stopping_the_download_of_media">Stopping the download of media</h3>
<p>While stopping the playback of media is as easy as calling the element's <code>pause()</code> method, the browser keeps downloading the media until the media element is disposed of through garbage collection.</p>
<p>Here's a trick that stops the download at once:</p>
<pre class="brush: js">var mediaElement = document.querySelector("#myMediaElementID");
mediaElement.<code>removeAttribute("src");</code>
mediaElement.<code>load();</code>
</pre>
<p>By removing the media element's <code>src</code> attribute and invoking the load() method, you release the resources associated with the video, which stops the network download. You must call <code>load()</code> after removing the attribute, because just removing the <code>src</code> attribute does not invoke the load algorithm. If the <code><video></code> element also has <code><source></code> element descendants, those should also be removed before calling <code>load()</code>.</p>
<p>Note that just setting the <code>src</code> attribute to an empty string will actually cause the browser to treat it as though you're setting a video source to a relative path. This causes the browser to attempt another download to something that is unlikely to be a valid video.</p>
<h3 id="Seeking_through_media">Seeking through media</h3>
<p>Media elements provide support for moving the current playback position to specific points in the media's content. This is done by setting the value of the <code>currentTime</code> property on the element; see {{ domxref("HTMLMediaElement") }} for further details on the element's properties. Simply set the value to the time, in seconds, at which you want playback to continue.</p>
<p>You can use the element's <code>seekable</code> property to determine the ranges of the media that are currently available for seeking to. This returns a {{ domxref("TimeRanges") }} object listing the ranges of times that you can seek to.</p>
<pre class="brush: js">var mediaElement = document.querySelector('#mediaElementID');
mediaElement.seekable.start(0); // Returns the starting time (in seconds)
mediaElement.seekable.end(0); // Returns the ending time (in seconds)
mediaElement.currentTime = 122; // Seek to 122 seconds
mediaElement.played.end(0); // Returns the number of seconds the browser has played
</pre>
<h3 id="Specifying_playback_range">Specifying playback range</h3>
<p>When specifying the URI of media for an {{ HTMLElement("audio") }} or {{ HTMLElement("video") }} element, you can optionally include additional information to specify the portion of the media to play. To do this, append a hash mark ("#") followed by the media fragment description.</p>
<p>A time range is specified using the syntax:</p>
<pre>#t=[starttime][,endtime]</pre>
<p>The time can be specified as a number of seconds (as a floating-point value) or as an hours/minutes/seconds time separated with colons (such as 2:05:01 for 2 hours, 5 minutes, and 1 second).</p>
<p>A few examples:</p>
<dl>
<dt><span class="nowiki">http://example.com/video.ogv#t=10,20</span></dt>
<dd>Specifies that the video should play the range 10 seconds through 20 seconds.</dd>
<dt><span class="nowiki">http://example.com/video.ogv#t=,10.5</span></dt>
<dd>Specifies that the video should play from the beginning through 10.5 seconds.</dd>
<dt><span class="nowiki">http://example.com/video.ogv#t=,02:00:00</span></dt>
<dd>Specifies that the video should play from the beginning through two hours.</dd>
<dt><span class="nowiki">http://example.com/video.ogv#t=60</span></dt>
<dd>Specifies that the video should start playing at 60 seconds and play through the end of the video.</dd>
</dl>
<div class="note">
<p><strong>Note</strong>: The playback range portion of the media element URI specification was added to Gecko 9.0 {{ geckoRelease("9.0") }}. At this time, this is the only part of the <a class="external" href="http://www.w3.org/TR/media-frags/" title="http://www.w3.org/TR/media-frags/">Media Fragments URI specification</a> implemented by Gecko, and it can only be used when specifying the source for media elements, and not in the address bar.</p>
</div>
<h2 id="Error_handling">Error handling</h2>
<p>Starting in Gecko 2.0 {{ geckoRelease("2.0") }}, error handling has been revised to match the latest version of the HTML5 specification. Instead of the <code>error</code> event being dispatched to the media element itself, it now gets delivered to the child {{ HTMLElement("source") }} elements corresponding to the sources resulting in the error.</p>
<p>This lets you detect which sources failed to load, which may be useful. Consider this HTML:</p>
<pre class="brush: html"><video>
<source id="mp4_src"
src="video.mp4"
type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
</source>
<source id="3gp_src"
src="video.3gp"
type='video/3gpp; codecs="mp4v.20.8, samr"'>
</source>
<source id="ogg_src"
src="video.ogv"
type='video/ogv; codecs="theora, vorbis"'>
</source>
</video></pre>
<p>Since Firefox doesn't support MP4 and 3GP on some platforms due to their patent-encumbered nature, the {{ HTMLElement("source") }} elements with the IDs "mp4_src" and "3gp_src" will receive <code>error</code> events before the Ogg resource is loaded. The sources are tried in the order in which they appear, and once one loads successfully, the remaining sources aren't tried at all.</p>
<h3 id="Checking_whether_the_browser_supports_the_supplied_formats">Checking whether the browser supports the supplied formats</h3>
<p>Use the following verified sources within your audio and video elements to check support.</p>
<ul>
<li>Audio MP3 (<code>type="audio/mpeg"</code>): <a href="http://jPlayer.org/audio/mp3/Miaow-01-Tempered-song.mp3">http://jPlayer.org/audio/mp3/Miaow-01-Tempered-song.mp3</a> (<a href="http://jsbin.com/gekatoge/1/edit">play the MP3 audio live</a>.)</li>
<li>Audio MP4 (<code>type="audio/mp4"</code>): <a href="http://jPlayer.org/audio/m4a/Miaow-01-Tempered-song.m4a">http://jPlayer.org/audio/m4a/Miaow-01-Tempered-song.m4a</a> (<a href="http://jsbin.com/gekatoge/2/edit">play the MP4 audio live</a>.)</li>
<li>Audio Ogg (<code>type="audio/ogg"</code>): <a href="http://jPlayer.org/audio/ogg/Miaow-01-Tempered-song.ogg">http://jPlayer.org/audio/ogg/Miaow-01-Tempered-song.ogg</a> (<a href="http://jsbin.com/gekatoge/4/edit">play the OGG audio live</a>.)</li>
<li>Video MP4 (<code>type="video/mp4"</code>): <a href="http://jPlayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v">http://jPlayer.org/video/m4v/Big_Buck_Bunny_Trailer.m4v</a> (<a href="http://jsbin.com/gekatoge/5/edit">play the MP4 video live</a>.)</li>
<li>Video WebM (<code>type="video/webm"</code>): <a href="http://jPlayer.org/video/webm/Big_Buck_Bunny_Trailer.webm">http://jPlayer.org/video/webm/Big_Buck_Bunny_Trailer.webm</a> (<a href="http://jsbin.com/gekatoge/6/edit">play the WebM video live</a>.)</li>
<li>Video Ogg (<code>type="video/ogg"</code>): <a href="http://jPlayer.org/video/ogv/Big_Buck_Bunny_Trailer.ogv">http://jPlayer.org/video/ogv/Big_Buck_Bunny_Trailer.ogv</a> (<a href="http://jsbin.com/gekatoge/7/edit">play the OGG video live</a>.)</li>
</ul>
<p>If these don't play then the browser you are testing doesn't support the given format. Consider using a different format or using a fallback.<br>
<br>
If these work but the files you are supplying don't, there are two possible issues:</p>
<h4 id="1._The_media_server_is_not_delivering_the_correct_mime_types_with_the_file">1. The media server is not delivering the correct mime types with the file</h4>
<p>Although this is usually supported, you may need to add the following to your media server's <code>.htaccess</code> file.</p>
<pre># AddType TYPE/SUBTYPE EXTENSION
AddType audio/mpeg mp3
AddType audio/mp4 m4a
AddType audio/ogg ogg
AddType audio/ogg oga
AddType video/mp4 mp4
AddType video/mp4 m4v
AddType video/ogg ogv
AddType video/webm webm
AddType video/webm webmv</pre>
<h4 id="2._Your_files_have_been_encoded_incorrectly">2. Your files have been encoded incorrectly</h4>
<p>Your files may have been encoded incorrectly — try encoding using one of the following tools, which are proven to be pretty reliable:</p>
<ul>
<li><a href="http://audacity.sourceforge.net/">Audacity</a> — Free Audio Editor and Recorder</li>
<li><a href="http://www.getmiro.com/">Miro</a> — Free, open-source music and video player</li>
<li><a href="http://handbrake.fr/">Handbrake</a> — Open Source Video Transcoder</li>
<li><a href="http://firefogg.org/">Firefogg</a> — Video and Audio encoding for Firefox</li>
<li><a href="https://www.ffmpeg.org/">FFmpeg2</a> — Comprehensive command line encoder</li>
<li><a href="https://libav.org/">Libav</a> — Comprehensive command line encoder</li>
<li><a href="http://m.vid.ly/">Vid.ly</a> — Video player,transcoding and delivery</li>
<li><a href="https://archive.org/">Internet Archive</a> — Free transcoding and storage</li>
</ul>
<h3 id="Detecting_when_no_sources_have_loaded">Detecting when no sources have loaded</h3>
<p>To detect that all child {{ HTMLElement("source") }} elements have failed to load, check the value of the media element's <code>networkState</code> attribute. If this is <code>HTMLMediaElement.NETWORK_NO_SOURCE</code>, you know that all the sources failed to load.</p>
<p>If at that point you add another source, by inserting a new {{ HTMLElement("source") }} element as a child of the media element, Gecko attempts to load the specified resource.</p>
<h3 id="Showing_fallback_content_when_no_source_could_be_decoded">Showing fallback content when no source could be decoded</h3>
<p>Another way to show the fallback content of a video, when none of the sources could be decoded in the current browser, is to add an error handler on the last source element. Then you can replace the video with its fallback content:</p>
<pre class="brush: html"><video controls>
<source src="dynamicsearch.mp4" type="video/mp4"></source>
<a href="dynamicsearch.mp4">
<img src="dynamicsearch.jpg" alt="Dynamic app search in Firefox OS">
</a>
<p>Click image to play a video demo of dynamic app search</p>
</video>
</pre>
<pre class="brush: js">var v = document.querySelector('video'),
sources = v.querySelectorAll('source'),
lastsource = sources[sources.length-1];
lastsource.addEventListener('error', function(ev) {
var d = document.createElement('div');
d.innerHTML = v.innerHTML;
v.parentNode.replaceChild(d, v);
}, false);
</pre>
<h2 id="AudioVideo_JavaScript_Libraries">Audio/Video JavaScript Libraries</h2>
<p>A number of audio and video JavaScript libaries exist. The most popular libraries allow you to choose a consistent player design over all browsers and provide a fallback for browsers that don't support audio and video natively. Fallbacks often use Adobe Flash or Microsoft Silverlight plugins. Other functionality such as the track element for subtitles can also be provided through media libraries.</p>
<h3 id="Audio_only">Audio only</h3>
<ul>
<li><a href="http://www.schillmania.com/projects/soundmanager2/">SoundManager</a></li>
</ul>
<h3 id="Video_only">Video only</h3>
<ul>
<li><a href="https://flowplayer.org/">flowplayer</a>: Gratis with a flowplayer logo watermark. Open source (GPL licensed.)</li>
<li><a href="http://www.jwplayer.com">JWPlayer</a>: Requires registration to download. Open Source Edition (Creative Commons License.)</li>
<li><a href="http://www.sublimevideo.net/">SublimeVideo</a>: Requires registration. Form based set up with domain specific link to CDN hosted library.</li>
<li><a href="http://www.videojs.com/">Video.js</a>: Gratis and Open Source (Apache 2 Licensed.)</li>
</ul>
<h3 id="Audio_and_Video">Audio and Video</h3>
<ul>
<li><a href="http://jPlayer.org">jPlayer</a>: Gratis and Open Source (MIT Licensed.)</li>
<li><a href="http://mediaelementjs.com/">mediaelement.js</a>: Gratis and Open Source (MIT Licensed.)</li>
</ul>
<h3 id="Web_Audio_API_2">Web Audio API</h3>
<ul>
<li><a href="https://github.com/cwilso/AudioContext-MonkeyPatch">AudioContext monkeypatch</a>: A polyfill for older versions of the Web Audio API; Open Source (Apache 2 Licensed.)</li>
</ul>
<h2 id="Basic_tutorials">Basic tutorials</h2>
<dl>
<dt><a href="/en-US/Apps/Build/Manipulating_media/cross_browser_video_player">Creating a cross-browser video player</a></dt>
<dd>A guide to creating a basic cross browser video player using the {{ htmlelement ("video") }} element.</dd>
<dt><a href="/en-US/Apps/Build/Manipulating_media/Video_player_styling_basics">Video player styling basics</a></dt>
<dd>With the cross-browser video player put in place in the previous article, this article now looks at providing some basic, reponsive styling for the player.</dd>
<dt><a href="/en-US/Apps/Build/Manipulating_media/Cross-browser_audio_basics">Cross-browser audio basics</a></dt>
<dd>
<div>
<p>This article provides a basic guide to creating an HTML5 audio player that works cross browser, with all the associated attributes, properties and events explained, and a quick guide to custom controls created using the Media API.</p>
</div>
</dd>
<dt><a href="/en-US/Apps/Build/Manipulating_media/buffering_seeking_time_ranges">Media buffering, seeking, and time ranges</a></dt>
<dd>Sometimes it's useful to know how much {{ htmlelement("audio") }} or {{ htmlelement("video") }} has downloaded or is playable without delay — a good example of this is the buffered progress bar of an audio or video player. This article discusses how to build a buffer/seek bar using <a href="/en-US/docs/Web/API/TimeRanges">TimeRanges</a>, and other features of the media API.</dd>
<dt><a href="/en-US/Apps/Build/Manipulating_media/HTML5_playbackRate_explained">HTML5 playbackRate explained</a></dt>
<dd>The <code>playbackRate</code> property allows us to change the speed or rate at which a piece of web audio or video is playing. This article explains it in detail.</dd>
<dt><a href="/en-US/docs/Web/API/Web_Audio_API/Using_Web_Audio_API">Using the Web Audio API</a></dt>
<dd>Explains the basics of using the Web Audio API to grab, manipulate and play back an audio source.</dd>
</dl>
<h2 id="Streaming_media_tutorials">Streaming media tutorials</h2>
<dl>
<dt><a href="/en-US/Apps/Build/Manipulating_media/Live_streaming_web_audio_and_video">Live streaming web audio and video</a></dt>
<dd>Live streaming technology is often employed to relay live events such as sports, concerts and more generally TV and Radio programmes that are output live. Often shortened to just streaming, live streaming is the process of transmitting media 'live' to computers and devices. This is a fairly complex and nascent subject with a lot of variables, so in this article we'll introduce you to the subject and let you know how you can get started.</dd>
<dt><a href="/en-US/Apps/Build/Manipulating_media/Setting_up_adaptive_streaming_media_sources">Setting up adaptive streaming media sources</a></dt>
<dd>Let's say you want to set up an adaptive streaming media source on a server, to be consumed inside an HTML5 media element. How would you do that? This article explains how, looking at two of the most common formats: MPEG-DASH and HLS (HTTP Live Streaming.)</dd>
<dt><a href="/en-US/docs/Web/HTML/DASH_Adaptive_Streaming_for_HTML_5_Video">DASH Adaptive Streaming for HTML 5 Video</a></dt>
<dd>Details how to set up adaptive streaming using DASH and WebM.</dd>
</dl>
<h2 id="Advanced_tutorials">Advanced tutorials</h2>
<dl>
<dt><a href="/en-US/Apps/Build/Manipulating_media/Adding_captions_and_subtitles_to_HTML5_video">Adding captions and subtitles to HTML5 video</a></dt>
<dd>This article explains how to add captions and subtitles to HTML5 {{ htmlelement("video") }}, using <a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Video_Text_Tracks_Format" title="WebVTT is a format for displaying timed text tracks (e.g. subtitles) with the <track> element. The primary purpose of WebVTT files is to add subtitles to a <video>.">Web_Video_Text_Tracks_Format</a> and the {{ htmlelement("track") }} element.</dd>
<dt><a href="/en-US/docs/Web/Apps/Developing/Manipulating_media/Web_Audio_API_cross_browser" title="/en-US/docs/Web/Apps/Developing/Manipulating_media/Web_Audio_API_cross_browser">Writing Web Audio API code that works in every browser</a></dt>
<dd>A guide to writing cross browser Web Audio API code.</dd>
<dt><a href="/en-US/Apps/Developing/Manipulating_media/H.264_support_in_Firefox">H.264 support in Firefox</a></dt>
<dd>This article explains the state of support for the H.264 video format in Firefox/Firefox OS, including code examples, tips and tricks.</dd>
<dt><a href="https://hacks.mozilla.org/2014/06/easy-audio-capture-with-the-mediarecorder-api/">Easy audio capture with the MediaRecorder API</a></dt>
<dd>Explains the basics of using the MediaRecorder API to directly record a media stream.</dd>
</dl>
<div class="note">
<p><strong>Note</strong>: Firefox OS versions 1.3 and above support the <a href="http://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol" title="http://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol">RTSP</a> protocol for streaming video delivery. A fallback solution for older versions would be to use <code><video></code> along with a suitable format for Gecko (such as WebM) to serve fallback content. More information will be published on this in good time.</p>
</div>
<h2 id="References">References</h2>
<ul>
<li><a href="/en-US/docs/Web/HTML/Element/video">The video element</a></li>
<li><a href="/en-US/docs/Web/Guide/Events/Media_events">Media events API</a></li>
<li><a href="/en-US/docs/Web/API/HTMLVideoElement">HTMLVideoElement API</a></li>
<li><a href="/en-US/docs/Web/API/MediaSource">MediaSource API</a></li>
<li><a href="/en-US/docs/Web/API/Web_Audio_API">Web Audio API</a></li>
<li><a href="/en-US/docs/Web/API/MediaRecorder_API">MediaRecorder API</a></li>
<li><a href="/en-US/docs/Web/API/MediaDevices/getUserMedia">getUserMedia</a></li>
</ul>
<p> </p>
|