目錄[-]
最近在整理博客和瀏覽器收藏夾中的教程,把一些自己比較了解的基礎(chǔ)知識(shí)進(jìn)行了匯總,并且加入自己開發(fā)中遇到的問題和理解。由于參考來源太多,所以做了個(gè)詳細(xì)列表在下面,感謝這些作者的無私和偉大,呵呵!
來源參考:w3、w3school、來源一、來源二、來源三、來源四、來源五、QA
<audio> 標(biāo)簽屬性
<audio id="media" src="http://www.abc.com/test.mp3" controls></audio>
src:音樂的URL (source標(biāo)簽在src屬性不存在時(shí)使用)
preload:預(yù)加載(none、metadata、auto。如果不使用此屬性,默認(rèn)為auto。)
autoplay:自動(dòng)播放
loop:循環(huán)播放
controls:瀏覽器自帶的控制條
<video> 標(biāo)簽屬性
<video id="media" src="http://www.abc.com/test.mp4" controls width="400px" height="400px"> </video>
src:視頻的URL
poster:視頻封面,沒有播放時(shí)顯示的圖片
preload:預(yù)加載
autoplay:自動(dòng)播放
loop:循環(huán)播放
controls:瀏覽器自帶的控制條
width:視頻寬度
height:視頻高度
muted:是否輸出視頻的聲音
獲取HTMLVideoElement和HTMLAudioElement對(duì)象
//audio可以直接通過new創(chuàng)建對(duì)象
Media = new Audio("http://www.abc.com/test.mp3");
//audio和video都可以通過標(biāo)簽獲取對(duì)象
Media = document.getElementById("media");
Media方法和屬性——HTMLVideoElement 和 HTMLAudioElement 均繼承自 HTMLMediaElement
//錯(cuò)誤狀態(tài)
Media.error; //null:正常
Media.error.code; //1.用戶終止 2.網(wǎng)絡(luò)錯(cuò)誤 3.解碼錯(cuò)誤 4.URL無效
//網(wǎng)絡(luò)狀態(tài)
Media.currentSrc; //返回當(dāng)前資源的URL
Media.src = value; //返回或設(shè)置當(dāng)前資源的URL
Media.canPlayType(type); //是否能播放某種格式的資源
Media.networkState; //0.此元素未初始化 1.正常但沒有使用網(wǎng)絡(luò) 2.正在下載數(shù)據(jù) 3.沒有找到資源
Media.load(); //重新加載src指定的資源
Media.buffered; //返回已緩沖區(qū)域,TimeRanges
Media.preload; //none:不預(yù)載 metadata:預(yù)載資源信息 auto:
//準(zhǔn)備狀態(tài)
Media.readyState; //1:HAVE_NOTHING 2:HAVE_METADATA 3.HAVE_CURRENT_DATA 4.HAVE_FUTURE_DATA 5.HAVE_ENOUGH_DATA
Media.seeking; //是否正在seeking
//回放狀態(tài)
Media.currentTime = value; //當(dāng)前播放的位置,賦值可改變位置
Media.startTime; //一般為0,如果為流媒體或者不從0開始的資源,則不為0
Media.duration; //當(dāng)前資源長度 流返回?zé)o限
Media.paused; //是否暫停
Media.defaultPlaybackRate = value;//默認(rèn)的回放速度,可以設(shè)置
Media.playbackRate = value;//當(dāng)前播放速度,設(shè)置后馬上改變
Media.played; //返回已經(jīng)播放的區(qū)域,TimeRanges,關(guān)于此對(duì)象見下文
Media.seekable; //返回可以seek的區(qū)域 TimeRanges
Media.ended; //是否結(jié)束
Media.autoPlay; //是否自動(dòng)播放
Media.loop; //是否循環(huán)播放
Media.play(); //播放
Media.pause(); //暫停//控制
Media.controls;//是否有默認(rèn)控制條
Media.volume = value; //音量
Media.muted = value; //靜音
//TimeRanges(區(qū)域)對(duì)象
TimeRanges.length; //區(qū)域段數(shù)
TimeRanges.start(index) //第index段區(qū)域的開始位置
TimeRanges.end(index) //第index段區(qū)域的結(jié)束位置
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 | eventTester = function (e){ Media.addEventListener(e, function (){ console.log((newDate()).getTime(),e); }); } eventTester( "loadstart" ); //客戶端開始請(qǐng)求數(shù)據(jù) eventTester( "progress" ); //客戶端正在請(qǐng)求數(shù)據(jù) eventTester( "suspend" ); //延遲下載 eventTester( "abort" ); //客戶端主動(dòng)終止下載(不是因?yàn)殄e(cuò)誤引起) eventTester( "error" ); //請(qǐng)求數(shù)據(jù)時(shí)遇到錯(cuò)誤 eventTester( "stalled" ); //網(wǎng)速失速 eventTester( "play" ); //play()和autoplay開始播放時(shí)觸發(fā) eventTester( "pause" ); //pause()觸發(fā) eventTester( "loadedmetadata" ); //成功獲取資源長度 eventTester( "loadeddata" ); // eventTester( "waiting" ); //等待數(shù)據(jù),并非錯(cuò)誤 eventTester( "playing" ); //開始回放 eventTester( "canplay" ); //可以播放,但中途可能因?yàn)榧虞d而暫停 eventTester( "canplaythrough" ); //可以播放,歌曲全部加載完畢 eventTester( "seeking" ); //尋找中 eventTester( "seeked" ); //尋找完畢 eventTester( "timeupdate" ); //播放時(shí)間改變 eventTester( "ended" ); //播放結(jié)束 eventTester( "ratechange" ); //播放速率改變 eventTester( "durationchange" ); //資源長度改變 eventTester( "volumechange" ); //音量改變 |
事件詳細(xì)說明:
Audio
Firefox:支持 Ogg Vorbis和WAV
Opera :支持Ogg Vorbis和WAV
Safari :支持MP3,AAC格式 ,和MP4
Chrome :支持Ogg Vorbis,MP3,WAV,AAC和MP4
Internet Explorer 9+ :支持MP3,AAC格式 ,和MP4
IOS :支持MP3,AAC格式 ,和MP4
Android :支持AAC和MP3
為了最大程度支持所有上面提到的瀏覽器,建議開發(fā)者使用Ogg Vorbis和MP3這兩種格式例如。
1 2 3 4 | < audio controls> < source src = "myAudio.ogg" type = "audio/ogg" > < source src = "myAudio.mp3" type = "audio/mp3" > </ audio > |
Video
Firefox :支持Ogg Theora格式和WEBM
Opera :支持Ogg Theora格式和WEBM
Safari :支持MP4
Chrome :支持Ogg Theora格式,MP4和WEBM
Internet Explorer 9 :支持MP4和WEBM(需要安裝插件)
IOS :支持MP4
Android :支持MP4和WEBM(Android 2.3版本以上)
為了支持上述所有的瀏覽器,建議使用WebM和MP4視頻文件作為source元素。例如。
1 2 3 4 | < video controls> < source src = "myVideo.mp4" type = "video/mp4" > < source src = "myVideo.webm" type = "video/webm" > </ video > |
再來張截圖示意:(http://en.wikipedia.org/wiki/Html_video_tag)
Chrome瀏覽器支持HTML5,它支持原生播放部分的MP4格式(不用通過Flash等插件)。
為什么是部分MP4呢?MP4有非常復(fù)雜的含義(見http://en.wikipedia.org/wiki/Mp4),普通人對(duì)MP4的理解是后綴為.mp4的文件。但MP4本身不是一種簡(jiǎn)單的視頻格式,它是一個(gè)包裝了視頻和音頻格式的殼。至于里面的視頻和音頻使用什么編碼格式是可變的。MP4的視頻格式可以使用DivX也可使用H264,Chrome只支持H264。
然后,我猜測(cè)問題的原因是這樣的:Chrome瀏覽器見到MP4后綴的文件,使用了原生HTML5視頻播放起播放,但卻發(fā)現(xiàn)視頻格式無法解碼。對(duì)于Firefox,它不支持原生播放MP4,于是使用了Flash,絕大部分的視頻格式基本都可通過Flash播放。
這篇2011年1月的消息提到Google將放棄對(duì)H264的支持:http://www.infoq.com/cn/news/2011/01/chrome-h264。這篇是Google方面的描述:http://blog.chromium.org/2011/01/html-video-codec-support-in-chrome.html。如果Google不再支持在Chrome上原生播放MP4,那么會(huì)調(diào)用Flash播放器播放,這樣反而不會(huì)出現(xiàn)有些MP4文件播放不了的問題。
為什么Chrome不支持所有的視頻編碼格式?絕大部份的視頻編碼格式都是要付版權(quán)費(fèi)的,Google已經(jīng)為H264買了單,F(xiàn)irefox沒有Google那么有錢不愿意買。
最后,我錄制了一段教學(xué)視頻,指導(dǎo)大家怎樣把各種視頻轉(zhuǎn)換成兼容性比較好的MP4文件。視頻中使用的軟件是“格式工廠”(http://www.formatoz.com/CN/index.html),這個(gè)軟件基本上只是做了一個(gè)界面,其核心調(diào)用了開源軟件FFMPEG。由于它違反了FFMPEG的LGPL許可協(xié)議,備受指責(zé)。使用Linux的朋友可以直接使用FFMPEG命令進(jìn)行視頻格式轉(zhuǎn)換,命令如下:
ffmpeg -i infile.flv -vcodec libx264 o5.mp4
如果轉(zhuǎn)換出的視頻在某些設(shè)備還是無法播放,可以試試?yán)肕ediaCoder轉(zhuǎn)換兼容性更好的MP4
即使對(duì)瀏覽器來說,已經(jīng)設(shè)置了正確的媒體,但有可能是您的服務(wù)器并不能正確識(shí)別多媒體的MIME類型。MIME類型告訴服務(wù)器如何處理不同的文件類型。如果你使用Apache,則可以在.htaccess文件中添加下面的音頻支持:
AddType audio/ogg ogg AddType audio/ogg oga AddType audio/wav wav AddType audio/mpeg mp3 AddType audio/mp4 mp4 AddType audio/mp4 mpa
類似地添加如下代碼,以支持視頻:
AddType video/webm webm AddType video/mp4 mp4 AddType video/ogg ogg AddType video/ogg ogv
如果不能訪問服務(wù)器的.htaccess文件,則有可能在服務(wù)器的控制面板地方有一個(gè)選項(xiàng),允許查看和添加MIME類型。
如果是Windows服務(wù)器,那么可能需要在IIS或者web.config中進(jìn)行設(shè)置在web.config文件中 。
一種很常見的情況是,用戶從客戶端提交給服務(wù)端一個(gè)類型的媒體文件,并且盡管你已經(jīng)從它的文件擴(kuò)展名中確認(rèn)了其MIME類型。但是,該文件沒有被正確解碼。例如,它可以是一個(gè)完全有效的MP4文件,但由于某種原因,在一些瀏覽器中無法播放。如果發(fā)生這種情況,最好把用戶上傳的文件進(jìn)行編碼,比如使用如Miro Video Coverter和Media Converter等編碼器,可以確保正確的編碼。
此外,一些文件,尤其是MP4文件,在測(cè)試時(shí),不要總是在一個(gè)支持其格式的瀏覽器中進(jìn)行測(cè)試,這是因?yàn)槭聦?shí)上,MP4存在不同的編碼格式,可以根據(jù)不同格式對(duì)MP4(又稱如H.264)進(jìn)行編碼(參考:http://en.wikipedia.org/wiki/H.264#Profiles)如果有的瀏覽器不支持其中的編碼格式,那么它自然不會(huì)工作。如果遇到這種情況,嘗試確保該文件是以最基本的MP4編碼方式進(jìn)行編碼。最好建議使用工具,比如Miro轉(zhuǎn)換工具,它能確保MP4文件能在最多的瀏覽器中得到支持。
如果需要支持Firefox 3.6和更低的版本,還需要轉(zhuǎn)換對(duì)應(yīng)的音頻文件為Ogg格式},并將它們添加到中的元素中。
一般情況下,HTML5的的音頻和視頻播放器將允許用戶在完整下載文件前,就可以開始進(jìn)行播放了,有時(shí)候,對(duì)于MP4文件來說卻不能這樣,要必須等待所有的視頻下載完畢再播放,這主要是編碼問題造成的
有時(shí),MP4文件使用索引進(jìn)行了編碼(其中包含了比如文件長度等信息),往往這些信息是放在文件的尾部而不是頭部。索引信息中,包含了文件的元信息,瀏覽器根據(jù)這些元信息去進(jìn)行下載。如果索引放在后面的話,則必須等待到獲得整個(gè)文件的索引后,才能知道文件的元信息,所以就必須等到整個(gè)文件下載完畢才能開始播放了。
如果您遇到這種情況,還有一個(gè)簡(jiǎn)單的修補(bǔ)程序,是由埃里克森Renaun提供的,下載地址為:http://renaun.com/blog/code/qtindexswapper/,下載到計(jì)算機(jī)上運(yùn)行,則可以把文件的索引信息移動(dòng)到文件頭并保存。
這個(gè)問題看上去好像有點(diǎn)多余,但每次在Stack Overflow中,都會(huì)看到很多開發(fā)者發(fā)問,比如為什么某個(gè)方法不能運(yùn)行,原因在于他們使用了不存在的屬性。比如,在
<audio>和<video>標(biāo)簽中都有的舊的屬性autobuffer,在2010年10月已經(jīng)被preload取代了。
人們似乎忘記了,HTML5是尚未敲定的標(biāo)準(zhǔn)(雖然它的大部分內(nèi)容現(xiàn)在已經(jīng)都相當(dāng)穩(wěn)定),所以作為開發(fā)者,必須多到W3C的官方網(wǎng)站去進(jìn)行查閱相關(guān)資料。
最近相信不少開發(fā)者會(huì)發(fā)現(xiàn)音量控制的操作在Firefox 11及以上的版本中被取消了。是的,靜音和音量控制仍然是可以使用的,但要通過鍵盤上的上和向下鍵進(jìn)行控制,其原因主要是發(fā)現(xiàn)了兩個(gè)bug(請(qǐng)參考:http://www.iandevlin.com/blog/2012/04/html5/html5-media-controls-and-firefox),這一點(diǎn)請(qǐng)開發(fā)者注意,估計(jì)firefox會(huì)很快修復(fù)這個(gè)問題。
HTML5的音頻和視頻點(diǎn)的最大賣點(diǎn)之一就是不需要安裝第三方插件-例如Flash
不幸的是,這不完全正確,ie 9及以上版本的瀏覽器和Safari是需要使用Microsoft Media Player和Apple的QuickTime,才能播放HTML5音頻和視頻。
HTML5 視頻的其中一大威力在于其全屏播放的特性但HTML5 規(guī)范中,對(duì)這個(gè)居然沒有任何提及,相反,在另外一個(gè)關(guān)于全屏幕播放的API中有定義,但還是在草稿階段,在一些瀏覽器中開始有試驗(yàn)性的支持。
以下瀏覽器去一些支持全屏API,但具體使用的api方法各自有不同:
Chrome 19 版本以上
Firefox的12 +
Safari瀏覽器5.1 +
注:iPhone上,video自動(dòng)全屏播放!
也有一些其他方法,能在其他瀏覽器中支持使用全屏API,比如https://github.com/sindresorhus/screenfull.js
Internet Explorer9 以上版本忽略了video poster屬性
如果在HTML 5的video標(biāo)簽中使用poster屬性,其含義為在視頻播放前提供一張靜態(tài)的圖片給用戶,但ie 9以上的版本,除非設(shè)置了preload屬性為none,否則將會(huì)忽略掉設(shè)置的poster屬性。
這是由于Internet Explorer是最遲支持HTML 5的瀏覽器,我們都習(xí)慣了其他瀏覽器中,如果設(shè)置了poster屬性,則會(huì)在播放視頻前,先顯示設(shè)置的這張圖片。但I(xiàn)E 9并不這樣做,如果要播放的視頻的第一幀已經(jīng)加載了,則不會(huì)顯示有poster屬性指定的圖片了,而且在IE 10中,目前依然存在這個(gè)問題。
HTML 5的起草者們,一直都希望HTML 5能訪問攝像頭和麥克風(fēng),因此早期是使用標(biāo)簽的,但現(xiàn)在是被getUserMedia API所取代了(詳見: http://dev.w3.org/2011/webrtc/editor/getusermedia.html)。
API本身是容易使用的 ,但目前瀏覽器支持相當(dāng)有限。Opera是目前唯一個(gè)實(shí)現(xiàn)這些功能的瀏覽器,但只支持視頻Internet Explorer 10也將對(duì)其進(jìn)行部分支持,Firefox也會(huì)跟隨。
通過iframe
1 2 3 4 5 6 7 8 | var ifr=document.createElement( "iframe" ); ifr.setAttribute( 'src' , "song.mp3" ); ifr.setAttribute( 'width' , '1px' ); ifr.setAttribute( 'height' , '1px' ); ifr.setAttribute( 'scrolling' , 'no' ); ifr.style.border= "0px" ; document.body.appendChild(ifr); |
通過頁面上的其他觸摸或者點(diǎn)擊事件來調(diào)用對(duì)應(yīng)的play()方法
HTML
<video id="player" width="480" height="320" webkit-playsinline>
Obj-C
webview.allowsInlineMediaPlayback = YES;
在網(wǎng)上看到有人用JS寫的播放器,木有仔細(xì)看,先貼過來。感覺讓我自己寫想不到這么周全,等后面要用再仔細(xì)尋更好方案。
原文地址:http://www.cnblogs.com/arby/archive/2012/04/07/2436352.html
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 | function Audio(song, playType, dom){ /* * 播放器構(gòu)造函數(shù)。 * dom:為audio元素,可以不傳。 * song : 為歌曲列表,只支持?jǐn)?shù)組形式,格式為[{}{}] * playType 為播放方式: 1 順序播放 2 隨機(jī)播放 3 單曲循環(huán) 4 全部循環(huán) */ if (!dom) { this .media = document.createElement( 'audio' ); document.body.appendChild( this .media); } else { this .media = typeof dom == 'string' document.getElementById(dom) : dom; } this .currentIndex = 0; this .songList = song; this .countTotal = this .songList.length; this .playType = playType || 1; this .MusicInfo = []; this .playing = false ; } /* * 播放器啟動(dòng)主函數(shù) */ Audio.prototype.startPlay = function (){ this .media.src = this .songList[ this .currentIndex].src; this ._play(); } /* * 播放器播放核心函數(shù). */ Audio.prototype._play = function (){ var self = this ; this .media.play(); this .playing = true ; this .mediaEvent( 'ended' ,callback); function callback(){ //單曲循環(huán)無需單獨(dú)處理,只需直接調(diào)用startPlay()函數(shù)。 if (self.media.currentTime == self.media.duration){ switch (self.playType){ case 1: if (self.currentIndex == self.countTotal-1){ return false ; } else { self.currentIndex++; } break ; case 2: self.currentIndex = Math.floor(Math.random()*self.countTotal); break ; case 4: self.currentIndex++; console.log( "self.currentIndex==" ,self.currentIndex); self.currentIndex = (self.currentIndex > self.countTotal-1) ? 0 : self.currentIndex; break ; } self.startPlay(); } } } /* *播放下一首如果當(dāng)前已經(jīng)是最后一首則播放第一首 */ Audio.prototype.playNext = function (){ this .currentIndex++; this .currentIndex = this .currentIndex > this .countTotal-1 ? 0 : this .currentIndex; this .startPlay(); } /* *播放上一首如果當(dāng)前已經(jīng)是第一首則播放最后一首 */ Audio.prototype.playPrevious = function (){ this .currentIndex++; this .currentIndex = this .currentIndex < 0 ? this .countTotal-1 : this .currentIndex; this .startPlay(); } /* * 暫停當(dāng)前播放,如果傳回調(diào)函數(shù),則暫停后執(zhí)行回調(diào)。 */ Audio.prototype.playPause = function (callback){ if ( this .playing){ this .media.pause(); this .playing = false ; } else { this .media.play(); this .playing = true ; } if (!callbakc){callback();} } /* * 獲取當(dāng)前播放位置 */ Audio.prototype.getCurrentTime = function (){ return this .media.currentTime; } /* * 播放器各種事件監(jiān)聽. * tip 類型必須是正確的類型 */ Audio.prototype.mediaEvent = function (eventType, callback){ Event.add( this .media,eventType,callback); } /* * 播放用戶自定義時(shí)間,即拖動(dòng)進(jìn)度條。 */ Audio.prototype.playUserTime = function (time){ this .media.currentTime = time; } /* * 獲取當(dāng)前媒體信息 * src 當(dāng)前媒體路徑 * size 當(dāng)前媒體總時(shí)長. */ Audio.prototype.getMusicInfo = function (){ this .MusicInfo.src = this .media.currentSrc; this .MusicInfo.size = this .media.duration; this .MusicInfo.name = this .songList[ this .currentIndex].name; return this .MusicInfo; } /* * 設(shè)置或者獲取當(dāng)前音量 * voluems的值需大于0 小于等于 1 */ Audio.prototype.setVolume = function (volumes){ if (volumes) { this .media.volume = volumes; } else { return this .media.volume; } } /* * 設(shè)置或者取消靜音. * flag的值為true是靜音,false時(shí)正常 */ Audio.prototype.muted = function (flag){ if (flag){ this .media.muted = 1; } else { this .media.muted = 0; } } /* * 向播放列表添加新歌曲 * song為所需要添加的歌曲,可以多首,格式如構(gòu)造函數(shù)中song. */ Audio.prototype.addSongToList = function (song){ this .songList.push(song); this .countTotal = this .songList.length; } Audio.prototype.getBuffered = function (){ return this .media.buffered; } /*全局事件監(jiān)聽封裝函數(shù)*/ var Event = { add : function (node, eventType, callback){ var node = typeof node == 'string' document.getElementById(node) : node; if (document.addEventListener){ node.addEventListener(eventType, callback, false ); } else { node.attachEvent( 'on' + eventType, callback); } }, remove : function (node, eventType, callback){ var node = typeof node == 'string' document.getElementById(node) : node; if (document.removeEventListener){ node.removeEventListener(eventType, callback, false ); } else { node.detachEvent( 'on' + eventType, callback); } } } var core = { formatPlayTime : function (tempTime){ var temp = tempTime.toString().split( "." )[0]; if (tempTime<=60){ temp = temp>=10? temp : "0" +temp; return "00 : " + temp; } else { var minute =Math.floor(temp/60); minute = (minute >= 10)? minute : "0" + minute; var second = temp%60; second = (second >= 10)? second : "0" +second; return minute + " : " + second; } } } |
聯(lián)系客服