github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/public/libs/abplayer/js/ABPlayer.js (about) 1 var ABP = { 2 "version":"0.8.0" 3 }; 4 5 (function(){ 6 "use strict"; 7 if(!ABP) return; 8 var $ = function (e) { return document.getElementById(e); }; 9 var _ = function (type, props, children, callback) { 10 var elem = null; 11 if (type === "text") { 12 return document.createTextNode(props); 13 } else { 14 elem = document.createElement(type); 15 } 16 for(var n in props){ 17 if(n !== "style" && n !== "className"){ 18 elem.setAttribute(n, props[n]); 19 }else if(n === "className"){ 20 elem.className = props[n]; 21 }else{ 22 for(var x in props.style){ 23 elem.style[x] = props.style[x]; 24 } 25 } 26 } 27 if (children) { 28 for(var i = 0; i < children.length; i++){ 29 if(children[i] != null) 30 elem.appendChild(children[i]); 31 } 32 } 33 if (callback && typeof callback === "function") { 34 callback(elem); 35 } 36 return elem; 37 }; 38 var addClass = function(elem, className){ 39 if(elem == null) return; 40 var oldClass = elem.className.split(" "); 41 if(oldClass.indexOf(className) < 0){ 42 oldClass.push(className); 43 } 44 elem.className = oldClass.join(" "); 45 }; 46 var hasClass = function(elem, className){ 47 if(elem == null) return false; 48 var oldClass = elem.className.split(" "); 49 return oldClass.indexOf(className) >= 0; 50 } 51 var removeClass = function(elem, className){ 52 if(elem == null) return; 53 var oldClass = elem.className.split(" "); 54 if(oldClass.indexOf(className) >= 0){ 55 oldClass.splice(oldClass.indexOf(className),1); 56 } 57 elem.className = oldClass.join(" "); 58 }; 59 var buildFromDefaults = function (n, d){ 60 var r = {}; 61 for(var i in d){ 62 if(n && typeof n[i] !== "undefined") 63 r[i] = n[i]; 64 else 65 r[i] = d[i]; 66 } 67 return r; 68 } 69 70 71 ABP.create = function (element, params) { 72 var elem = element; 73 if(!params){ 74 params = {}; 75 } 76 params = buildFromDefaults(params,{ 77 "replaceMode":true, 78 "width":512, 79 "height":384, 80 "src":"", 81 "mobile":false 82 }); 83 if (typeof element === "string") { 84 elem = $(element); 85 } 86 // 'elem' is the parent container in which we create the player. 87 if(!hasClass(elem, "ABP-Unit")){ 88 // Assuming we are injecting 89 var container = _("div", { 90 "className": "ABP-Unit", 91 "style":{ 92 "width": params.width + "px", 93 "height": params.height + "px" 94 } 95 }); 96 elem.appendChild(container); 97 }else{ 98 container = elem; 99 } 100 // Create the innards if empty 101 if(container.children.length > 0 && params.replaceMode){ 102 container.innerHTML = ""; 103 } 104 var playlist = []; 105 var danmaku = []; 106 if(typeof params.src === "string"){ 107 params.src = _("video",{ 108 "autobuffer":"true", 109 "dataSetup": "{}", 110 },[ 111 _("source",{ 112 "src":params.src 113 }) 114 ]); 115 playlist.push(params.src); 116 }else if(params.src.hasOwnProperty("playlist")){ 117 var data = params.src; 118 var plist = data.playlist; 119 for(var id = 0; id < plist.length; id++){ 120 if(plist[id].hasOwnProperty("sources")){ 121 var sources = []; 122 for(var mime in plist[id]["sources"]){ 123 sources.push(_("source", { 124 "src":plist[id][mime], 125 "type":mime 126 })); 127 } 128 playlist.push(_("video",{ 129 "autobuffer":"true", 130 "dataSetup": "{}", 131 },sources)); 132 }else if(plist[id].hasOwnProperty("video")){ 133 playlist.push(plist[id]["video"]); 134 }else{ 135 console.log("No recognized format"); 136 } 137 danmaku.push(plist[id]["comments"]); 138 } 139 }else{ 140 playlist.push(params.src); 141 } 142 container.appendChild(_("div",{ 143 "className" : "ABP-Video", 144 "tabindex" : "10" 145 }, [_("div", { 146 "className":"ABP-Container" 147 }), 148 playlist[0] 149 ])); 150 container.appendChild(_("div", { 151 "className":"ABP-Text", 152 },[ 153 _("input", { 154 "type":"text" 155 }) 156 ])); 157 container.appendChild(_("div", { 158 "className":"ABP-Control" 159 },[ 160 _("div", { 161 "className": "button ABP-Play" 162 }), 163 _("div", { 164 "className": "progress-bar" 165 },[ 166 _("div", { 167 "className": "bar dark" 168 }), 169 _("div", { 170 "className": "bar" 171 }) 172 ]), 173 _("div", { 174 "className": "button ABP-CommentShow" 175 }), 176 _("div", { 177 "className": "button ABP-FullScreen" 178 }) 179 ])); 180 var bind = ABP.bind(container, params.mobile); 181 if(playlist.length > 0){ 182 var currentVideo = playlist[0]; 183 bind.gotoNext = function(){ 184 var index = playlist.indexOf(currentVideo) + 1; 185 if(index < playlist.length){ 186 currentVideo = playlist[index]; 187 currentVideo.style.display = ""; 188 var container = bind.video.parentNode; 189 container.removeChild(bind.video); 190 container.appendChild(currentVideo); 191 bind.video.style.display = "none"; 192 bind.video = currentVideo; 193 bind.swapVideo(currentVideo); 194 currentVideo.addEventListener("ended", function(){ 195 bind.gotoNext(); 196 }); 197 } 198 if(index < danmaku.length && danmaku[index] !== null){ 199 CommentLoader(danmaku[index], bind.cmManager); 200 } 201 } 202 currentVideo.addEventListener("ended", function(){ 203 bind.gotoNext(); 204 }); 205 CommentLoader(danmaku[0], bind.cmManager); 206 } 207 return bind; 208 } 209 210 ABP.load = function (inst, videoProvider, commentProvider, commentReceiver){ 211 // 212 }; 213 214 ABP.bind = function (playerUnit, mobile, state) { 215 var ABPInst = { 216 btnPlay:null, 217 barTime:null, 218 barLoad:null, 219 divComment:null, 220 btnFull:null, 221 btnDm:null, 222 video:null, 223 divTextField:null, 224 txtText:null, 225 cmManager:null, 226 defaults:{ 227 w:0, 228 h:0 229 }, 230 state:buildFromDefaults(state, { 231 fullscreen: false, 232 commentVisible: true, 233 allowRescale: false, 234 autosize: false 235 }), 236 createPopup:function(text, delay){ 237 if(playerUnit.hasPopup === true) 238 return false; 239 var p = _("div", { 240 "className":"ABP-Popup" 241 },[_("text",text)]); 242 p.remove = function(){ 243 if(p.isRemoved) return; 244 p.isRemoved = true; 245 playerUnit.removeChild(p); 246 playerUnit.hasPopup = false; 247 }; 248 playerUnit.appendChild(p); 249 playerUnit.hasPopup = true; 250 if(typeof delay === "number"){ 251 setTimeout(function(){ 252 p.remove(); 253 },delay); 254 } 255 return p; 256 }, 257 removePopup:function(){ 258 var pops = playerUnit.getElementsByClassName("ABP-Popup"); 259 for(var i = 0; i < pops.length; i++){ 260 if(pops[i].remove != null){ 261 pops[i].remove(); 262 }else{ 263 pops[i].parentNode.removeChild(pops[i]); 264 } 265 } 266 playerUnit.hasPopup = false; 267 }, 268 swapVideo: null 269 }; 270 ABPInst.swapVideo = function(video){ 271 video.addEventListener("timeupdate", function(){ 272 if(!dragging) 273 ABPInst.barTime.style.width = ((video.currentTime / video.duration) * 100) + "%"; 274 }); 275 video.addEventListener("ended", function(){ 276 ABPInst.btnPlay.className = "button ABP-Play"; 277 ABPInst.barTime.style.width = "0%"; 278 }); 279 video.addEventListener("progress",function(){ 280 if(this.buffered != null){ 281 try{ 282 var s = this.buffered.start(0); 283 var e = this.buffered.end(0); 284 }catch(err){ 285 return; 286 } 287 var dur = this.duration; 288 var perc = (e/dur) * 100; 289 ABPInst.barLoad.style.width = perc + "%"; 290 } 291 }); 292 video.addEventListener("loadedmetadata", function(){ 293 if(this.buffered != null){ 294 try{ 295 var s = this.buffered.start(0); 296 var e = this.buffered.end(0); 297 }catch(err){ 298 return; 299 } 300 var dur = this.duration; 301 var perc = (e/dur) * 100; 302 ABPInst.barLoad.style.width = perc + "%"; 303 } 304 }); 305 video.isBound = true; 306 var lastPosition = 0; 307 if(ABPInst.cmManager){ 308 ABPInst.cmManager.clear(); 309 video.addEventListener("progress", function(){ 310 if(lastPosition == video.currentTime){ 311 video.hasStalled = true; 312 ABPInst.cmManager.stopTimer(); 313 }else 314 lastPosition = video.currentTime; 315 }); 316 if(window){ 317 window.addEventListener("resize", function(){ 318 //Notify on resize 319 ABPInst.cmManager.setBounds(); 320 }); 321 } 322 video.addEventListener("timeupdate", function(){ 323 if(ABPInst.cmManager.display === false) return; 324 if(video.hasStalled){ 325 ABPInst.cmManager.startTimer(); 326 video.hasStalled = false; 327 } 328 ABPInst.cmManager.time(Math.floor(video.currentTime * 1000)); 329 }); 330 video.addEventListener("play", function(){ 331 ABPInst.cmManager.startTimer(); 332 try{ 333 var e = this.buffered.end(0); 334 var dur = this.duration; 335 var perc = (e/dur) * 100; 336 ABPInst.barLoad.style.width = perc + "%"; 337 }catch(err){} 338 }); 339 video.addEventListener("ratechange", function(){ 340 if(ABPInst.cmManager.def.globalScale != null){ 341 if(video.playbackRate !== 0){ 342 ABPInst.cmManager.def.globalScale = (1 / video.playbackRate); 343 ABPInst.cmManager.rescale(); 344 } 345 } 346 }); 347 video.addEventListener("pause", function(){ 348 ABPInst.cmManager.stopTimer(); 349 }); 350 video.addEventListener("waiting", function(){ 351 ABPInst.cmManager.stopTimer(); 352 }); 353 video.addEventListener("playing",function(){ 354 ABPInst.cmManager.startTimer(); 355 }); 356 } 357 } 358 359 if(playerUnit === null || playerUnit.getElementsByClassName === null) return; 360 ABPInst.defaults.w = playerUnit.offsetWidth; 361 ABPInst.defaults.h = playerUnit.offsetHeight; 362 var _v = playerUnit.getElementsByClassName("ABP-Video"); 363 if(_v.length <= 0) return; 364 var video = null; 365 for(var i in _v[0].children){ 366 if(_v[0].children[i].tagName != null && 367 _v[0].children[i].tagName.toUpperCase() === "VIDEO"){ 368 video = _v[0].children[i]; 369 break; 370 } 371 } 372 if(_v[0] && mobile){ 373 _v[0].style.bottom="0px"; 374 } 375 var cmtc = _v[0].getElementsByClassName("ABP-Container"); 376 if(cmtc.length > 0) 377 ABPInst.divComment = cmtc[0]; 378 if(video === null) return; 379 ABPInst.video = video; 380 /** Bind the Play Button **/ 381 var _p = playerUnit.getElementsByClassName("ABP-Play"); 382 if(_p.length <= 0) return; 383 ABPInst.btnPlay = _p[0]; 384 /** Bind the Loading Progress Bar **/ 385 var pbar = playerUnit.getElementsByClassName("progress-bar"); 386 if(pbar.length <= 0) return; 387 ABPInst.barHitArea = pbar[0]; 388 var pbars = pbar[0].getElementsByClassName("bar"); 389 ABPInst.barTime = pbars[0]; 390 ABPInst.barLoad = pbars[1]; 391 /** Bind the FullScreen button **/ 392 var fbtn = playerUnit.getElementsByClassName("ABP-FullScreen"); 393 if(fbtn.length <= 0) return; 394 ABPInst.btnFull = fbtn[0]; 395 /** Bind the TextField **/ 396 var txtf = playerUnit.getElementsByClassName("ABP-Text"); 397 if(txtf.length > 0){ 398 ABPInst.divTextField = txtf[0]; 399 var txti = txtf[0].getElementsByTagName("input"); 400 if(txti.length > 0) 401 ABPInst.txtText = txti[0]; 402 } 403 /** Bind the Comment Disable button **/ 404 var cmbtn = playerUnit.getElementsByClassName("ABP-CommentShow"); 405 if(cmbtn.length > 0){ 406 ABPInst.btnDm = cmbtn[0]; 407 } 408 /** Create a commentManager if possible **/ 409 if(typeof CommentManager !== "undefined"){ 410 ABPInst.cmManager = new CommentManager(ABPInst.divComment); 411 ABPInst.cmManager.display = true; 412 ABPInst.cmManager.init(); 413 ABPInst.cmManager.clear(); 414 if(window){ 415 window.addEventListener("resize", function(){ 416 //Notify on resize 417 ABPInst.cmManager.setBounds(); 418 }); 419 } 420 } 421 /** Bind mobile **/ 422 if(mobile){ 423 // Controls 424 var controls = playerUnit.getElementsByClassName("ABP-Control"); 425 if(controls.length > 0){ 426 ABPInst.controlBar = controls[0]; 427 } 428 var timer = -1; 429 var hideBar = function(){ 430 ABPInst.controlBar.style.display = "none"; 431 ABPInst.divTextField.style.display = "none"; 432 ABPInst.divComment.style.bottom = "0px"; 433 ABPInst.cmManager.setBounds(); 434 }; 435 ABPInst.divComment.style.bottom = 436 (ABPInst.controlBar.offsetHeight + ABPInst.divTextField.offsetHeight) + "px"; 437 var listenerMove = function(){ 438 ABPInst.controlBar.style.display = ""; 439 ABPInst.divTextField.style.display = ""; 440 ABPInst.divComment.style.bottom = 441 (ABPInst.controlBar.offsetHeight + ABPInst.divTextField.offsetHeight) + "px"; 442 try{ 443 if (timer != -1){ 444 clearInterval(timer); 445 timer = -1; 446 } 447 timer = setInterval(function(){ 448 if(document.activeElement !== ABPInst.txtText){ 449 hideBar(); 450 clearInterval(timer); 451 timer = -1; 452 } 453 }, 2500); 454 } catch(e){ 455 console.log(e); 456 } 457 }; 458 playerUnit.addEventListener("touchmove",listenerMove); 459 playerUnit.addEventListener("mousemove",listenerMove); 460 timer = setTimeout(function(){ 461 hideBar(); 462 }, 4000); 463 } 464 if(video.isBound !== true){ 465 ABPInst.swapVideo(video); 466 ABPInst.btnFull.addEventListener("click", function(){ 467 ABPInst.state.fullscreen = hasClass(playerUnit, "ABP-FullScreen"); 468 if(!ABPInst.state.fullscreen){ 469 addClass(playerUnit, "ABP-FullScreen"); 470 }else{ 471 removeClass(playerUnit, "ABP-FullScreen"); 472 } 473 ABPInst.state.fullscreen = !ABPInst.state.fullscreen; 474 if(ABPInst.cmManager) 475 ABPInst.cmManager.setBounds(); 476 if(!ABPInst.state.allowRescale) return; 477 if(ABPInst.state.fullscreen){ 478 if(ABPInst.defaults.w >0){ 479 ABPInst.cmManager.def.scrollScale = playerUnit.offsetWidth / ABPInst.defaults.w; 480 } 481 }else{ 482 ABPInst.cmManager.def.scrollScale = 1; 483 } 484 }); 485 ABPInst.btnDm.addEventListener("click", function(){ 486 if(ABPInst.cmManager.display == false){ 487 ABPInst.cmManager.display = true; 488 ABPInst.cmManager.startTimer(); 489 }else{ 490 ABPInst.cmManager.display = false; 491 ABPInst.cmManager.clear(); 492 ABPInst.cmManager.stopTimer(); 493 } 494 }); 495 ABPInst.barTime.style.width = "0%"; 496 var dragging = false; 497 ABPInst.barHitArea.addEventListener("mousedown", function(e){ 498 dragging = true; 499 }); 500 document.addEventListener("mouseup", function(e){ 501 dragging = false; 502 }); 503 ABPInst.barHitArea.addEventListener("mouseup", function(e){ 504 dragging = false; 505 var newTime = ((e.layerX) / this.offsetWidth) * ABPInst.video.duration; 506 if(Math.abs(newTime - ABPInst.video.currentTime) > 4){ 507 if(ABPInst.cmManager) 508 ABPInst.cmManager.clear(); 509 } 510 ABPInst.video.currentTime = newTime; 511 }); 512 ABPInst.barHitArea.addEventListener("mousemove", function(e){ 513 if(dragging){ 514 ABPInst.barTime.style.width =((e.layerX) * 100 / this.offsetWidth) + "%"; 515 } 516 }); 517 ABPInst.btnPlay.addEventListener("click", function(){ 518 if(ABPInst.video.paused){ 519 ABPInst.video.play(); 520 this.className = "button ABP-Play ABP-Pause"; 521 }else{ 522 ABPInst.video.pause(); 523 this.className = "button ABP-Play"; 524 } 525 }); 526 playerUnit.addEventListener("keydown", function(e){ 527 if(e && e.keyCode == 32 && document.activeElement !== ABPInst.txtText){ 528 ABPInst.btnPlay.click(); 529 e.preventDefault(); 530 } 531 }); 532 playerUnit.addEventListener("touchmove", function(e){ 533 event.preventDefault(); 534 }); 535 var _touch = null; 536 playerUnit.addEventListener("touchstart", function(e){ 537 if(e.targetTouches.length > 0) { 538 //Determine whether we want to start or stop 539 _touch = e.targetTouches[0]; 540 } 541 }); 542 playerUnit.addEventListener("touchend", function(e){ 543 if(e.changedTouches.length > 0) { 544 if(_touch != null){ 545 var diffx = e.changedTouches[0].pageX - _touch.pageX; 546 var diffy = e.changedTouches[0].pageY - _touch.pageY; 547 if(Math.abs(diffx) < 20 && Math.abs(diffy) < 20){ 548 _touch = null; 549 return; 550 } 551 if(Math.abs(diffx) > 3 * Math.abs(diffy)){ 552 if(diffx > 0) { 553 if(ABPInst.video.paused){ 554 ABPInst.btnPlay.click(); 555 } 556 } else { 557 if(!ABPInst.video.paused){ 558 ABPInst.btnPlay.click(); 559 } 560 } 561 } else if (Math.abs(diffy) > 3 * Math.abs(diffx)) { 562 if(diffy < 0){ 563 ABPInst.video.volume = Math.min(1,ABPInst.video.volume + 0.1) 564 }else{ 565 ABPInst.video.volume = Math.max(0,ABPInst.video.volume - 0.1) 566 } 567 } 568 _touch = null; 569 } 570 } 571 }); 572 573 } 574 /** Bind command interface **/ 575 if(ABPInst.txtText !== null){ 576 ABPInst.txtText.addEventListener("keyup", function(k){ 577 if(this.value == null) return; 578 if(/^!/.test(this.value)){ 579 this.style.color = "#5DE534"; 580 }else{ 581 this.style.color = ""; 582 } 583 if(k != null && k.keyCode === 13){ 584 if(this.value == "") return; 585 if(/^!/.test(this.value)){ 586 /** Execute command **/ 587 var commandPrompts = this.value.substring(1).split(":"); 588 var command = commandPrompts.shift(); 589 switch (command){ 590 case "help":{ 591 var popup = ABPInst.createPopup("提示信息:",2000); 592 }break; 593 case "speed": 594 case "rate": 595 case "spd":{ 596 if(commandPrompts.length < 1){ 597 ABPInst.createPopup("速度调节:输入百分比【 1% - 300% 】", 2000); 598 }else{ 599 var pct = parseInt(commandPrompts[0]); 600 if(pct != NaN){ 601 var percentage = Math.min(Math.max(pct, 1), 300); 602 ABPInst.video.playbackRate = percentage / 100; 603 } 604 if(ABPInst.cmManager !== null){ 605 ABPInst.cmManager.clear(); 606 } 607 } 608 }break; 609 case "off":{ 610 ABPInst.cmManager.display = false; 611 ABPInst.cmManager.clear(); 612 ABPInst.cmManager.stopTimer(); 613 }break; 614 case "on":{ 615 ABPInst.cmManager.display = true; 616 ABPInst.cmManager.startTimer(); 617 }break; 618 case "cls": 619 case "clear":{ 620 if(ABPInst.cmManager !== null){ 621 ABPInst.cmManager.clear(); 622 } 623 }break; 624 case "pp": 625 case "pause":{ 626 ABPInst.video.pause(); 627 }break; 628 case "p": 629 case "play":{ 630 ABPInst.video.play(); 631 }break; 632 case "vol": 633 case "volume":{ 634 if(commandPrompts.length == 0){ 635 var popup = ABPInst.createPopup("目前音量:" + 636 Math.round(ABPInst.video.volume * 100) + "%", 2000); 637 }else{ 638 var precVolume = parseInt(commandPrompts[0]); 639 if(precVolume !== null && precVolume !== NaN){ 640 ABPInst.video.volume = Math.max(Math.min(precVolume, 100),0) / 100; 641 } 642 ABPInst.createPopup("目前音量:" + 643 Math.round(ABPInst.video.volume * 100) + "%", 2000); 644 } 645 }break; 646 default:break; 647 } 648 this.value = ""; 649 } 650 }else if(k != null && k.keyCode === 38){ 651 if(!k.shiftKey){ 652 /** Volume up **/ 653 ABPInst.video.volume = Math.round(Math.min((ABPInst.video.volume * 100) + 5, 100)) / 100; 654 ABPInst.removePopup(); 655 var p = ABPInst.createPopup("目前音量:" + 656 Math.round(ABPInst.video.volume * 100) + "%", 800); 657 }else{ 658 if(ABPInst.cmManager !== null){ 659 var opa = Math.min(Math.round(ABPInst.cmManager.def.opacity * 100) + 5,100); 660 ABPInst.cmManager.def.opacity = opa / 100; 661 ABPInst.removePopup(); 662 var p = ABPInst.createPopup("弹幕透明度:" + Math.round(opa) + "%",800); 663 } 664 } 665 }else if(k != null && k.keyCode === 40){ 666 if(!k.shiftKey){ 667 /** Volume Down **/ 668 ABPInst.video.volume = Math.round(Math.max((ABPInst.video.volume * 100) - 5, 0)) / 100; 669 ABPInst.removePopup(); 670 var p = ABPInst.createPopup("目前音量:" + 671 Math.round(ABPInst.video.volume * 100) + "%", 800); 672 }else{ 673 if(ABPInst.cmManager !== null){ 674 var opa = Math.max(Math.round(ABPInst.cmManager.def.opacity * 100) - 5,0); 675 ABPInst.cmManager.def.opacity = opa / 100; 676 ABPInst.removePopup(); 677 var p = ABPInst.createPopup("弹幕透明度:" + Math.round(opa) + "%",800); 678 } 679 } 680 } 681 }); 682 } 683 /** Create a bound CommentManager if possible **/ 684 if(typeof CommentManager !== "undefined"){ 685 if(ABPInst.state.autosize){ 686 var autosize = function(){ 687 if(video.videoHeight === 0 || video.videoWidth === 0){ 688 return; 689 } 690 var aspectRatio = video.videoHeight / video.videoWidth; 691 // We only autosize within the bounds 692 var boundW = playerUnit.offsetWidth; 693 var boundH = playerUnit.offsetHeight; 694 var oldASR = boundH / boundW; 695 696 if(oldASR < aspectRatio){ 697 playerUnit.style.width = (boundH / aspectRatio) + "px"; 698 playerUnit.style.height = boundH + "px"; 699 }else{ 700 playerUnit.style.width = boundW + "px"; 701 playerUnit.style.height = (boundW * aspectRatio) + "px"; 702 } 703 704 ABPInst.cmManager.setBounds(); 705 }; 706 video.addEventListener("loadedmetadata", autosize); 707 autosize(); 708 } 709 } 710 return ABPInst; 711 } 712 })()