Widget:BilibiliVideo:修订间差异

H萌娘,万物皆可H的百科全书!
跳到导航 跳到搜索
imported>=海豚=
无编辑摘要
(fix)
 
(未显示1个用户的18个中间版本)
第1行: 第1行:
<noinclude>{{BilibiliVideo/doc/copyright}}
<noinclude>{{BilibiliVideo/doc/copyright}}
'''本Widget不能单独使用''',请使用{{tl|BilibiliVideo}}!</noinclude><includeonly>
'''本Widget不能单独使用''',请使用{{tl|BilibiliVideo}}!</noinclude><includeonly><!--{if !isset($wgBilibili) || !$wgBilibili}--><!--{assign var="wgBilibili" value=true scope="global"}--><style>
<!--{if !isset($wgBilibili) || !$wgBilibili}-->
<!--{assign var="wgBilibili" value=true scope="global"}-->
<style>
.bilibili-video-container {
.bilibili-video-container {
    border: 1px solid rgba(170,170,170,0.37);
    border: 1px solid rgba(170,170,170,0.37);
第111行: 第108行:
</style><script>
</style><script>
"use strict";
"use strict";
window.RLQ.push(() => {
window.addEventListener('jquery-ready', () => {
   const errMsg = {
     id: '此处填写的id有误,请参考<a href="https://zh.moegirl.org.cn/Template:BilibiliVideo#firstHeading" target="_blank">模板文档</a>修正……',
     error: "执行出现问题,请复制以下内容并在提问求助区处粘贴寻求帮助:$$$",
     attr: '下方填写的参数 $$$ 有误,请参考<a href="https://zh.moegirl.org.cn/Template:BilibiliVideo#firstHeading" target="_blank">模板文档</a>修正……',
   };
   const sanNode = $(`<${"span/"}>`);
   const genErr = (type, msg = "") => type in errMsg ? `<${"div"} style="font-style: italic; border: 1px dashed red;">BilibiliVideo模板:${errMsg[type].replace("$$$", sanNode.text(msg).html())}<${"/div"}>` : "";
   const injectErrMsgBefore = ($ele, type, msg = "") => $ele.before(genErr(type, msg));
    try {
    try {
      const isNaN = Number.isNaN || window.isNaN;
      const isNaN = Number.isNaN || window.isNaN;
     const temp = new Set();
      const cssLengthUnitValidator = (length, defaultValue, callback, paramName, $ele) => {
      const cssLengthUnitValidator = (length, defaultValue, callback) => {
        if (typeof length !== "string" || length.length === 0) {
        if (typeof length !== "string" || length.length === 0) {
          callback(false);
          callback(false);
第123行: 第127行:
        if (isNaN(parsedNumber) || parsedNumber <= 0) {
        if (isNaN(parsedNumber) || parsedNumber <= 0) {
          callback(false);
          callback(false);
         injectErrMsgBefore($ele, "attr", paramName);
          return defaultValue;
          return defaultValue;
        }
        }
第134行: 第139行:
        }
        }
        callback(false);
        callback(false);
       injectErrMsgBefore($ele, "attr", paramName);
        return defaultValue;
        return defaultValue;
      };
      };
      const converter = new class Converter {
      const fixedNumber = (number) => `${+number < 10 ? "0" : ""}${number}`;
       constructor() {
     const secondsParser = (seconds) => `${Math.floor(+seconds / 60)}:${fixedNumber(+seconds % 60)}`;
         this._base58Table = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF";
     const idCorrector = (id) => {
         this._digitMap = [11, 10, 3, 8, 4, 6];
       if (/^(?:av)?\d{1,9}$/i.test(id)) {
         this._xor = 177451812;
          return {
         this._add = 8728348608;
           id: id.replace(/^av/i, ""),
         this._aidRegExp = /(?:av)\d{1,9}/ig;
           prefix: {
         this._bvidRegExp = /(?:[bB][vV])?1?[fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF]{9}/g;
             href: "av",
          this._bvidTemplate = ["B", "V", "1", "", "", "4", "", "1", "", "7", "", ""];
             iframe: "aid",
       }
           },
       _bvTobvid(bv) {
          };
         if (bv.length === 12) {
       } else if (/^(?:(?:[bB][vV])?1)?[fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF]{9}$/.test(id)
           return bv;
          && /4.1.7..$/.test(id)) {
          } else if (bv.length === 10) {
          return {
           return `BV${bv}`;
           id: id.replace(/^.*([fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF]{9})$/i, "1$1"),
         } else if (bv.length === 9) {
           prefix: {
           return `BV1${bv}`;
             href: "BV",
         }
             iframe: "bvid",
         throw new Error("BV's length must be 9, 10 or 12");
            },
       }
          };
       _bvidToAid(bvid) {
         let r = 0;
         for (let i = 0; i < 6; i++) {
           r += this._base58Table.indexOf(bvid[this._digitMap[i]]) * 58 ** i;
         }
         return `av${r - this._add ^ this._xor}`;
       }
       bvidToAid(str) {
          return str.replace(this._bvidRegExp, (bv) => {
           return this._bvidToAid(this._bvTobvid(bv));
         });
       }
       _avToAid(av) {
         if (/^av/i.test(av)) {
           return av;
         }
          return `av${av}`;
       }
       _aidToBvid(aid) {
         const av = (+aid.replace(/^av/g, "") ^ this._xor) + this._add;
         const bvidClone = Array.from(this._bvidTemplate);
         for (let i = 0; i < 6; i++) {
           bvidClone[this._digitMap[i]] = this._base58Table[Math.floor(av / 58 ** i) % 58];
         }
         return bvidClone.join("");
       }
       aidToBvid(str) {
         return str.replace(this._aidRegExp, (av) => {
            return this._aidToBvid(this._avToAid(av));
          });
        }
        }
       return false;
      };
      };
      if (mw.config.get("skin") === "minerva") {
      if (mw.config.get("skin") === "minerva") {
第194行: 第171行:
          element.addClass("bilibili-video-initialized");
          element.addClass("bilibili-video-initialized");
          const _id = dataset.id,
          const _id = dataset.id,
           id = _id.replace(/^[ab]v/i, ""),
            title = dataset.title,
            title = dataset.title,
            pagename = dataset.pagename,
            pagename = dataset.pagename,
第201行: 第177行:
            subtitle = dataset.subtitle === "true" ? true : false;
            subtitle = dataset.subtitle === "true" ? true : false;
          let page = parseInt(dataset.page);
          let page = parseInt(dataset.page);
          if (isNaN(page) || page < 1) { page = 1; }
          if (isNaN(page) || page < 1) {
         let prefix;
           page = 1;
         let decode = null;
           if (typeof dataset.page === "string" && dataset.page !== "") {
         if (/^(?:av)?\d{1,9}$/i.test(_id)) {
              injectErrMsgBefore(element, "attr", "page");
           prefix = {
             href: "av",
             iframe: "aid",
           };
         } else if (/^(?:bv)?[\da-z]{10}$/i.test(_id)) {
           prefix = {
              href: "BV",
             iframe: "bvid",
           };
           if (!converter._bvidRegExp.test(_id)) {
             temp.add(_id);
           } else {
             decode = converter.bvidToAid(_id);
            }
            }
         }
         if ((isNaN(t) || t <= 0) && typeof dataset.t === "string" && dataset.t !== "") {
           injectErrMsgBefore(element, "attr", "t");
         }
         const validation = idCorrector(_id);
         let id,
           prefix;
         if (validation) {
           id = validation.id;
           prefix = validation.prefix;
          } else {
          } else {
            if (/^(?:av)?\d{10,}$/i.test(_id)) {
            ele.outerHTML = genErr("id");
             temp.add(_id);
            return;
           }
            return ele.outerHTML = "<i>id错误</i>";
          }
          }
          ele.innerText = "正在加载中,若长时间空白则说明是网络问题……";
          ele.innerText = "正在加载中,若长时间空白则说明是网络问题……";
          $.ajax({
          $.ajax({
            url: `https://mgwbcprd.azureedge.net/BilibiliMeta/Index/${encodeURIComponent(typeof decode === "string" ? decode : prefix.href + id)}`,
            url: `https://api.bilibili.com/x/web-interface/view?${prefix.iframe}=${id}&jsonp=jsonp`,
            type: "GET",
            type: "GET",
           dataType: "jsonp",
            timeout: 10000,
            timeout: 10000,
            success: function (data) {
            success: function ({ code, message, data }) {
              const list = data.VideoEntities
              if (code !== 0) {
                .map((e, i) => {
                element.before($("<a/>").addClass("bilibili-video-button").attr("rel", "nofollow noreferrer noopener").attr("href", `https://www.bilibili.com/video/${prefix.href}${id}?p=${page}${tIsInvalid ? "" : `&t=${t}`}`).text((title || prefix.href + id) + (![0, 1].includes(page) && !isNaN(page) ? ` (P${page})` : ""))).remove();
                 e.page = i + 1;
               console.info("Widget:BilibiliVideo", `${prefix.href}${id}`, code, message);
                 e.title = e.Title.replace(/^\d+、/, "");
               return;
                 return e;
             }
               });
             const list = data.pages;
              let _page = 1;
              let _page = 1;
              const name = title || (data.Title ? data.Title : prefix.href + id);
              const name = title || (data.title ? data.title : prefix.href + id);
              let index;
              let index;
              let length;
              let length;
              if (pagename) {
              if (pagename) {
                for (index = 0, length = list.length; index < length; index++) {
                for (index = 0, length = list.length; index < length; index++) {
                  if (list[index].Title !== pagename && list[index].title !== pagename) { continue; }
                  if (list[index].part !== pagename) { continue; }
                  _page = list[index].page;
                  _page = list[index].page;
                  break;
                  break;
第249行: 第221行:
              } else { _page = page; }
              } else { _page = page; }
              index = _page - 1;
              index = _page - 1;
             let sec = `${t % 60}`;
              const time = secondsParser(t);
             if (sec.length === 1) { sec = `0${sec}`; }
              const button = $("<a/>").addClass("bilibili-video-button").attr("rel", "nofollow noreferrer noopener").attr("href", `https://www.bilibili.com/video/${prefix.href}${id}?p=${_page}${tIsInvalid ? "" : `&t=${t}`}`).text(`${name} [${_page}/${secondsParser(list[index].duration)}]${tIsInvalid ? "" : `[跳转至${time}]`}`);
              const time = `${Math.floor(t / 60)}:${sec}`;
              if (list[index] !== undefined && list[index].cid !== undefined && subtitle) {
              const button = $("<a/>").addClass("bilibili-video-button").attr("rel", "nofollow noreferrer noopener").attr("href", `https://www.bilibili.com/video/${prefix.href}${id}?p=${_page}${tIsInvalid ? "" : `&t=${t}`}`).text(`${name} [${_page}/${list.length}]${tIsInvalid ? "" : `[跳转至${time}]`}`);
                button.append(`<br>(${_page}、${list[index].part})`);
              if (list[index] !== undefined && list[index].VideoCid !== undefined && subtitle) {
                button.append(`<br>(${_page}、${list[index].Title})`);
              }
              }
              element.before(button).remove();
              element.before(button).remove();
            },
            },
            error: function () {
            error: function () {
              element.before($("<a/>").addClass("bilibili-video-button").attr("rel", "nofollow noreferrer noopener").attr("href", `https://www.bilibili.com/video/${prefix.href}${id}?p=${page}${tIsInvalid ? "" : `&t=${t}`}`).text((title || prefix.href + id) + ([0, 1].indexOf(page) !== -1 && !isNaN(page) ? ` (P${page})` : ""))).remove();
              element.before($("<a/>").addClass("bilibili-video-button").attr("rel", "nofollow noreferrer noopener").attr("href", `https://www.bilibili.com/video/${prefix.href}${id}?p=${page}${tIsInvalid ? "" : `&t=${t}`}`).text((title || prefix.href + id) + (![0, 1].includes(page) && !isNaN(page) ? ` (P${page})` : ""))).remove();
            },
            },
          });
          });
第325行: 第295行:
            const dataset = ele.dataset,
            const dataset = ele.dataset,
              _id = dataset.id,
              _id = dataset.id,
             id = _id.replace(/^[ab]v/i, ""),
              selfbox = $(ele);
              selfbox = $(ele);
            let prefix;
            const validation = idCorrector(_id);
            let decode = null;
            let id,
           if (/^(?:av)?\d{1,9}$/i.test(_id)) {
              prefix;
              prefix = {
            if (validation) {
               href: "av",
              id = validation.id;
               iframe: "aid",
              prefix = validation.prefix;
             };
            } else if (/^(?:bv)?[\da-z]{10}$/i.test(_id)) {
              prefix = {
               href: "BV",
               iframe: "bvid",
             };
             if (!converter._bvidRegExp.test(_id)) {
               temp.add(_id);
              } else {
               decode = converter.bvidToAid(_id);
             }
            } else {
            } else {
              if (/^(?:av)?\d{10,}$/i.test(_id)) {
              ele.outerHTML = genErr("id");
                temp.add(_id);
             return;
           }
           let page = parseInt(+(dataset.page || 1));
           if (isNaN(page) || page < 1) {
             page = 1;
             if (typeof dataset.page === "string" && dataset.page !== "") {
                injectErrMsgBefore(selfbox, "attr", "page");
              }
              }
             return ele.outerHTML = "<i>id错误</i>";
            }
            }
           let page = parseInt(+(dataset.page || 1));
           if (isNaN(page) || page < 1) { page = 1; }
            const pagename = dataset.pagename;
            const pagename = dataset.pagename;
            const title = dataset.title;
            const title = dataset.title;
            const height = cssLengthUnitValidator(dataset.height, "441px", (isValidated) => isValidated || selfbox.removeAttr("data-height"));
            const height = cssLengthUnitValidator(dataset.height, "441px", (isValidated) => isValidated || selfbox.removeAttr("data-height"), "height", selfbox);
            const width = cssLengthUnitValidator(dataset.width, "665px", (isValidated) => isValidated || selfbox.removeAttr("data-width"));
            const width = cssLengthUnitValidator(dataset.width, "665px", (isValidated) => isValidated || selfbox.removeAttr("data-width"), "width", selfbox);
            const maxHeight = cssLengthUnitValidator(dataset.maxHeight, undefined, (isValidated) => isValidated || selfbox.removeAttr("data-max-height"));
            const maxHeight = cssLengthUnitValidator(dataset.maxHeight, "100vh", (isValidated) => isValidated || selfbox.removeAttr("data-max-height"), "maxHeight", selfbox);
            const maxWidth = cssLengthUnitValidator(dataset.maxWidth, undefined, (isValidated) => isValidated || selfbox.removeAttr("data-max-width"));
            const maxWidth = cssLengthUnitValidator(dataset.maxWidth, "100%", (isValidated) => isValidated || selfbox.removeAttr("data-max-width"), "maxWidth", selfbox);
            const subtitle = dataset.subtitle === "true" ? true : false;
            const subtitle = dataset.subtitle === "true" ? true : false;
            const t = parseInt(dataset.t);
            const t = parseInt(dataset.t);
第378行: 第339行:
              "max-height": maxHeight,
              "max-height": maxHeight,
            });
            });
            if (!tIsInvalid) { selfbox.removeAttr("data-auto-expand"); }
            if (!tIsInvalid) {
            let sec = `${t % 60}`;
             selfbox.removeAttr("data-auto-expand");
           if (sec.length === 1) { sec = `0${sec}`; }
            } else if (typeof dataset.t === "string" && dataset.t !== "") {
            const time = `${Math.floor(t / 60)}:${sec}`;
             injectErrMsgBefore(selfbox, "attr", "t");
            title_text.text(`${(title || prefix.href + id) + ([0, 1].indexOf(page) === -1 ? ` (${page})` : "") + (tIsInvalid ? "" : `[视频从${time}开始播放]`)} 【视频信息加载中……】`);
           }
            const time = secondsParser(t);
            title_text.text(`${(title || prefix.href + id) + (![0, 1].includes(page) ? ` (P${page})` : "") + (tIsInvalid ? "" : `[视频从${time}开始播放]`)}`);
            iframeContainer.css({
            iframeContainer.css({
              width: width,
              width: width,
第415行: 第378行:
              placeholderToggle(iframe);
              placeholderToggle(iframe);
            });
            });
            window.setTimeout(() => { //异步出去不要卡主线程
            $.ajax({
             $.ajax({
             url: `https://api.bilibili.com/x/web-interface/view?${prefix.iframe}=${id}&jsonp=jsonp`,
               url: `https://mgwbcprd.azureedge.net/BilibiliMeta/Index/${encodeURIComponent(typeof decode === "string" ? decode : prefix.href + id)}`,
             type: "GET",
               type: "GET",
             dataType: "jsonp",
               timeout: 10000,
             timeout: 10000,
               success: function (data) {
             success: function ({ code, message, data }) {
                 const list = data.VideoEntities
               if (code !== 0) {
                   .map((e, i) => {
                  title_text.text((title || prefix.href + id) + (![0, 1].includes(page) ? ` (P${page})` : "") + (tIsInvalid ? "" : `[视频从${time}开始播放]`));
                     e.page = i + 1;
                     e.title = e.Title.replace(/^\d+、/, "");
                     return e;
                   });
                 let _page = 1;
                 const name = title || (data.Title ? data.Title : prefix.href + id);
                 let index;
                 let length;
                 if (pagename) {
                   for (index = 0, length = list.length; index < length; index++) {
                     if (list[index].Title !== pagename && list[index].title !== pagename) { continue; }
                     _page = list[index].page;
                     break;
                   }
                 } else { _page = page; }
                 index = _page - 1;
                 const href = title_text.attr("href");
                 if (list[index] !== undefined && list[index].VideoCid !== undefined) {
                   iframe.attr("data-src", `${iframe_href_base + prefix.iframe}=${id}&page=${_page}${tIsInvalid ? "" : `&t=${t}`}`);
                   title_text.attr("href", href.replace(new RegExp(`\\?p=${page}`, "g"), `?p=${_page}`));
                   title_text.text(`${name} [${_page}/${list.length}]${tIsInvalid ? "" : `[视频从${time}开始播放]`}`);
                   if (subtitle) { title_text.append(`<br>(${_page}、${list[index].Title})`); }
                 } else {
                   title_text.text(name + (tIsInvalid ? "" : `[视频从${time}开始播放]`));
                   iframe.attr("data-src", `${iframe_href_base + prefix.iframe}=${id}&page=${_page}${tIsInvalid ? "" : `&t=${t}`}`);
                 }
                 lazyLoadObserver.observe(iframe[0]);
               },
               error: function (e) {
                  title_text.text((title || prefix.href + id) + ([0, 1].indexOf(page) === -1 ? ` (${page})` : "") + (tIsInvalid ? "" : `[视频从${time}开始播放]`));
                 if (e && e.responseJSON && e.responseJSON.message && e.responseJSON.message === "Authentication is required for accessing this video.") { title_text.parent().append('<sup title="“Bilibili采用会员制,大部分投稿视频会员与游客都可以观看,\n  但部分视频在UP主设定下只有会员才可以观看(这些视频常被称为‘只有会员才知道的世界’)。”\n  - Bilibili#用户制度 @ ZhMoegirl\n在这种情况下我们无法为您解析视频及其分P标题、分P数量等。">(只有会员才知道的世界)</sup>'); }
                  iframe.attr("data-src", `${iframe_href_base + prefix.iframe}=${id}&page=${page}${tIsInvalid ? "" : `&t=${t}`}`);
                  iframe.attr("data-src", `${iframe_href_base + prefix.iframe}=${id}&page=${page}${tIsInvalid ? "" : `&t=${t}`}`);
                  lazyLoadObserver.observe(iframe[0]);
                  lazyLoadObserver.observe(iframe[0]);
                },
                 console.info("Widget:BilibiliVideo", `${prefix.href}${id}`, code, message);
              });
                 return;
            }, 13);
               }
               const list = data.pages;
               let _page = 1;
               const name = title || (data.title ? data.title : prefix.href + id);
               let index;
               let length;
               if (pagename) {
                 for (index = 0, length = list.length; index < length; index++) {
                   if (list[index].part !== pagename) { continue; }
                   _page = list[index].page;
                   break;
                 }
                } else { _page = page; }
               index = _page - 1;
               const href = title_text.attr("href");
               if (list[index] !== undefined && list[index].cid !== undefined) {
                 iframe.attr("data-src", `${iframe_href_base}${prefix.iframe}=${id}&cid=${list[index].cid}&page=${_page}${tIsInvalid ? "" : `&t=${t}`}`);
                 title_text.attr("href", href.replace(new RegExp(`\\?p=${page}`, "g"), `?p=${_page}`));
                 title_text.text(`${name} [${_page}/${list.length}]${tIsInvalid ? "" : `[视频从${time}开始播放]`}`);
                 if (subtitle) { title_text.append(`<br>(${_page}、${list[index].part})`); }
               } else {
                 title_text.text(name + (tIsInvalid ? "" : `[视频从${time}开始播放]`));
                 iframe.attr("data-src", `${iframe_href_base + prefix.iframe}=${id}&page=${_page}${tIsInvalid ? "" : `&t=${t}`}`);
               }
               lazyLoadObserver.observe(iframe[0]);
              },
             error: function () {
               title_text.text((title || prefix.href + id) + (![0, 1].includes(page) ? ` (P${page})` : "") + (tIsInvalid ? "" : `[视频从${time}开始播放]`));
               iframe.attr("data-src", `${iframe_href_base + prefix.iframe}=${id}&page=${page}${tIsInvalid ? "" : `&t=${t}`}`);
               lazyLoadObserver.observe(iframe[0]);
             },
            });
            //toggle
            //toggle
           selfbox.find(".bilibili-toggle").on("click", (_, ele) => {
             const self = $(ele);
             selfbox.width(iframeContainer.outerWidth(true));
             selfbox.toggleClass("onshow");
             iframeContainer.toggle();
             if (self.text() === "显示视频") {
               self.text("隐藏视频");
               $(window).resize();
             } else {
               self.text("显示视频");
               selfbox.removeAttr("style");
             }
           });
            selfbox.find(".bilibili-widescreen").on("click", (_, ele) => {
            selfbox.find(".bilibili-widescreen").on("click", (_, ele) => {
              const self = $(ele);
              const self = $(ele);
第509行: 第459行:
          });
          });
        });
        });
       setTimeout(() => {
         $('.bilibili-video-container.exec[data-auto-expand="true"]').find(".bilibili-toggle").click();
       }, 100);
      }
      }
     setTimeout(async () => {
       if (temp.size > 0 && mw.config.get("wgUserGroups").includes("autoconfirmed")) {
         const raw = await $.get(`https://zh.moegirl.org/Template:BilibiliVideo/bvid?action=raw&ctype=application/json&_=${Math.random()}`);
         let flags = false;
         for (const i of temp) {
           if (!(i in raw)) {
             flags = true;
             raw[i] = mw.config.get("wgPageName");
           }
         }
         if (flags) {
           new mw.Api().postWithToken("csrf", {
             action: "edit",
             title: "Template:BilibiliVideo/bvid",
             text: JSON.stringify(raw),
             summary: `[[Widget:BilibiliVideo|BilibiliVideo]]:bvid不符合格式 - ${Array.from(temp.values()).filter(bvid => !(bvid in raw)).join(", ")}`,
             tags: "Automation tool",
             minor: true,
             bot: true,
             nocreate: true,
             watchlist: "nochange",
             contentformat: "application/json",
             contentmodel: "json",
           });
         }
       }
     }, 1);
    } catch (e) {
    } catch (e) {
      // eslint-disable-next-line prefer-template
      /* eslint-disable */
      prompt("BilibiliVideo模板执行出现问题,请复制以下内容并在提问求助区处粘贴寻求帮助:", navigator.userAgent + " : " + e + " " + e.stack.split("\n")[1].trim());
      var msg = genErr("error", navigator.userAgent + " : " + e + " " + e.stack.split("\n")[1].trim());
     $(".bilibili-video-container").each(function (_, ele) {
       ele.outerHTML = msg;
     });
     /* eslint-enable */
    }
    }
});
});
</script><!--{/if}-->
</script><!--{/if}--></includeonly>
</includeonly>

2022年11月20日 (日) 17:07的最新版本

名称: Bilibili视频插件
作者: 加大号的猫
修订: Boxsnake
重修订: AnnAngela
H5版再修订:
新H5版又修订:
移动版支持: XYZ指示物
版权协定: MIT
发布日期:

2012年6月29日第一版发布;
2015年2月6日更新;
2016年11月29日更新更多细节;
2017年4月10日更新至H5版(感谢众多dalao的debug_(:зゝ∠)_);
2020年01月27日更新至新版H5播放器。

发布地址: https://zh.moegirl.org.cn/Widget:BilibiliVideo && https://zh.moegirl.org.cn/Template:BilibiliVideo
注意事项: 如有问题,请联系作者。

本Widget不能单独使用,请使用{{BilibiliVideo}}!