video.html 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. {% extends 'themes/wayback/base.html' %}
  2. {% block head %}
  3. <meta name="description" content="{{ vinfo['desc'] }}">
  4. <meta name="keywords" content="{{ keywords }}">
  5. <meta property="og:site_name" content="{{ vinfo['owner']['name'] }} | MikuInvidious">
  6. <meta property="og:url" content="{{ site_url }}/video/{{ vid }}">
  7. <meta property="og:title" content="{{ vinfo['title'] }}">
  8. <meta property="og:image" content="{{ vinfo['pic'] }}">
  9. <meta property="og:description" content="{{ vinfo['desc'] }}">
  10. <meta property="og:type" content="video.other">
  11. <meta property="og:video:url" content="{{ site_url }}/embed/{{ vid }}">
  12. <meta property="og:video:secure_url" content="{{ site_url }}/embed/{{ vid }}">
  13. <meta property="og:video:type" content="text/html">
  14. <meta property="og:video:width" content="1280">
  15. <meta property="og:video:height" content="720">
  16. <meta name="twitter:card" content="player">
  17. <meta name="twitter:url" content="{{ site_url }}/video/{{ vid }}">
  18. <meta name="twitter:title" content="{{ vinfo['title'] }}">
  19. <meta name="twitter:description" content="{{ vinfo['desc'] }}">
  20. <meta name="twitter:image" content="{{ vinfo['pic'] }}">
  21. <meta name="twitter:player" content="{{ site_url }}/embed/{{ vid }}">
  22. <meta name="twitter:player:width" content="1280">
  23. <meta name="twitter:player:height" content="720">
  24. <link rel="alternate" href="https://www.bilibili.com/video/{{ vid }}">
  25. <title>{{ vinfo['title'] }} - MikuInvidious</title>
  26. <meta name="referrer" content="never">
  27. <link rel="stylesheet" href="/static/themes/wayback/css/player.css">
  28. <link rel="stylesheet" href="/static/vjs/video-js.min.css">
  29. <link rel="stylesheet" href="/static/vjs/videojs-resolution-switcher.css">
  30. <script>
  31. current_vid = '{{ vid }}'; idx = {{ idx }}; total_pages = {{ vset|length }};
  32. ato = {{ 'true' if ato else 'false' }};
  33. </script>
  34. {% endblock %}
  35. {% block content %}
  36. <div id="player-container" class="h-box">
  37. <video style="outline:none;width:100%;background-color:#000" playsinline controls poster="{{ vinfo['pic']|pic }}" id="player" class="on-video_player video-js player-style-invidious">
  38. {% for src in supported_src %}
  39. <source src="/proxy/video/{{ vid }}_{{ idx }}_{{ src['quality'] }}" type="video/mp4"
  40. label="{{ src['new_description'] }}"
  41. />
  42. {% endfor %}
  43. <p class="vjs-no-js">
  44. To view this video please enable JavaScript, and consider upgrading to a web browser that
  45. <a href="https://videojs.com/html5-video-support/" target="_blank">supports HTML5 video</a>
  46. </p>
  47. </video>
  48. <script src="/static/vjs/video.min.js"></script>
  49. <script src="/static/vjs/videojs-resolution-switcher.js"></script>
  50. <script src="/static/danmakujs/danmaku.min.js"></script>
  51. </div>
  52. <div class="h-box">
  53. <h1>
  54. {{ vinfo['title'] }}
  55. <a id='avswitch' title="Audio mode" href="/video/{{ vid }}?listen=1{{ '&ato=1' if ato else '' }}">
  56. <i class="icon ion-md-headset"></i>
  57. </a>
  58. </h1>
  59. {% if vset|length > 1 %}
  60. <h1 style="text-align: center;">
  61. P{{ vset[idx]['page'] }}: {{ vset[idx]['part'] }}
  62. </h1>
  63. {% endif %}
  64. </div>
  65. <div class="pure-g">
  66. <div class="pure-u-1 pure-u-lg-1-5">
  67. <div class="h-box">
  68. <span id="watch-on-youtube">
  69. <a href="https://www.bilibili.com/video/{{ vinfo['bvid'] }}">在哔哩哔哩上观看</a>
  70. </span>
  71. {% if site_allow_download %}
  72. <form class="pure-form pure-form-stacked" action="/download" method="post" rel="noopener" target="_blank">
  73. <input type="hidden" name="id" value="{{ vinfo['bvid'] }}">
  74. <input type="hidden" name="cvid" value="{{ idx }}">
  75. <div class="pure-control-group">
  76. <label for="download_widget">下载格式: </label>
  77. <select style="width:100%" name="qual" id="download_widget">
  78. {% for src in supported_src %}
  79. <option value="{{ src['quality'] }}">{{ src['new_description'] }}</option>
  80. {% endfor %}
  81. </select>
  82. </div>
  83. <button type="submit" class="pure-button pure-button-primary">
  84. <b>下载</b>
  85. </button>
  86. </form>
  87. {% endif %}
  88. <p id="views"><i class="icon ion-ios-eye"></i> {{ vinfo['stat']['view']|intsep }}</p>
  89. <p id="likes"><i class="icon ion-ios-thumbs-up"></i> {{ vinfo['stat']['like']|intsep }}</p>
  90. <p id="coins"><i class="icon ion-logo-bitcoin"></i> {{ vinfo['stat']['coin']|intsep }}</p>
  91. <p id="saves"><i class="icon ion-ios-bookmark"></i> {{ vinfo['stat']['favorite']|intsep }}</p>
  92. <p id="shares"><i class="icon ion-md-share"></i> {{ vinfo['stat']['share']|intsep }}</p>
  93. <p id="genre">
  94. 视频分区:<a href="/vv/{{ vinfo['tid'] }}">{{ vinfo['tname'] }}</a>
  95. </p>
  96. </div>
  97. </div>
  98. <div class="pure-u-1 pure-u-lg-3-5">
  99. <div class="h-box">
  100. <a href="/space/{{ vinfo['owner']['mid'] }}" style="display:block;width:fit-content;width:-moz-fit-content">
  101. <div class="channel-profile">
  102. <img src="{{ vinfo['owner']['face']|pic }}" alt="" />
  103. <span id="channel-name">{{ vinfo['owner']['name'] }}</span>
  104. </div>
  105. </a>
  106. <p id="published-date">
  107. 上传于 {{ vinfo['pubdate']|date }}
  108. </p>
  109. <div id="description-box">
  110. <div id="descriptionWrapper">{{ vinfo['desc'] }}</div>
  111. </div>
  112. <hr>
  113. <div id="comments">
  114. <h3>浏览总计 {{ vcomments['page']['count'] }} 条评论中的 {{ vcomments['page']['size'] if vcomments['page']['size'] < vcomments['page']['count'] else vcomments['page']['count'] }} 条评论</h3>
  115. <div>
  116. {% if vcomments['replies'] %}
  117. {% for rep in vcomments['replies'] %}
  118. <div class="pure-g" style="width:100%">
  119. <div class="channel-profile pure-u-4-24 pure-u-md-2-24">
  120. <img loading="lazy" style="margin-right:1em;margin-top:1em;width:90%" src="{{ "{}@100w".format(rep['member']['avatar'])|pic }}" alt="">
  121. </div>
  122. <div class="pure-u-20-24 pure-u-md-22-24">
  123. <p><b><a class="" href="/space/{{ rep['member']['mid'] }}">{{ rep['member']['uname'] }}</a></b></p>
  124. <p style="white-space:pre-wrap">{{ rep['content']['message'] }}</p>
  125. <p>
  126. <span>{{ rep['reply_control']['time_desc'] }}</span>
  127. | <i class="icon ion-ios-thumbs-up"></i> {{ rep['like']|intsep }}
  128. </p>
  129. </div>
  130. </div>
  131. {% endfor %}
  132. {% endif %}
  133. <hr>
  134. </div>
  135. </div>
  136. </div>
  137. </div>
  138. <div class="pure-u-1 pure-u-lg-1-5">
  139. {% if vset|length > 1 %}
  140. <div class="h-box">
  141. <div class="pure-control-group">
  142. <label for="continue">Play next by default: </label>
  143. <input name="continue" id="continue" type="checkbox">
  144. </div>
  145. </div>
  146. <hr>
  147. <div class="h-box pure-menu pure-menu-scrollable" style="height: 30em;">
  148. {% for v in vset %}
  149. <a href="/video/{{ vid }}:{{ v['page']-1 }}">
  150. {% if v['first_frame'] %}
  151. <div class="thumbnail">
  152. <img width="320" height="180" loading="lazy" class="thumbnail" src="{{ "{}@320w".format(v['first_frame'])|pic }}" alt="">
  153. <p class="length">{{ v['duration']|secdur }}</p>
  154. </div>
  155. {% endif %}
  156. <p style="width:100%">
  157. P{{ v['page'] }}: {{ v['part'] }}
  158. </p>
  159. </a>
  160. {% endfor %}
  161. </div>
  162. <hr>
  163. {% endif %}
  164. <div class="h-box">
  165. {% for rv in vrelated %}
  166. <a href="/video/{{ rv['bvid'] }}">
  167. <div class="thumbnail">
  168. <img width="320" height="180" loading="lazy" class="thumbnail" src="{{ "{}@320w".format(rv['pic'])|pic }}" alt="">
  169. <p class="length">{{ rv['duration']|secdur }}</p>
  170. </div>
  171. <p style="width:100%">
  172. {{ rv['title'] }}
  173. </p>
  174. </a>
  175. {% endfor %}
  176. </div>
  177. </div>
  178. </div>
  179. <script src="/static/themes/wayback/js/player.js"></script>
  180. {% endblock %}