ybplayer.js 68 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668
  1. (function() {
  2. 'use strict'
  3. function YBPlayer ({container, src, title, poster, formats, barrages, barrageShow, barrageGap, barrageConfig, controls, playShow=true, progressShow=true, timeShow = true, volumeShow=true, settingShow=true, fullscreenShow=true, autoplay, mirror, pictureInPicture, nextBtnShow, prevBtnShow, muted, loop, preload, settings, initialTime, duration, volume, playbackRate, objectFit, crossOrigin, segments, isLive, flvConfig, enableBlob }){
  4. if(!(this instanceof YBPlayer)){ //如果this不是指向MyClass
  5. throw new TypeError("TypeError: Class constructor YBPlayer cannot be invoked without 'new'")
  6. }
  7. this.container = typeof container == 'string' ? document.getElementById(container) : container
  8. this.src = src || ''
  9. this.title = title || ''
  10. this.poster = poster || ''
  11. this.formats = formats || 'auto'
  12. this.barrages = barrages
  13. this.barrageShow = barrageShow
  14. this.barrageGap = barrageGap || 5
  15. this.barrageConfig = barrageConfig
  16. this.controls = controls
  17. this.playShow = playShow
  18. this.progressShow = progressShow
  19. this.timeShow = timeShow
  20. this.volumeShow = volumeShow
  21. this.settingShow = settingShow
  22. this.fullscreenShow = fullscreenShow
  23. this.autoplay = autoplay
  24. this.mirror = mirror
  25. this.pictureInPicture = pictureInPicture
  26. this.nextBtnShow = nextBtnShow
  27. this.prevBtnShow = prevBtnShow
  28. this.muted = muted
  29. this.loop = loop
  30. this.preload = preload || 'auto'
  31. this.settings = settings || 'all'
  32. this.initialTime = initialTime || 0
  33. this.duration = duration || 0
  34. this.volume = volume || 1
  35. this.playbackRate = playbackRate || 1
  36. this.objectFit = objectFit || 'contain'
  37. this.crossOrigin = crossOrigin || ''
  38. this.segments = segments
  39. this.isLive = isLive
  40. this.flvConfig = flvConfig || {}
  41. this.enableBlob = enableBlob
  42. this.video = null
  43. this.hls = null
  44. this.flv = null
  45. this.barrage = null
  46. this._eventCallback = {}
  47. this._wrapperEl = null
  48. this._videoEl = null
  49. this._posterEl = null
  50. this._videoBackground = 'inherit'
  51. this._headersEl = null
  52. this._controlsEl = null
  53. this._barrageEl = null
  54. this._settingEl = null
  55. this._playbackRateEl = null
  56. this._slotsEl = null
  57. this._controlSlotsEl = null
  58. this._isDrag = false
  59. this._controlsTimer = null
  60. this._seizingTimer = null
  61. this._init()
  62. }
  63. Object.defineProperty(YBPlayer.prototype,'_init',{
  64. value:function(){
  65. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  66. throw new TypeError("TypeError: YBPlayer._init is not a constructor")
  67. }
  68. if ( this.container && typeof this.container != 'undefined' ) {
  69. try{
  70. this.container.style.position = 'relative';
  71. this.container.style.overflow = 'hidden';
  72. //监听全屏事件
  73. this.container.addEventListener('fullscreenerror', this._fullscreenerror.bind(this));
  74. this.container.addEventListener('mozfullscreenerror', this._fullscreenerror.bind(this));
  75. this.container.addEventListener('msfullscreenerror', this._fullscreenerror.bind(this));
  76. this.container.addEventListener('webkitfullscreenerror', this._fullscreenerror.bind(this));
  77. this.container.addEventListener('fullscreenchange', this._fullscreenchanged.bind(this));
  78. this.container.addEventListener('mozfullscreenchange', this._fullscreenchanged.bind(this));
  79. this.container.addEventListener('msfullscreenchange', this._fullscreenchanged.bind(this));
  80. this.container.addEventListener('webkitfullscreenchange', this._fullscreenchanged.bind(this));
  81. this._wrapperEl = document.createElement('DIV')
  82. this._wrapperEl.setAttribute('class', 'ybplayer-video-wrapper')
  83. this.container.appendChild(this._wrapperEl)
  84. this._wrapperEl.onclick = () => {
  85. if ( this._playbackRateEl ) {
  86. this._hidePlaybackRate()
  87. } else if ( this._settingEl ) {
  88. this._hideSetting()
  89. } else if ( this._controlsEl ) {
  90. if ( this._controlsEl.classList.value.indexOf('ybplayer-controls-show') > -1 ) {
  91. this._hideControls()
  92. } else {
  93. this._showControls()
  94. }
  95. }
  96. }
  97. this._initVideo();
  98. this._initSlots();
  99. this._setVideoUrl();
  100. if ( this.controls ) this._initControls();
  101. }catch(e){
  102. throw new Error(e.toString());
  103. }
  104. }
  105. },
  106. enumerable:false
  107. })
  108. Object.defineProperty(YBPlayer.prototype,'_destroy',{
  109. value:function(destroyContainer = true){
  110. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  111. throw new TypeError("TypeError: YBPlayer._destroy is not a constructor")
  112. }
  113. this._destroyHls()
  114. this._destroyFlv();
  115. this._destroyControls();
  116. this._destroyHeaders();
  117. this._destroyBarrage();
  118. this._destroyVideo();
  119. this._destroySlots();
  120. if ( this._wrapperEl ) {
  121. this._wrapperEl.onclick = null;
  122. this._wrapperEl.remove();
  123. this._wrapperEl = null;
  124. }
  125. if ( this.container && destroyContainer ) {
  126. this.container.removeEventListener('fullscreenerror', this._fullscreenerror.bind(this));
  127. this.container.removeEventListener('mozfullscreenerror', this._fullscreenerror.bind(this));
  128. this.container.removeEventListener('msfullscreenerror', this._fullscreenerror.bind(this));
  129. this.container.removeEventListener('webkitfullscreenerror', this._fullscreenerror.bind(this));
  130. this.container.removeEventListener('fullscreenchange', this._fullscreenchanged.bind(this));
  131. this.container.removeEventListener('mozfullscreenchange', this._fullscreenchanged.bind(this));
  132. this.container.removeEventListener('msfullscreenchange', this._fullscreenchanged.bind(this));
  133. this.container.removeEventListener('webkitfullscreenchange', this._fullscreenchanged.bind(this));
  134. this.container = null;
  135. }
  136. },
  137. enumerable:false
  138. })
  139. Object.defineProperty(YBPlayer.prototype,'_initVideo',{
  140. value:function(){
  141. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  142. throw new TypeError("TypeError: YBPlayer._initVideo is not a constructor")
  143. }
  144. this._videoEl = document.createElement('DIV');
  145. this._videoEl.setAttribute('class', 'ybplayer-video-content');
  146. this._wrapperEl.appendChild(this._videoEl);
  147. this.video = document.createElement('VIDEO');
  148. this.video.setAttribute('style', 'width: 100%;height:100%;flex:1;opacity:0;object-fit:' + this.objectFit + ';');
  149. this.video.setAttribute('preload', this.preload);
  150. this.video.setAttribute('volume', this.volume);
  151. this.video.setAttribute('x-webkit-airplay', 'allow');
  152. this.video.setAttribute('webkit-playsinline', true);
  153. this.video.setAttribute('playsinline', true);
  154. this.video.setAttribute('x5-video-player-type', 'h5');
  155. this.video.setAttribute('x5-video-play', true);
  156. this.crossOrigin && this.video.setAttribute('crossOrigin', this.crossOrigin);
  157. this.video.innerHTML = '您的浏览器不支持 video 标签。';
  158. this._videoEl.appendChild(this.video);
  159. this._showPoster()
  160. this.video.muted = this.muted;
  161. this.video.defaultMuted = this.muted;
  162. this.video.playbackRate = this.playbackRate;
  163. this.video.defaultPlaybackRate = this.playbackRate;
  164. this.video.autoplay = this.autoplay;
  165. this.video.loop = this.loop;
  166. this.video.oncanplay = () => {
  167. this._eventCallback.canplay && this._eventCallback.canplay({
  168. duration: this.video.duration,
  169. width: this.video.videoWidth,//视频宽度
  170. height: this.video.videoHeight//视频高度
  171. });
  172. }
  173. this.video.oncanplaythrough = () => {
  174. this._eventCallback.canplaythrough && this._eventCallback.canplaythrough({
  175. duration: this.video.duration,
  176. width: this.video.videoWidth,//视频宽度
  177. height: this.video.videoHeight//视频高度
  178. });
  179. }
  180. this.video.onloadeddata = () => {
  181. this._eventCallback.loadeddata && this._eventCallback.loadeddata({
  182. duration: this.video.duration,
  183. width: this.video.videoWidth,//视频宽度
  184. height: this.video.videoHeight//视频高度
  185. });
  186. this.video.currentTime = this.initialTime;
  187. this.video.style.opacity = 1
  188. }
  189. this.video.onloadedmetadata = () => {
  190. this._eventCallback.loadedmetadata && this._eventCallback.loadedmetadata({
  191. duration: this.video.duration,
  192. width: this.video.videoWidth,//视频宽度
  193. height: this.video.videoHeight//视频高度
  194. });
  195. if ( this.barrageShow ) this._initBarrage();
  196. }
  197. this.video.onloadstart = () => {
  198. this._eventCallback.loadstart && this._eventCallback.loadstart();
  199. }
  200. this.video.onplay = () => {
  201. this._hidePoster()
  202. this._eventCallback.play && this._eventCallback.play()
  203. this.barrage && this.barrage.play();
  204. this._setControlsView('play')
  205. if ( this.duration && this.video.currentTime >= this.duration && !this.isLive ) this.seek(0)
  206. if ( this.flv ) this.flv.play()
  207. }
  208. this.video.onpause = () => {
  209. this._eventCallback.pause && this._eventCallback.pause();
  210. this.barrage && this.barrage.pause();
  211. this._setControlsView('play')
  212. if ( this.flv ) this.flv.pause()
  213. }
  214. this.video.onended = () => {
  215. this._eventCallback.ended && this._eventCallback.ended();
  216. }
  217. this.video.onseeking = () => {
  218. this._eventCallback.seeking && this._eventCallback.seeking({
  219. currentTime: this.video.currentTime
  220. });
  221. }
  222. this.video.onseeked = () => {
  223. this._eventCallback.seeked && this._eventCallback.seeked({
  224. currentTime: this.video.currentTime
  225. });
  226. this.barrage && this.barrage.seek(this.video.currentTime);
  227. }
  228. this.video.ontimeupdate = () => {
  229. this._eventCallback.timeupdate && this._eventCallback.timeupdate({
  230. currentTime: this.video.currentTime
  231. })
  232. if ( this.duration && this.video.currentTime >= this.duration && !this.isLive ) {
  233. if ( this.loop ) {
  234. this.seek(0)
  235. } else {
  236. this.pause();
  237. this._eventCallback.ended && this._eventCallback.ended();
  238. }
  239. }
  240. if ( this._seizingTimer ) {
  241. window.clearTimeout(this._seizingTimer)
  242. this._seizingTimer = null
  243. }
  244. this._seizingTimer = window.setTimeout(() => {
  245. if ( this.video && this.video.src && !this.video.paused ) this._eventCallback.seizing && this._eventCallback.seizing()
  246. }, 5000)
  247. this._setControlsView('timeUpdate')
  248. }
  249. this.video.ondurationchange = () => {
  250. this._eventCallback.durationchange && this._eventCallback.durationchange({
  251. duration: this.video.duration
  252. })
  253. }
  254. this.video.onwaiting = () => {
  255. this._eventCallback.waiting && this._eventCallback.waiting({
  256. currentTime: this.video.currentTime
  257. });
  258. this.barrage && this.barrage.pause();
  259. }
  260. this.video.onplaying = () => {
  261. this._eventCallback.playing && this._eventCallback.playing({
  262. currentTime: this.video.currentTime
  263. })
  264. this.barrage && this.barrage.play();
  265. }
  266. this.video.onprogress = () => {
  267. this._eventCallback.progress && this._eventCallback.progress({
  268. buffered: this.video.buffered
  269. })
  270. }
  271. this.video.onabort = () => {
  272. this._eventCallback.abort && this._eventCallback.abort();
  273. }
  274. this.video.onerror = (e) => {
  275. this._eventCallback.error && this._eventCallback.error(this._deepClone(e));
  276. }
  277. this.video.onvolumechange = () => {
  278. this._eventCallback.volumechange && this._eventCallback.volumechange({
  279. volume: this.video.volume
  280. });
  281. this._setControlsView('volume')
  282. }
  283. this.video.onratechange = () => {
  284. this._eventCallback.ratechange && this._eventCallback.ratechange({
  285. playbackRate: this.video.playbackRate
  286. });
  287. if ( this._playbackRateEl && this._querySelector('ybplayer-setting') ) {
  288. for ( let i = 0; i < this._querySelectorAll('ybplayer-setting').length; i++ ) {
  289. this._querySelectorAll('ybplayer-setting')[i].getElementsByClassName('ybplayer-setting-text')[0].style.color = this.playbackRate == this._querySelectorAll('ybplayer-setting')[i].getAttribute('data-rate') ? '#2ca2f9' : '#333';
  290. }
  291. }
  292. this.barrage && this.barrage.setConfig({
  293. playbackRate: this.video.playbackRate
  294. });
  295. }
  296. this.video.onenterpictureinpicture = () => {
  297. this._eventCallback.enterpictureinpicture && this._eventCallback.enterpictureinpicture()
  298. this.pictureInPicture = true
  299. this._setSettingView('pictureInPicture');
  300. }
  301. this.video.onleavepictureinpicture = () => {
  302. this._eventCallback.leavepictureinpicture && this._eventCallback.leavepictureinpicture()
  303. this.pictureInPicture = false
  304. this._setSettingView('pictureInPicture');
  305. }
  306. this._barrageEl = document.createElement('DIV');
  307. this._barrageEl.setAttribute('class', 'ybplayer-video-barrage');
  308. this._barrageEl.setAttribute('style', 'margin:' + this.barrageGap + 'px 0;');
  309. this._wrapperEl.appendChild(this._barrageEl);
  310. },
  311. enumerable:false
  312. })
  313. Object.defineProperty(YBPlayer.prototype,'_destroyVideo',{
  314. value:function(){
  315. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  316. throw new TypeError("TypeError: YBPlayer._destroyVideo is not a constructor")
  317. }
  318. if ( this.video ) {
  319. this.video.pause();
  320. this.video.src = '';
  321. this.video.oncanplay = null;
  322. this.video.onloadedmetadata = null;
  323. this.video.onplay = null;
  324. this.video.onpause = null;
  325. this.video.onended = null;
  326. this.video.onseeking = null;
  327. this.video.onseeked = null;
  328. this.video.ontimeupdate = null;
  329. this.video.ondurationchange = null;
  330. this.video.onwaiting = null;
  331. this.video.onplaying = null;
  332. this.video.onprogress = null;
  333. this.video.onabort = null;
  334. this.video.onerror = null;
  335. this.video.onvolumechange = null;
  336. this.video.onratechange = null;
  337. this.video.onenterpictureinpicture = null;
  338. this.video.onleavepictureinpicture = null;
  339. this.video.remove();
  340. this.video = null;
  341. }
  342. this._hidePoster()
  343. if ( this._videoEl ) {
  344. this._videoEl.remove();
  345. this._videoEl = null;
  346. }
  347. if ( this._barrageEl ) {
  348. this._barrageEl.remove();
  349. this._barrageEl = null;
  350. }
  351. if ( this._seizingTimer ) {
  352. window.clearTimeout(this._seizingTimer)
  353. this._seizingTimer = null
  354. }
  355. },
  356. enumerable:false
  357. })
  358. Object.defineProperty(YBPlayer.prototype,'_showPoster',{
  359. value:function(){
  360. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  361. throw new TypeError("TypeError: YBPlayer._showPoster is not a constructor")
  362. }
  363. if ( this._videoEl && this.poster && this.video.paused ) {
  364. let img = new Image();
  365. img.onload = () => {
  366. if ( this.video.paused ) {
  367. this._posterEl = document.createElement('DIV');
  368. this._posterEl.setAttribute('class', 'ybplayer-video-poster');
  369. this._posterEl.setAttribute('style', `background-size: ${this.objectFit};background-image: url(${this.poster})`);
  370. this._videoEl.appendChild(this._posterEl);
  371. }
  372. img = null
  373. }
  374. img.onerror = () => {
  375. img = null
  376. }
  377. img.src = this.poster;
  378. }
  379. },
  380. enumerable:false
  381. })
  382. Object.defineProperty(YBPlayer.prototype,'_hidePoster',{
  383. value:function(){
  384. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  385. throw new TypeError("TypeError: YBPlayer._hidePoster is not a constructor")
  386. }
  387. if ( this._posterEl ) {
  388. this._posterEl.onerror = null
  389. this._posterEl.onload = null
  390. this._posterEl.remove()
  391. this._posterEl = null
  392. }
  393. },
  394. enumerable:false
  395. })
  396. Object.defineProperty(YBPlayer.prototype,'_initHeaders',{
  397. value:function(){
  398. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  399. throw new TypeError("TypeError: YBPlayer._initHeaders is not a constructor")
  400. }
  401. if ( this.container && this.title ) {
  402. this._destroyHeaders()
  403. this._headersEl = document.createElement('DIV');
  404. this._headersEl.setAttribute('class', 'ybplayer-headers');
  405. this._headersEl.innerHTML = `
  406. <div class="ybplayer-headers-shadow"></div>
  407. <i class="ybplayerIconfont icon-angle-arrow-left ybplayer-icon ${this._setClassName('ybplayer-icon-back')}"></i>
  408. <span class="${this._setClassName('ybplayer-headers-title')}">${this.title}</span>
  409. `;
  410. this.container.appendChild(this._headersEl);
  411. this._querySelector('ybplayer-icon-back').onclick = () => {
  412. this.exitFullscreen()
  413. }
  414. }
  415. },
  416. enumerable:false
  417. })
  418. Object.defineProperty(YBPlayer.prototype,'_destroyHeaders',{
  419. value:function(){
  420. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  421. throw new TypeError("TypeError: YBPlayer._destroyHeaders is not a constructor")
  422. }
  423. if ( this._headersEl ) {
  424. this._querySelector('ybplayer-icon-back').onclick = null
  425. this._headersEl.remove();
  426. this._headersEl = null;
  427. }
  428. },
  429. enumerable:false
  430. })
  431. Object.defineProperty(YBPlayer.prototype,'_initControls',{
  432. value:function(){
  433. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  434. throw new TypeError("TypeError: YBPlayer._initControls is not a constructor")
  435. }
  436. if ( this.container ) {
  437. this._controlsEl = document.createElement('DIV');
  438. this._controlsEl.setAttribute('class', 'ybplayer-controls');
  439. this._controlsEl.innerHTML = `
  440. <div class="ybplayer-controls-top">
  441. <div class="${this._setClassName('ybplayer-icon-play-prev')}" style="margin-right: ${this.prevBtnShow ? '10px' : 0};">
  442. ${this.prevBtnShow ? `
  443. <i class="ybplayerIconfont icon-play-prev-fill ybplayer-icon"></i>
  444. ` : ''}
  445. </div>
  446. <div class="${this._setClassName('ybplayer-icon-play')}">
  447. ${this.playShow ? `
  448. <i class="ybplayerIconfont ${this.video && !this.video.paused ? 'icon-pause' : 'icon-play'} ybplayer-icon"></i>
  449. ` : ''}
  450. </div>
  451. <div class="${this._setClassName('ybplayer-icon-play-next')}" style="margin-left: ${this.nextBtnShow ? '10px' : 0};">
  452. ${this.nextBtnShow ? `
  453. <i class="ybplayerIconfont icon-play-next-fill ybplayer-icon"></i>
  454. ` : ''}
  455. </div>
  456. <span class="${this._setClassName('ybplayer-controls-time')}">
  457. ${this.timeShow ? `
  458. 00:00 / 00:00
  459. ` : ''}
  460. </span>
  461. <div class="${this._setClassName('ybplayer-icon-volume')}" style="margin-left: ${this.volumeShow ? '25px' : 0};">
  462. ${this.volumeShow ? `
  463. <i class="ybplayerIconfont icon-volume-${this.muted ? 'muted' : 'medium'} ybplayer-icon"></i>
  464. ` : ''}
  465. </div>
  466. <div class="${this._setClassName('ybplayer-icon-setting')}" style="margin-left: ${this.settingShow ? '25px' : 0};">
  467. ${this.settingShow ? `
  468. <i class="ybplayerIconfont icon-setting ybplayer-icon"></i>
  469. ` : ''}
  470. </div>
  471. <div class="${this._setClassName('ybplayer-icon-fullscreen')}" style="margin-left: ${this.fullscreenShow ? '25px' : 0};">
  472. ${this.fullscreenShow ? `
  473. <i class="ybplayerIconfont ${ this.fullscreen ? 'icon-out-fullscreen' : 'icon-in-fullscreen'} ybplayer-icon"></i>
  474. ` : ''}
  475. </div>
  476. </div>
  477. <div class="${this._setClassName('ybplayer-controls-progress')}">
  478. </div>
  479. <div class="ybplayer-controls-shadow"></div>
  480. `;
  481. this.container.appendChild(this._controlsEl);
  482. this._controlsEl.onmousedown = () => {
  483. this._clear_controlsTimer()
  484. }
  485. this._controlsEl.onmouseleave = () => {
  486. this._start_controlsTimer()
  487. }
  488. if ( this.playShow ) {
  489. this._querySelector('ybplayer-icon-play').onclick = () => {
  490. this.toggle()
  491. }
  492. }
  493. if ( this.volumeShow ) {
  494. this._querySelector('ybplayer-icon-volume').onclick = () => {
  495. this.setConfig('muted', !this.muted)
  496. }
  497. }
  498. if ( this.settingShow ) {
  499. this._querySelector('ybplayer-icon-setting').onclick = () => {
  500. this._showSetting()
  501. }
  502. }
  503. if ( this.fullscreenShow ) {
  504. this._querySelector('ybplayer-icon-fullscreen').onclick = () => {
  505. this.switchFullscreen()
  506. }
  507. }
  508. if ( this.prevBtnShow ) {
  509. this._querySelector('ybplayer-icon-play-prev').onclick = () => {
  510. this._eventCallback.prevBtnClick && this._eventCallback.prevBtnClick();
  511. }
  512. }
  513. if ( this.nextBtnShow ) {
  514. this._querySelector('ybplayer-icon-play-next').onclick = () => {
  515. this._eventCallback.nextBtnClick && this._eventCallback.nextBtnClick();
  516. }
  517. }
  518. this._initProgress()
  519. this._showControls();
  520. }
  521. },
  522. enumerable:false
  523. })
  524. Object.defineProperty(YBPlayer.prototype,'_destroyControls',{
  525. value:function(){
  526. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  527. throw new TypeError("TypeError: YBPlayer._destroyControls is not a constructor")
  528. }
  529. if ( this._controlsEl ) {
  530. this._destroyProgress()
  531. this._controlsEl.onmousedown = null
  532. this._controlsEl.onmouseleave = null
  533. if ( this.playShow && this._querySelector('ybplayer-icon-volume') ) this._querySelector('ybplayer-icon-play').onclick = null
  534. if ( this.volumeShow && this._querySelector('ybplayer-icon-volume') ) this._querySelector('ybplayer-icon-volume').onclick = null
  535. if ( this.settingShow && this._querySelector('ybplayer-icon-setting') ) this._querySelector('ybplayer-icon-setting').onclick = null
  536. if ( this.fullscreenShow && this._querySelector('ybplayer-icon-fullscreen') ) this._querySelector('ybplayer-icon-fullscreen').onclick = null
  537. if ( this.prevBtnShow && this._querySelector('ybplayer-icon-play-prev') ) this._querySelector('ybplayer-icon-play-prev').onclick = null
  538. if ( this.nextBtnShow && this._querySelector('ybplayer-icon-play-next') ) this._querySelector('ybplayer-icon-play-next').onclick = null
  539. this._controlsEl.remove();
  540. this._controlsEl = null
  541. }
  542. if ( this._settingEl ) {
  543. for ( let i = 0; i < this._querySelectorAll('ybplayer-setting').length; i++ ) {
  544. this._querySelectorAll('ybplayer-setting').onclick = null
  545. }
  546. this._settingEl.remove();
  547. this._settingEl = null;
  548. }
  549. if ( this._playbackRateEl ) {
  550. for ( let i = 0; i < this._querySelectorAll('ybplayer-setting').length; i++ ) {
  551. this._querySelectorAll('ybplayer-setting')[i].onclick = null
  552. }
  553. this._playbackRateEl.remove();
  554. this._playbackRateEl = null;
  555. }
  556. },
  557. enumerable:false
  558. })
  559. Object.defineProperty(YBPlayer.prototype,'_showControls',{
  560. value:function(){
  561. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  562. throw new TypeError("TypeError: YBPlayer._showControls is not a constructor")
  563. }
  564. this._clear_controlsTimer()
  565. if ( this._controlsEl ) {
  566. this._controlsEl.setAttribute('class', 'ybplayer-controls ybplayer-controls-show');
  567. if ( this._controlSlotsEl ) this._controlSlotsEl.style.visibility = 'visible';
  568. if ( this._headersEl ) this._headersEl.setAttribute('class', 'ybplayer-headers ybplayer-headers-show');
  569. this._eventCallback.controlsChange && this._eventCallback.controlsChange({
  570. controls: true
  571. });
  572. this._start_controlsTimer()
  573. }
  574. },
  575. enumerable:false
  576. })
  577. Object.defineProperty(YBPlayer.prototype,'_hideControls',{
  578. value:function(){
  579. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  580. throw new TypeError("TypeError: YBPlayer._hideControls is not a constructor")
  581. }
  582. this._clear_controlsTimer()
  583. if ( this._controlsEl ) {
  584. this._controlsEl.setAttribute('class', 'ybplayer-controls ybplayer-controls-hide')
  585. if ( this._headersEl ) this._headersEl.setAttribute('class', 'ybplayer-headers ybplayer-headers-hide');
  586. if ( this._controlSlotsEl ) this._controlSlotsEl.style.visibility = 'hidden';
  587. this._eventCallback.controlsChange && this._eventCallback.controlsChange({
  588. controls: false
  589. });
  590. }
  591. },
  592. enumerable:false
  593. })
  594. Object.defineProperty(YBPlayer.prototype,'_setControlsView',{
  595. value:function(value){
  596. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  597. throw new TypeError("TypeError: YBPlayer._setControlsView is not a constructor")
  598. }
  599. if ( !this.controls ) return
  600. if ( value == 'play' && this._querySelector('ybplayer-icon-play') ) {
  601. if ( this.playShow ) {
  602. this._querySelector('ybplayer-icon-play').innerHTML = `<i class="ybplayerIconfont icon-${this.video.paused ? 'play' : 'pause'} ybplayer-icon"></i>`;
  603. } else {
  604. this._querySelector('ybplayer-icon-play').innerHTML = '';
  605. }
  606. } else if ( value == 'timeUpdate' ) {
  607. if ( !this._isDrag ) {
  608. if ( this.timeShow ) {
  609. var currentTime = this.video ? this.video.currentTime && this.video.currentTime != 'Infinity' ? this.video.currentTime : 0 : 0;
  610. var duration = this.isLive ? this.duration : this.video ? (this.duration || (this.video.duration && this.video.duration != 'Infinity' ? this.video.duration : 0) ) : 0;
  611. var timeEl = this._querySelector('ybplayer-controls-time')
  612. var rate = duration > 0 ? currentTime / duration : 0
  613. if ( this._querySelector('ybplayer-slider-focus') ) {
  614. this._querySelector('ybplayer-slider-focus').style.width = (rate * 100) + '%'
  615. }
  616. if ( this._querySelector('ybplayer-slider') ) {
  617. this._querySelector('ybplayer-slider').value = rate * 100
  618. }
  619. if ( this._querySelector('ybplayer-controls-time') ) {
  620. this._querySelector('ybplayer-controls-time').innerHTML = this.isLive ? this._timesFormat(parseInt(duration) + parseInt(currentTime)) : `${this._timesFormat(currentTime)} / ${this._timesFormat(duration)}`
  621. }
  622. } else {
  623. this._querySelector('ybplayer-controls-time').innerHTML = ''
  624. }
  625. }
  626. } else if ( value == 'volume' && this._querySelector('ybplayer-icon-volume') ) {
  627. if ( this.volumeShow ) {
  628. this._querySelector('ybplayer-icon-volume').style.marginLeft = '25px';
  629. this._querySelector('ybplayer-icon-volume').innerHTML = '<i class="ybplayerIconfont icon-volume-' + (this.muted ? 'muted' : 'medium') + ' ybplayer-icon"></i>'
  630. this._querySelector('ybplayer-icon-volume').onclick = () => {
  631. this.setConfig('muted', !this.muted)
  632. }
  633. } else {
  634. this._querySelector('ybplayer-icon-volume').style.marginLeft = '';
  635. this._querySelector('ybplayer-icon-volume').innerHTML = '';
  636. this._querySelector('ybplayer-icon-volume').onclick = null
  637. }
  638. } else if ( value == 'setting' && this._querySelector('ybplayer-icon-setting') ) {
  639. if ( this.settingShow ) {
  640. this._querySelector('ybplayer-icon-setting').style.marginLeft = '25px';
  641. this._querySelector('ybplayer-icon-setting').innerHTML = '<i class="ybplayerIconfont icon-setting ybplayer-icon"></i>';
  642. this._querySelector('ybplayer-icon-setting').onclick = () => {
  643. this._showSetting()
  644. }
  645. } else {
  646. this._querySelector('ybplayer-icon-setting').style.marginLeft = '';
  647. this._querySelector('ybplayer-icon-setting').innerHTML = '';
  648. this._querySelector('ybplayer-icon-setting').onclick = null;
  649. }
  650. } else if ( value == 'fullscreen' && this._querySelector('ybplayer-icon-fullscreen') ) {
  651. if ( this.fullscreenShow ) {
  652. this._querySelector('ybplayer-icon-fullscreen').style.marginLeft = '25px';
  653. this._querySelector('ybplayer-icon-fullscreen').innerHTML = '<i class="ybplayerIconfont icon-' + (this.fullscreen ? 'out-fullscreen' : 'in-fullscreen') + ' ybplayer-icon"></i>';
  654. this._querySelector('ybplayer-icon-fullscreen').onclick = () => {
  655. this.switchFullscreen()
  656. }
  657. } else {
  658. this._querySelector('ybplayer-icon-fullscreen').style.marginLeft = '';
  659. this._querySelector('ybplayer-icon-fullscreen').innerHTML = '';
  660. this._querySelector('ybplayer-icon-fullscreen').onclick = null;
  661. }
  662. } else if ( value == 'prevBtn' && this._querySelector('ybplayer-icon-play-prev') ) {
  663. if ( this.prevBtnShow ) {
  664. this._querySelector('ybplayer-icon-play-prev').style.marginRight = '10px';
  665. this._querySelector('ybplayer-icon-play-prev').innerHTML = '<i class="ybplayerIconfont icon-play-prev-fill ybplayer-icon"></i>';
  666. this._querySelector('ybplayer-icon-play-prev').onclick = () => {
  667. this._eventCallback.prevBtnClick && this._eventCallback.prevBtnClick()
  668. }
  669. } else {
  670. this._querySelector('ybplayer-icon-play-prev').style.marginRight = '';
  671. this._querySelector('ybplayer-icon-play-prev').innerHTML = '';
  672. this._querySelector('ybplayer-icon-play-prev').onclick = null;
  673. }
  674. } else if ( value == 'nextBtn' && this._querySelector('ybplayer-icon-play-next') ) {
  675. if ( this.nextBtnShow ) {
  676. this._querySelector('ybplayer-icon-play-next').style.marginLeft = '10px';
  677. this._querySelector('ybplayer-icon-play-next').innerHTML = '<i class="ybplayerIconfont icon-play-next-fill ybplayer-icon"></i>';
  678. this._querySelector('ybplayer-icon-play-next').onclick = () => {
  679. this._eventCallback.nextBtnClick && this._eventCallback.nextBtnClick()
  680. }
  681. } else {
  682. this._querySelector('ybplayer-icon-play-next').style.marginLeft = '';
  683. this._querySelector('ybplayer-icon-play-next').innerHTML = '';
  684. this._querySelector('ybplayer-icon-play-next').onclick = null;
  685. }
  686. }
  687. },
  688. enumerable:false
  689. })
  690. Object.defineProperty(YBPlayer.prototype,'_initProgress',{
  691. value:function(){
  692. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  693. throw new TypeError("TypeError: YBPlayer._initProgress is not a constructor")
  694. }
  695. if ( this._querySelector('ybplayer-controls-progress') && this.progressShow && !this.isLive ) {
  696. this._querySelector('ybplayer-controls-progress').innerHTML = `
  697. <div class="ybplayer-slider-box">
  698. <div class="${this._setClassName('ybplayer-slider-track')}"></div>
  699. <div class="${this._setClassName('ybplayer-slider-focus')}"></div>
  700. <input class="${this._setClassName('ybplayer-slider')} ybplayer-controls-slider" value="0" type="range">
  701. </div>
  702. `
  703. this._querySelector('ybplayer-slider').onchange = (e) => {
  704. this._isDrag = false
  705. this.video && this.seek((this._querySelector('ybplayer-slider').value / 100) * (this.duration || this.video.duration));
  706. this._start_controlsTimer();
  707. }
  708. this._querySelector('ybplayer-slider').oninput = (e) => {
  709. this._isDrag = true
  710. if ( this._querySelector('ybplayer-slider-focus') ) this._querySelector('ybplayer-slider-focus').style.width = this._querySelector('ybplayer-slider').value + '%'
  711. this._clear_controlsTimer();
  712. }
  713. }
  714. },
  715. enumerable:false
  716. })
  717. Object.defineProperty(YBPlayer.prototype,'_destroyProgress',{
  718. value:function(){
  719. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  720. throw new TypeError("TypeError: YBPlayer._destroyProgress is not a constructor")
  721. }
  722. if ( this._querySelector('ybplayer-controls-progress') ) {
  723. if ( this._querySelector('ybplayer-slider') ) this._querySelector('ybplayer-slider').onchange = null
  724. if ( this._querySelector('ybplayer-slider') ) this._querySelector('ybplayer-slider').oninput = null
  725. this._querySelector('ybplayer-controls-progress').innerHTML = ''
  726. }
  727. },
  728. enumerable:false
  729. })
  730. Object.defineProperty(YBPlayer.prototype,'_clear_controlsTimer',{
  731. value:function(){
  732. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  733. throw new TypeError("TypeError: YBPlayer._clear_controlsTimer is not a constructor")
  734. }
  735. if ( this.controls && this._controlsTimer ) {
  736. window.clearTimeout(this._controlsTimer)
  737. this._controlsTimer = null
  738. }
  739. },
  740. enumerable:false
  741. })
  742. Object.defineProperty(YBPlayer.prototype,'_start_controlsTimer',{
  743. value:function(){
  744. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  745. throw new TypeError("TypeError: YBPlayer._start_controlsTimer is not a constructor")
  746. }
  747. if ( this.controls ) {
  748. this._controlsTimer = window.setTimeout(() => {
  749. this._hideControls()
  750. }, 5000)
  751. }
  752. },
  753. enumerable:false
  754. })
  755. Object.defineProperty(YBPlayer.prototype,'_initSlots',{
  756. value:function(){
  757. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  758. throw new TypeError("TypeError: YBPlayer._initSlots is not a constructor")
  759. }
  760. let nodes = this.container.childNodes;
  761. for ( let i = 0; i < nodes.length; i++ ) {
  762. if ( [].concat(nodes[i].classList).toString().indexOf('ybplayer-slots') > -1 ) {
  763. this._slotsEl = nodes[i]
  764. let childNodes = this._slotsEl.childNodes;
  765. for ( let j = 0; j < childNodes.length; j++ ) {
  766. if ( [].concat(childNodes[j].classList).toString().indexOf('ybplayer-controls-slots') > -1 ) {
  767. this._controlSlotsEl = childNodes[j];
  768. }
  769. }
  770. this._wrapperEl.appendChild(this._slotsEl);
  771. }
  772. }
  773. },
  774. enumerable:false
  775. })
  776. Object.defineProperty(YBPlayer.prototype,'_destroySlots',{
  777. value:function(){
  778. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  779. throw new TypeError("TypeError: YBPlayer._destroySlots is not a constructor")
  780. }
  781. if ( this._controlSlotsEl ) this._controlSlotsEl = null
  782. if ( this._slotsEl && this.container ) {
  783. this.container.appendChild(this._slotsEl)
  784. this._slotsEl = null
  785. }
  786. },
  787. enumerable:false
  788. })
  789. Object.defineProperty(YBPlayer.prototype,'_showSetting',{
  790. value:function(){
  791. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  792. throw new TypeError("TypeError: YBPlayer._showSetting is not a constructor")
  793. }
  794. if ( this.container ) {
  795. this._settingEl = document.createElement('DIV');
  796. this._settingEl.setAttribute('class', 'ybplayer-settings');
  797. let barrageHtml = '';
  798. let settings = this.settings.split(',').map(setting => setting.trim());
  799. try{
  800. barrageHtml = YBBarrage ? `
  801. <div class="${this._setClassName('ybplayer-setting')}" data-value="barrage">
  802. <i class="ybplayerIconfont icon-barrage-${this.barrageShow ? 'show' : 'hide'} ybplayer-setting-icon"></i>
  803. <p class="ybplayer-setting-text">${this.barrageShow ? '关闭弹幕' : '开启弹幕'}</p>
  804. </div>
  805. ` : '';
  806. }catch(e){
  807. }
  808. this._settingEl.innerHTML = `
  809. ${ this.settings == 'all' || settings.indexOf('barrage') > -1 ? barrageHtml : ''}
  810. ${ this.settings == 'all' || settings.indexOf('playbackRate') > -1 ? `
  811. <div class="${this._setClassName('ybplayer-setting')}" data-value="playbackRate">
  812. <i class="ybplayerIconfont icon-play-rate-circle ybplayer-setting-icon"></i>
  813. <p class="ybplayer-setting-text">播放速度</p>
  814. </div>
  815. ` : '' }
  816. ${ this.settings == 'all' || settings.indexOf('mirror') > -1 ? `
  817. <div class="${this._setClassName('ybplayer-setting')}" data-value="mirror">
  818. <i class="ybplayerIconfont icon-mirror ybplayer-setting-icon"></i>
  819. <p class="ybplayer-setting-text">${this.mirror ? '关闭镜像' : '镜像画面'}</p>
  820. </div>
  821. ` : '' }
  822. ${ this.settings == 'all' || settings.indexOf('capture') > -1 ? `
  823. <div class="${this._setClassName('ybplayer-setting')}" data-value="capture">
  824. <i class="ybplayerIconfont icon-screenshot ybplayer-setting-icon"></i>
  825. <p class="ybplayer-setting-text">截取画面</p>
  826. </div>
  827. ` : '' }
  828. ${ (this.settings == 'all' || settings.indexOf('pictureInPicture') > -1) && document.pictureInPictureEnabled ? `
  829. <div class="${this._setClassName('ybplayer-setting')}" data-value="pictureInPicture">
  830. <i class="ybplayerIconfont icon-picture-in-picture-${this.pictureInPicture ? 'open' : 'exit'} ybplayer-setting-icon"></i>
  831. <p class="ybplayer-setting-text">${this.pictureInPicture ? '退出画中画' : '画中画'}</p>
  832. </div>
  833. ` : '' }
  834. `;
  835. this.container.appendChild(this._settingEl);
  836. for ( let i = 0; i < this._querySelectorAll('ybplayer-setting').length; i++ ) {
  837. this._querySelectorAll('ybplayer-setting')[i].onclick = () => {
  838. let type = this._querySelectorAll('ybplayer-setting')[i].getAttribute('data-value');
  839. if ( type == 'barrage' ) {
  840. this.setConfig('barrageShow', !this.barrageShow);
  841. } else if ( type == 'playbackRate' ) {
  842. if ( this._playbackRateEl ) {
  843. this._hidePlaybackRate();
  844. } else {
  845. this._showPlaybackRate();
  846. }
  847. } else if ( type == 'mirror' ) {
  848. this.setConfig('mirror', !this.mirror);
  849. } else if ( type == 'capture' ) {
  850. this.capture();
  851. this._hideSetting();
  852. } else {
  853. this.setConfig('pictureInPicture', !this.pictureInPicture);
  854. }
  855. }
  856. }
  857. }
  858. },
  859. enumerable:false
  860. })
  861. Object.defineProperty(YBPlayer.prototype,'_hideSetting',{
  862. value:function(){
  863. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  864. throw new TypeError("TypeError: YBPlayer._hideSetting is not a constructor")
  865. }
  866. if ( this.container && this._settingEl ) {
  867. this._settingEl.setAttribute('class', 'ybplayer-settings ybplayer-settings-hide');
  868. for ( let i = 0; i < this._querySelectorAll('ybplayer-setting').length; i++ ) {
  869. this._querySelectorAll('ybplayer-setting')[i].onclick = null
  870. }
  871. window.setTimeout(() => {
  872. this.container.removeChild(this._settingEl);
  873. this._settingEl = null;
  874. }, 300);
  875. }
  876. },
  877. enumerable:false
  878. })
  879. Object.defineProperty(YBPlayer.prototype,'_setSettingView',{
  880. value:function(value){
  881. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  882. throw new TypeError("TypeError: YBPlayer._setSettingView is not a constructor")
  883. }
  884. if ( this._querySelector('ybplayer-setting') ) {
  885. for ( let i = 0; i < this._querySelectorAll('ybplayer-setting').length; i++ ) {
  886. if ( this._querySelectorAll('ybplayer-setting')[i].getAttribute('data-value') == value ) {
  887. if ( value == 'barrage' ) {
  888. this._querySelectorAll('ybplayer-setting')[i].innerHTML = `
  889. <i class="ybplayerIconfont icon-barrage-${this.barrageShow ? 'show' : 'hide'} ybplayer-setting-icon"></i>
  890. <p class="ybplayer-setting-text">${this.barrageShow ? '关闭弹幕' : '开启弹幕'}</p>
  891. `;
  892. } else if ( value == 'mirror' ) {
  893. this._querySelectorAll('ybplayer-setting')[i].innerHTML = `
  894. <i class="ybplayerIconfont icon-mirror ybplayer-setting-icon"></i>
  895. <p class="ybplayer-setting-text">${this.mirror ? '关闭镜像' : '镜像画面'}</p>
  896. `;
  897. } else if ( value == 'pictureInPicture' ) {
  898. this._querySelectorAll('ybplayer-setting')[i].innerHTML = `
  899. <i class="ybplayerIconfont icon-picture-in-picture-${this.pictureInPicture ? 'open' : 'exit'} ybplayer-setting-icon"></i>
  900. <p class="ybplayer-setting-text">${this.pictureInPicture ? '退出画中画' : '画中画'}</p>
  901. `;
  902. }
  903. }
  904. }
  905. }
  906. },
  907. enumerable:false
  908. })
  909. Object.defineProperty(YBPlayer.prototype,'_showPlaybackRate',{
  910. value:function(){
  911. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  912. throw new TypeError("TypeError: YBPlayer._showPlaybackRate is not a constructor")
  913. }
  914. if ( this.container ) {
  915. this._hideSetting();
  916. this._playbackRateEl = document.createElement('DIV');
  917. this._playbackRateEl.setAttribute('class', 'ybplayer-settings');
  918. let playbackRates = [{
  919. label: '0.25',
  920. value: 0.25
  921. },{
  922. label: '0.5',
  923. value: 0.5
  924. },{
  925. label: '0.75',
  926. value: 0.75
  927. },{
  928. label: '正常',
  929. value: 1.0
  930. },{
  931. label: '1.25',
  932. value: 1.25
  933. },{
  934. label: '1.5',
  935. value: 1.5
  936. },{
  937. label: '1.75',
  938. value: 1.75
  939. },{
  940. label: '2.0',
  941. value: 2.0
  942. }];
  943. for ( let rate of playbackRates ) {
  944. this._playbackRateEl.innerHTML += `
  945. <div class="${this._setClassName('ybplayer-setting')}" data-rate="${rate.value}">
  946. <p class="ybplayer-setting-text" style="color: ${rate.value == this.playbackRate ? '#2ca2f9' : '#333'};">${rate.label}</p>
  947. </div>
  948. `;
  949. }
  950. this.container.appendChild(this._playbackRateEl);
  951. let that = this
  952. for ( let i = 0; i < this._querySelectorAll('ybplayer-setting').length; i++ ) {
  953. this._querySelectorAll('ybplayer-setting')[i].onclick = function () {
  954. that.setConfig('playbackRate', this.getAttribute('data-rate'))
  955. }
  956. }
  957. }
  958. },
  959. enumerable:false
  960. })
  961. Object.defineProperty(YBPlayer.prototype,'_hidePlaybackRate',{
  962. value:function(){
  963. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  964. throw new TypeError("TypeError: YBPlayer._hidePlaybackRate is not a constructor")
  965. }
  966. if ( this.container && this._playbackRateEl ) {
  967. this._playbackRateEl.setAttribute('class', 'ybplayer-settings ybplayer-settings-hide');
  968. for ( let i = 0; i < this._querySelectorAll('ybplayer-setting').length; i++ ) {
  969. this._querySelectorAll('ybplayer-setting')[i].onclick = null
  970. }
  971. window.setTimeout(() => {
  972. this.container.removeChild(this._playbackRateEl);
  973. this._playbackRateEl = null;
  974. this._showSetting();
  975. }, 300);
  976. }
  977. },
  978. enumerable:false
  979. })
  980. Object.defineProperty(YBPlayer.prototype,'_initBarrage',{
  981. value:function(){
  982. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  983. throw new TypeError("TypeError: YBPlayer._initBarrage is not a constructor")
  984. }
  985. try{
  986. this.barrage = new YBBarrage({
  987. container: this._barrageEl,
  988. barrages: this.barrages,
  989. config: Object.assign({}, this.barrageConfig, {
  990. initialTime: this.video ? this.video.currentTime : 0
  991. })
  992. });
  993. if ( !this.video.paused ) this.barrage.play();
  994. this._setSettingView('barrage');
  995. this._eventCallback.barrageChange && this._eventCallback.barrageChange({
  996. show: true
  997. })
  998. }catch(e){
  999. //TODO handle the exception
  1000. }
  1001. },
  1002. enumerable:false
  1003. })
  1004. Object.defineProperty(YBPlayer.prototype,'_destroyBarrage',{
  1005. value:function(){
  1006. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1007. throw new TypeError("TypeError: YBPlayer._destroyBarrage is not a constructor")
  1008. }
  1009. if ( this.barrage ) {
  1010. this.barrage.stop();
  1011. this.barrage = null;
  1012. this._setSettingView('barrage');
  1013. this._eventCallback.barrageChange && this._eventCallback.barrageChange({
  1014. show: false
  1015. })
  1016. }
  1017. },
  1018. enumerable:false
  1019. })
  1020. Object.defineProperty(YBPlayer.prototype,'_setConfig',{
  1021. value:function(attribute, value){
  1022. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1023. throw new TypeError("TypeError: YBPlayer._setConfig is not a constructor")
  1024. }
  1025. let videoAttributes = ['autoplay', 'loop', 'muted', 'preload', 'volume', 'playbackRate', 'crossOrigin'];
  1026. if ( this.video && videoAttributes.indexOf(attribute) > -1 )
  1027. this.video[attribute] = value;
  1028. if ( this.video && attribute == 'objectFit' )
  1029. this.video.style.objectFit = value;
  1030. if ( this.video && attribute == 'mirror' ) {
  1031. this.video.style.transform = 'rotateY(' + (value ? 180 : 0) + 'deg)';
  1032. this._setSettingView('mirror');
  1033. }
  1034. if ( this.video && attribute == 'pictureInPicture' ) {
  1035. if ( document.pictureInPictureEnabled ) {
  1036. if ( value )
  1037. this.video.requestPictureInPicture();
  1038. else
  1039. document.pictureInPictureElement && document.exitPictureInPicture();
  1040. }
  1041. }
  1042. if ( attribute == 'controls' ) {
  1043. if ( value )
  1044. this._initControls()
  1045. else
  1046. this._destroyControls()
  1047. }
  1048. if ( attribute == 'prevBtnShow' ) {
  1049. this._setControlsView('prevBtn')
  1050. }
  1051. if ( attribute == 'nextBtnShow' ) {
  1052. this._setControlsView('nextBtn')
  1053. }
  1054. if ( attribute == 'timeShow' ) {
  1055. this._setControlsView('timeUpdate')
  1056. }
  1057. if ( attribute == 'settingShow' ) {
  1058. this._setControlsView('setting')
  1059. }
  1060. if ( attribute == 'progressShow' ) {
  1061. if ( value )
  1062. this._initProgress()
  1063. else
  1064. this._destroyProgress()
  1065. }
  1066. if ( attribute == 'barrageShow' ) {
  1067. if ( value )
  1068. this._initBarrage()
  1069. else
  1070. this._destroyBarrage()
  1071. }
  1072. if ( attribute == 'barrageConfig' ) {
  1073. this.barrage && this.barrage.setConfig(value);
  1074. }
  1075. if ( attribute == 'barrageGap' ) {
  1076. this.barrage && this.barrage.refresh();
  1077. }
  1078. if ( attribute == 'title' ) {
  1079. if ( value ) {
  1080. if ( this._querySelector('ybplayer-headers-title') ) {
  1081. this._querySelector('ybplayer-headers-title').innerHTML = value;
  1082. } else {
  1083. this._initHeaders();
  1084. }
  1085. } else {
  1086. this._destroyHeaders();
  1087. }
  1088. }
  1089. if ( attribute == 'src' || attribute == 'segments' ) {
  1090. this._destroyControls();
  1091. this._destroyBarrage();
  1092. this._destroyHeaders();
  1093. this._destroyHls()
  1094. this._destroyFlv();
  1095. this._destroyVideo();
  1096. this._destroySlots();
  1097. this._initVideo();
  1098. this._initSlots();
  1099. this._setVideoUrl();
  1100. if ( this.fullscreen ) this._initHeaders();
  1101. if ( this.controls ) this._initControls();
  1102. }
  1103. },
  1104. enumerable:false
  1105. })
  1106. //获取后缀
  1107. Object.defineProperty(YBPlayer.prototype,'_suffix',{
  1108. value:function(name){
  1109. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1110. throw new TypeError("TypeError: YBPlayer._suffix is not a constructor")
  1111. }
  1112. let fileName = name.lastIndexOf(".");
  1113. let fileNameLength = name.length;
  1114. let fileFormat = name.substring(fileName + 1, fileNameLength);
  1115. return fileFormat;
  1116. },
  1117. enumerable:false
  1118. })
  1119. //格式化时间
  1120. Object.defineProperty(YBPlayer.prototype,'_timesFormat',{
  1121. value:function(value){
  1122. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1123. throw new TypeError("TypeError: YBPlayer._timesFormat is not a constructor")
  1124. }
  1125. let hours = Math.floor(value / 60 / 60 % 60) >= 10 ? Math.floor(value / 60 / 60 % 60) : '0' + Math.floor(value / 60 / 60 % 60);
  1126. let minutes = Math.floor(value / 60 % 60) >= 10 ? Math.floor(value / 60 % 60) : '0' + Math.floor(value / 60 % 60);
  1127. let seconds = Math.floor(value % 60) >= 10 ? Math.floor(value % 60) : '0' + Math.floor(value % 60);
  1128. return hours == '00' ? (minutes + ':' + seconds) : (hours + ':' + minutes + ':' + seconds);
  1129. },
  1130. enumerable:false
  1131. })
  1132. //深度克隆
  1133. Object.defineProperty(YBPlayer.prototype,'_deepClone',{
  1134. value:function(obj){
  1135. if(typeof obj !== "object" && typeof obj !== 'function') {
  1136. //原始类型直接返回
  1137. return obj;
  1138. }
  1139. var o = Object.prototype.toString.call(obj) === '[object Array]' ? [] : {};
  1140. for(let i in obj) {
  1141. if(obj.hasOwnProperty(i)){
  1142. o[i] = i === 'loader' ? '' : Object.prototype.toString.call( obj[i] ) === '[object XMLHttpRequest]' ? "" : typeof obj[i] === "object" ? this._deepClone(obj[i]) : obj[i];
  1143. }
  1144. }
  1145. return o;
  1146. },
  1147. enumerable:false
  1148. })
  1149. Object.defineProperty(YBPlayer.prototype,'_setClassName',{
  1150. value:function(className){
  1151. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1152. throw new TypeError("TypeError: YBPlayer._setClassName is not a constructor")
  1153. }
  1154. return this.container.id + '_' + className + ' ' + className
  1155. },
  1156. enumerable:false
  1157. })
  1158. Object.defineProperty(YBPlayer.prototype,'_querySelector',{
  1159. value:function(className){
  1160. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1161. throw new TypeError("TypeError: YBPlayer._querySelector is not a constructor")
  1162. }
  1163. return this.container && document.getElementsByClassName(this.container.id + '_' + className) && document.getElementsByClassName(this.container.id + '_' + className).length > 0 ? document.getElementsByClassName(this.container.id + '_' + className)[0] : null
  1164. },
  1165. enumerable:false
  1166. })
  1167. Object.defineProperty(YBPlayer.prototype,'_querySelectorAll',{
  1168. value:function(className){
  1169. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1170. throw new TypeError("TypeError: YBPlayer._querySelectorAll is not a constructor")
  1171. }
  1172. return this.container ? document.getElementsByClassName(this.container.id + '_' + className) || [] : []
  1173. },
  1174. enumerable:false
  1175. })
  1176. Object.defineProperty(YBPlayer.prototype,'_setVideoUrl',{
  1177. value:function(){
  1178. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1179. throw new TypeError("TypeError: YBPlayer._setVideoUrl is not a constructor")
  1180. }
  1181. if ( this.src ) {
  1182. let formats = '';
  1183. if ( this.formats == 'auto' )
  1184. formats = this._suffix(this.src.split('?')[0]);
  1185. else
  1186. formats = this.formats;
  1187. if ( formats == 'm3u8' )
  1188. this._setM3u8();
  1189. else if ( formats == 'flv' )
  1190. this._setFlv();
  1191. else
  1192. this._setBlob();
  1193. } else if ( this.segments ) {
  1194. this._setFlv();
  1195. }
  1196. },
  1197. enumerable:false
  1198. })
  1199. Object.defineProperty(YBPlayer.prototype,'_setBlob',{
  1200. value:function(){
  1201. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1202. throw new TypeError("TypeError: YBPlayer._setBlob is not a constructor")
  1203. }
  1204. if ( this.enableBlob ) {
  1205. let xhr = new XMLHttpRequest()
  1206. xhr.open('GET', this.src, true)
  1207. xhr.responseType = 'blob'
  1208. xhr.onload = () => {
  1209. if ( xhr.status == 200 ) {
  1210. try {
  1211. this.video.srcObject = xhr.response
  1212. } catch (error) {
  1213. const URL = window.URL || window.webkitURL
  1214. this.video.src = URL.createObjectURL(xhr.response);
  1215. }
  1216. } else {
  1217. this.video.src = this.src
  1218. }
  1219. // this.video.load()
  1220. xhr.abort()
  1221. xhr = null
  1222. }
  1223. xhr.onerror = () => {
  1224. this.video.src = this.src
  1225. // this.video.load()
  1226. xhr = null
  1227. }
  1228. xhr.send()
  1229. } else {
  1230. this.video.src = this.src
  1231. // this.video.load()
  1232. }
  1233. },
  1234. enumerable:false
  1235. })
  1236. Object.defineProperty(YBPlayer.prototype,'_setM3u8',{
  1237. value:function(){
  1238. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1239. throw new TypeError("TypeError: YBPlayer._setM3u8 is not a constructor")
  1240. }
  1241. try{
  1242. if ( Hls.isSupported() ) {
  1243. this.hls = new Hls();
  1244. this.hls.loadSource(this.src);
  1245. this.hls.attachMedia(this.video);
  1246. // this.hls.on(Hls.Events.MANIFEST_PARSED, (e) => { });
  1247. this.hls.on(Hls.Events.ERROR, (e, data) => {
  1248. this._eventCallback.error && this._eventCallback.error(this._deepClone(data));
  1249. });
  1250. } else {
  1251. this.video.src = this.src;
  1252. // this.video.load();
  1253. }
  1254. }catch(e){
  1255. this._eventCallback.error && this._eventCallback.error(this._deepClone(e))
  1256. }
  1257. },
  1258. enumerable:false
  1259. })
  1260. Object.defineProperty(YBPlayer.prototype,'_destroyHls',{
  1261. value:function(){
  1262. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1263. throw new TypeError("TypeError: YBPlayer._destroyHls is not a constructor")
  1264. }
  1265. if (this.hls) {
  1266. this.hls.destroy();
  1267. this.hls= null;
  1268. }
  1269. },
  1270. enumerable:false
  1271. })
  1272. Object.defineProperty(YBPlayer.prototype,'_setFlv',{
  1273. value:function(){
  1274. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1275. throw new TypeError("TypeError: YBPlayer._setFlv is not a constructor")
  1276. }
  1277. try{
  1278. if (flvjs.isSupported()) {
  1279. this.flv = flvjs.createPlayer(
  1280. {
  1281. type: "flv",
  1282. isLive: this.isLive,
  1283. url: this.src,
  1284. segments: this.segment && this.segments.length > 0 ? this.segment : null,
  1285. cors: this.flvConfig.cors,
  1286. withCredentials: this.flvConfig.withCredentials,
  1287. hasAudio: this.flvConfig.hasAudio,
  1288. hasVideo: this.flvConfig.hasVideo,
  1289. duration: this.flvConfig.duration,
  1290. filesize: this.flvConfig.filesize
  1291. },
  1292. Object.assign({}, {
  1293. enableWorker: false, //不启用分离线程
  1294. enableStashBuffer: false, //关闭IO隐藏缓冲区
  1295. isLive: true,
  1296. lazyLoad: false
  1297. }, this.flvConfig)
  1298. )
  1299. } else {
  1300. this.video.src = this.src;
  1301. // this.video.load();
  1302. }
  1303. this.flv.on('error', this._flvError.bind(this));
  1304. this.flv.on("statistics_info", this._statisticsInfo.bind(this));
  1305. this.flv.on("loading_complete", this._loadingComplete.bind(this));
  1306. this.flv.on("recovered_early_eof", this._recoveredEarlyEof.bind(this));
  1307. this.flv.on("media_info", this._mediaInfo.bind(this));
  1308. this.flv.on("metadata_arrived", this._metadataArrived.bind(this));
  1309. this.flv.on("scriptdata_arrived", this._scriptdataArrived.bind(this));
  1310. this.flv.attachMediaElement(this.video);
  1311. this.flv.load();
  1312. }catch(e){
  1313. this._flvError(e)
  1314. }
  1315. },
  1316. enumerable:false
  1317. })
  1318. Object.defineProperty(YBPlayer.prototype,'_destroyFlv',{
  1319. value:function(){
  1320. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1321. throw new TypeError("TypeError: YBPlayer._destroyFlv is not a constructor")
  1322. }
  1323. if (this.flv) {
  1324. this.flv.off('error', this._flvError)
  1325. this.flv.off('statistics_info', this._statisticsInfo.bind(this))
  1326. this.flv.off('loading_complete', this._loadingComplete.bind(this))
  1327. this.flv.off("recovered_early_eof", this._recoveredEarlyEof.bind(this));
  1328. this.flv.off("media_info", this._mediaInfo.bind(this));
  1329. this.flv.off("metadata_arrived", this._metadataArrived.bind(this));
  1330. this.flv.off("scriptdata_arrived", this._scriptdataArrived.bind(this));
  1331. this.flv.pause();
  1332. this.flv.unload();
  1333. this.flv.detachMediaElement();
  1334. this.flv.destroy();
  1335. this.flv= null;
  1336. }
  1337. },
  1338. enumerable:false
  1339. })
  1340. Object.defineProperty(YBPlayer.prototype,'_flvError',{
  1341. value:function(e){
  1342. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1343. throw new TypeError("TypeError: YBPlayer._flvError is not a constructor")
  1344. }
  1345. this._eventCallback.error && this._eventCallback.error(this._deepClone(e));
  1346. },
  1347. enumerable:false
  1348. })
  1349. Object.defineProperty(YBPlayer.prototype,'_statisticsInfo',{
  1350. value:function(e){
  1351. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1352. throw new TypeError("TypeError: YBPlayer._statisticsInfo is not a constructor")
  1353. }
  1354. this._eventCallback.statisticsInfo && this._eventCallback.statisticsInfo(this._deepClone(e));
  1355. },
  1356. enumerable:false
  1357. })
  1358. Object.defineProperty(YBPlayer.prototype,'_loadingComplete',{
  1359. value:function(e){
  1360. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1361. throw new TypeError("TypeError: YBPlayer._loadingComplete is not a constructor")
  1362. }
  1363. this._eventCallback.loadingComplete && this._eventCallback.loadingComplete(this._deepClone(e));
  1364. },
  1365. enumerable:false
  1366. })
  1367. Object.defineProperty(YBPlayer.prototype,'_recoveredEarlyEof',{
  1368. value:function(e){
  1369. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1370. throw new TypeError("TypeError: YBPlayer._recoveredEarlyEof is not a constructor")
  1371. }
  1372. this._eventCallback.recoveredEarlyEof && this._eventCallback.recoveredEarlyEof(this._deepClone(e));
  1373. },
  1374. enumerable:false
  1375. })
  1376. Object.defineProperty(YBPlayer.prototype,'_mediaInfo',{
  1377. value:function(e){
  1378. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1379. throw new TypeError("TypeError: YBPlayer._mediaInfo is not a constructor")
  1380. }
  1381. this._eventCallback.mediaInfo && this._eventCallback.mediaInfo(this._deepClone(e));
  1382. },
  1383. enumerable:false
  1384. })
  1385. Object.defineProperty(YBPlayer.prototype,'_metadataArrived',{
  1386. value:function(e){
  1387. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1388. throw new TypeError("TypeError: YBPlayer._metadataArrived is not a constructor")
  1389. }
  1390. this._eventCallback.metadataArrived && this._eventCallback.metadataArrived(this._deepClone(e));
  1391. },
  1392. enumerable:false
  1393. })
  1394. Object.defineProperty(YBPlayer.prototype,'_scriptdataArrived',{
  1395. value:function(e){
  1396. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1397. throw new TypeError("TypeError: YBPlayer._scriptdataArrived is not a constructor")
  1398. }
  1399. this._eventCallback.scriptdataArrived && this._eventCallback.scriptdataArrived(this._deepClone(e));
  1400. },
  1401. enumerable:false
  1402. })
  1403. Object.defineProperty(YBPlayer.prototype,'_fullscreenerror',{
  1404. value:function(){
  1405. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1406. throw new TypeError("TypeError: YBPlayer._fullscreenerror is not a constructor")
  1407. }
  1408. if ( this.container ) {
  1409. this.container.style.position = 'fixed';
  1410. this.container.style.left = 0;
  1411. this.container.style.right = 0;
  1412. this.container.style.bottom = 0;
  1413. this.container.style.top = 0;
  1414. this.container.style.width = '100vw';
  1415. this.container.style.height = '100vh';
  1416. this.container.style.zIndex = 999;
  1417. this._videoBackground = this.container.style.background
  1418. this.container.style.background = '#000'
  1419. this._cssfullscreenchange();
  1420. }
  1421. },
  1422. enumerable:false
  1423. })
  1424. Object.defineProperty(YBPlayer.prototype,'_fullscreenchanged',{
  1425. value:function(){
  1426. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1427. throw new TypeError("TypeError: YBPlayer._fullscreenchanged is not a constructor")
  1428. }
  1429. if ( document.fullscreenElement || document.mozFullScreenElement || document.msFullscreenElement || document.webkitFullscreenElement ) {
  1430. this._eventCallback.fullscreenChange && this._eventCallback.fullscreenChange({
  1431. fullscreen: true,
  1432. type: 'requestfullscreen'
  1433. });
  1434. this.fullscreen = true;
  1435. this._initHeaders();
  1436. } else {
  1437. this._eventCallback.fullscreenChange && this._eventCallback.fullscreenChange({
  1438. fullscreen: false,
  1439. type: 'requestfullscreen'
  1440. });
  1441. this.fullscreen = false;
  1442. this._destroyHeaders();
  1443. }
  1444. this._setControlsView('fullscreen');
  1445. this.refreshBarrage();
  1446. },
  1447. enumerable:false
  1448. })
  1449. Object.defineProperty(YBPlayer.prototype,'_cssfullscreenchange',{
  1450. value:function(){
  1451. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1452. throw new TypeError("TypeError: YBPlayer._cssfullscreenchange is not a constructor")
  1453. }
  1454. if ( this.container && this.container.style.position == 'fixed' ) {
  1455. this._eventCallback.fullscreenChange && this._eventCallback.fullscreenChange({
  1456. fullscreen: true,
  1457. type: 'cssfullscreen'
  1458. });
  1459. this.fullscreen = true;
  1460. this._initHeaders();
  1461. } else {
  1462. this._eventCallback.fullscreenChange && this._eventCallback.fullscreenChange({
  1463. fullscreen: false,
  1464. type: 'cssfullscreen'
  1465. });
  1466. this.fullscreen = false;
  1467. this._destroyHeaders();
  1468. }
  1469. this._setControlsView('fullscreen');
  1470. this.refreshBarrage();
  1471. },
  1472. enumerable:false
  1473. })
  1474. Object.defineProperty(YBPlayer.prototype,'on',{
  1475. value:function(event, callback){
  1476. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1477. throw new TypeError("TypeError: YBPlayer.on is not a constructor")
  1478. }
  1479. this._eventCallback[event] = callback;
  1480. },
  1481. enumerable:false
  1482. })
  1483. Object.defineProperty(YBPlayer.prototype,'play',{
  1484. value:function(){
  1485. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1486. throw new TypeError("TypeError: YBPlayer.play is not a constructor")
  1487. }
  1488. this.video && this.video.play()
  1489. },
  1490. enumerable:false
  1491. })
  1492. Object.defineProperty(YBPlayer.prototype,'pause',{
  1493. value:function(){
  1494. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1495. throw new TypeError("TypeError: YBPlayer.pause is not a constructor")
  1496. }
  1497. this.video && this.video.pause()
  1498. },
  1499. enumerable:false
  1500. })
  1501. Object.defineProperty(YBPlayer.prototype,'toggle',{
  1502. value:function(){
  1503. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1504. throw new TypeError("TypeError: YBPlayer.toggle is not a constructor")
  1505. }
  1506. this.video && this.video.paused ? this.video.play() : this.video.pause()
  1507. },
  1508. enumerable:false
  1509. })
  1510. Object.defineProperty(YBPlayer.prototype,'seek',{
  1511. value:function(time){
  1512. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1513. throw new TypeError("TypeError: YBPlayer.seek is not a constructor")
  1514. }
  1515. if ( this.video ) this.video.currentTime = time
  1516. },
  1517. enumerable:false
  1518. })
  1519. Object.defineProperty(YBPlayer.prototype,'reload',{
  1520. value:function(){
  1521. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1522. throw new TypeError("TypeError: YBPlayer.reload is not a constructor")
  1523. }
  1524. this._destroy(false)
  1525. this._init()
  1526. },
  1527. enumerable:false
  1528. })
  1529. Object.defineProperty(YBPlayer.prototype,'stop',{
  1530. value:function(){
  1531. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1532. throw new TypeError("TypeError: YBPlayer.stop is not a constructor")
  1533. }
  1534. this._destroy()
  1535. },
  1536. enumerable:false
  1537. })
  1538. Object.defineProperty(YBPlayer.prototype,'capture',{
  1539. value:function(){
  1540. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1541. throw new TypeError("TypeError: YBPlayer.capture is not a constructor")
  1542. }
  1543. const canvas = document.createElement('canvas');
  1544. canvas.width = this.video.videoWidth;
  1545. canvas.height = this.video.videoHeight;
  1546. canvas.getContext('2d').drawImage(this.video, 0, 0, canvas.width, canvas.height);
  1547. canvas.toBlob(blob => {
  1548. this._eventCallback.captureFinish && this._eventCallback.captureFinish({
  1549. blob: blob,
  1550. base64: canvas.toDataURL('image/jpg')
  1551. })
  1552. }, 'image/jpg')
  1553. },
  1554. enumerable:false
  1555. })
  1556. Object.defineProperty(YBPlayer.prototype,'drawBarrage',{
  1557. value:function(barrage){
  1558. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1559. throw new TypeError("TypeError: YBPlayer.drawBarrage is not a constructor")
  1560. }
  1561. this.barrage && this.barrage.add(barrage);
  1562. },
  1563. enumerable:false
  1564. })
  1565. Object.defineProperty(YBPlayer.prototype,'refreshBarrage',{
  1566. value:function(){
  1567. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1568. throw new TypeError("TypeError: YBPlayer.refreshBarrage is not a constructor")
  1569. }
  1570. this.barrage && this.barrage.refresh();
  1571. },
  1572. enumerable:false
  1573. })
  1574. Object.defineProperty(YBPlayer.prototype,'setBarrages',{
  1575. value:function(barrages){
  1576. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1577. throw new TypeError("TypeError: YBPlayer.setBarrages is not a constructor")
  1578. }
  1579. this.barrages = barrages;
  1580. this.barrage && this.barrage.setBarrages(barrages);
  1581. },
  1582. enumerable:false
  1583. })
  1584. Object.defineProperty(YBPlayer.prototype,'setConfig',{
  1585. value:function(attribute, value){
  1586. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1587. throw new TypeError("TypeError: YBPlayer.setConfig is not a constructor")
  1588. }
  1589. this[attribute] = value;
  1590. this._setConfig(attribute, value);
  1591. },
  1592. enumerable:false
  1593. })
  1594. Object.defineProperty(YBPlayer.prototype,'switchFullscreen',{
  1595. value:function(){
  1596. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1597. throw new TypeError("TypeError: YBPlayer.switchFullscreen is not a constructor")
  1598. }
  1599. if ( document.fullscreenElement || document.mozFullScreenElement || document.msFullscreenElement || document.webkitFullscreenElement || (this.container && this.container.style.position == 'fixed') ) {
  1600. this.exitFullscreen()
  1601. } else {
  1602. this.lanuchFullscreen()
  1603. }
  1604. },
  1605. enumerable:false
  1606. })
  1607. Object.defineProperty(YBPlayer.prototype,'lanuchFullscreen',{
  1608. value:function(){
  1609. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1610. throw new TypeError("TypeError: YBPlayer.lanuchFullscreen is not a constructor")
  1611. }
  1612. if ( document.fullscreenElement || document.mozFullScreenElement || document.msFullscreenElement || document.webkitFullscreenElement ) return
  1613. const rfs = document.documentElement.requestFullscreen || document.documentElement.webkitRequestFullscreen || document.documentElement.mozRequestFullscreen || document.documentElement.requestFullScreen || document.documentElement.webkitRequestFullScreen || document.documentElement.mozRequestFullScreen
  1614. if ( typeof rfs != 'undefined' && rfs && this.container ) {
  1615. rfs.call(this.container)
  1616. } else if (typeof window.ActiveXObject !== "undefined") {
  1617. //IE浏览器,模拟按下F11全屏
  1618. var wscript = new ActiveXObject("WScript.Shell");
  1619. if (wscript != null) {
  1620. wscript.SendKeys("{F11}");
  1621. }
  1622. } else {
  1623. this._fullscreenerror()
  1624. }
  1625. },
  1626. enumerable:false
  1627. })
  1628. Object.defineProperty(YBPlayer.prototype,'exitFullscreen',{
  1629. value:function(){
  1630. if(!(this instanceof YBPlayer)){//那么相反 不是正常调用的就是错误的调用
  1631. throw new TypeError("TypeError: YBPlayer.exitFullscreen is not a constructor")
  1632. }
  1633. if ( document.fullscreenElement || document.mozFullScreenElement || document.msFullscreenElement || document.webkitFullscreenElement ) {
  1634. const cfs = document.exitFullscreen || document.mozCancelFullScreen || document.msExitFullscreen || document.webkitExitFullscreen;
  1635. if ( typeof cfs != 'undefined' && cfs ) {
  1636. cfs.call(document)
  1637. }
  1638. } else if (typeof window.ActiveXObject !== "undefined") {
  1639. //IE浏览器,模拟按下F11键退出全屏
  1640. var wscript = new ActiveXObject("WScript.Shell");
  1641. if (wscript != null) {
  1642. wscript.SendKeys("{F11}");
  1643. }
  1644. } else {
  1645. if ( this.container && this.container.style.position == 'fixed' ) {
  1646. this.container.style.position = 'relative';
  1647. this.container.style.width = '100%';
  1648. this.container.style.height = '100%';
  1649. this.container.style.top = 'inherit';
  1650. this.container.style.left = 'inherit';
  1651. this.container.style.right = 'inherit';
  1652. this.container.style.bottom = 'inherit';
  1653. this.container.style.zIndex = 'inherit';
  1654. this.container.style.background = this._videoBackground
  1655. this._videoBackground = 'inherit'
  1656. this._cssfullscreenchange();
  1657. }
  1658. }
  1659. },
  1660. enumerable:false
  1661. })
  1662. if ("object" == typeof exports && "undefined" != typeof module) module.exports = YBPlayer;
  1663. else if ("function" == typeof define && define.amd) define([], YBPlayer);
  1664. else {
  1665. var t;
  1666. t = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : this, t.YBPlayer = YBPlayer
  1667. }
  1668. })();