video_player.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. <?php
  2. function ppvm_player($ppub, $path, $video) {
  3. $metadata = $ppub->metadata;
  4. ?>
  5. <!DOCTYPE html>
  6. <html lang="<?php echo($metadata["language"] ?? SITE_LANGUAGE);?>">
  7. <head>
  8. <meta charset="utf-8">
  9. <title><?php echo(htmlentities($metadata["title"]));?> - <?php echo(SITE_NAME);?></title>
  10. <meta name="description" content="<?php echo(htmlentities($metadata["description"]));?>">
  11. <meta name="author" content="<?php echo(htmlentities($metadata["author"]));?>">
  12. <link rel="alternate" type="application/x-ppub" title="<?php echo(htmlentities($metadata["title"]));?> (as PPUB)" href="?download=true" />
  13. <script type="text/javascript" src="<?php echo(SITE_URL);?>/ppvm_player.js"></script>
  14. <style type="text/css">
  15. body {
  16. margin: 0px;
  17. background-color: #000;
  18. }
  19. video {
  20. display: block;
  21. height: auto;
  22. width: 100vw;
  23. height: 100vh;
  24. }
  25. .additional-contols {
  26. background: rgba(45, 45, 45, 0.8);
  27. padding: 6px;
  28. color: #ffffff;
  29. height: 24px;
  30. position: absolute;
  31. top: -36px;
  32. left: 0;
  33. right: 0;
  34. opacity: 0;
  35. transition: 0.2s all;
  36. display: flex;
  37. align-items: center;
  38. justify-content: space-between;
  39. gap: 8px;
  40. }
  41. body:hover .additional-contols, .paused {
  42. top: 0px;
  43. opacity: 1;
  44. }
  45. body, input {
  46. font: 1rem -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto, Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji", "Segoe UI Symbol";
  47. }
  48. dialog {
  49. background: rgba(45, 45, 45, 1);
  50. color: #ffffff;
  51. border: 1px solid aliceblue;
  52. max-width: 75%;
  53. }
  54. dialog p{
  55. margin-top: 2px;
  56. }
  57. dialog::backdrop {
  58. background: rgba(45, 45, 45, 0.8);
  59. }
  60. dialog .contents {
  61. margin: -15px;
  62. margin-bottom: 0px;
  63. padding: 15px;
  64. padding-bottom: 0px;
  65. max-height: calc(75vh - 55px);
  66. overflow-y: auto;
  67. }
  68. dialog .controls {
  69. border-top: 1px solid dimgrey;
  70. padding-top: 10px;
  71. }
  72. a {
  73. color: skyblue;
  74. }
  75. a:visited {
  76. color: aquamarine;
  77. }
  78. .additional-contols a {
  79. color: #ffffff;
  80. }
  81. .additional-control {
  82. display: inline-block;
  83. }
  84. .filler {
  85. flex: 1;
  86. }
  87. .site a {
  88. text-decoration: none;
  89. color: #ffffff;
  90. margin: 8px;
  91. height: 18px;
  92. line-height: 20px;
  93. }
  94. .site a:hover {
  95. color: skyblue;
  96. }
  97. .additional-control button, .additional-control select {
  98. background: rgba(45, 45, 45, 0);
  99. border: 1px solid rgba(45, 45, 45, 0);
  100. color: #ffffff;
  101. cursor: pointer;
  102. text-decoration: underline;
  103. text-align: right;
  104. margin-top: 0px;
  105. margin-bottom: 2px;
  106. margin-left: 2px;
  107. margin-right: 2px;
  108. padding-left: 6px;
  109. padding-right: 6px;
  110. padding-bottom: 3px;
  111. padding-top: 1px;
  112. height: 23px;
  113. -webkit-appearance: none;
  114. }
  115. .additional-control button:hover, .additional-control select:hover {
  116. color: skyblue;
  117. }
  118. .additional-control button:focus, .additional-control select:focus {
  119. color: skyblue;
  120. }
  121. .additional-control select option {
  122. color: #000000;
  123. }
  124. summary {
  125. cursor: pointer;
  126. }
  127. #share-modal textarea, pre {
  128. width: 500px;
  129. background: rgb(30, 30, 30);
  130. color: #fff;
  131. border: none;
  132. padding: 8px;
  133. margin-top: 8px;
  134. margin-bottom: 18px;
  135. border-radius: 4px;
  136. overflow: scroll;
  137. white-space: pre;
  138. }
  139. #download-modal li {
  140. margin-bottom: 8px;
  141. }
  142. </style>
  143. </head>
  144. <body>
  145. <video controls id="player" poster="<?php echo($video->metadata["poster"]);?>">
  146. </video>
  147. <div id="controls" class="additional-contols paused">
  148. <div class="additional-control site">
  149. <a href="<?php echo(SITE_URL);?>/<?php echo($_GET["ppub"]);?>/<?php echo($_GET["asset"]);?>" target="_blank"><strong><?php echo(htmlentities($ppub->metadata["title"]));?></strong></a>
  150. <button onclick="showInfo()">Info</button>
  151. <button onclick="shareVideo()">Share</button>
  152. <button onclick="downloadVideo()">Download</button>
  153. </div>
  154. <div class="additional-control quality">
  155. <select name="quality" id="quality-selector" onchange="qualitySelected()">
  156. </select>
  157. </div>
  158. </div>
  159. <dialog id="download-modal">
  160. <form method="dialog">
  161. <div class="contents">
  162. <p><strong>Download video</strong><br/>
  163. <a href="<?php echo($video->metadata["master"]); ?>" download>Download the full quality version of this video</a> or select a different version to suit your needs below.
  164. </p>
  165. <details>
  166. <summary>Other formats and versions</summary>
  167. <ul>
  168. <?php
  169. foreach ($video->entries as $entry) {
  170. $entry_asset = $ppub->asset_index[$entry->filename];
  171. echo(" <li><a href=\"" . $entry->filename . "\" download>" . htmlentities($entry->label) . "</a><br/>\n");
  172. echo(" <small>" . round(($entry_asset->end_location - $entry_asset->start_location) / 1000000, 2) . "MB, " . $entry_asset->mimetype . "</small></li>\n");
  173. }
  174. ?>
  175. </ul>
  176. </details>
  177. <p>
  178. <?php if ($ppub->metadata["copyright"] != null) { ?>
  179. <br/>
  180. <?php echo($ppub->metadata["copyright"]);?>
  181. <?php } if ($ppub->metadata["licence"] != null) { ?>
  182. <br/>
  183. <a href="<?php echo($ppub->metadata["licence"]);?>">See Licence</a>
  184. <?php } ?></p>
  185. </div>
  186. <div class="controls">
  187. <button value="cancel">Close</button>
  188. </div>
  189. </form>
  190. </dialog>
  191. <dialog id="info-modal">
  192. <form method="dialog">
  193. <div class="contents">
  194. <p><strong><?php echo(htmlentities($ppub->metadata["title"]));?></strong>
  195. <?php if($ppub->metadata["author"] != null) {
  196. preg_match("/^([^<]*(?= *<|$))<*([^>]*)>*/", $ppub->metadata["author"], $author);
  197. ?>
  198. <br/>By <?php
  199. if(isset($author[2]) && $author[2] != '') {
  200. echo("<a href=\"mailto:".$author[2]."\">");
  201. echo(htmlentities(trim($author[1])));
  202. echo("</a>");
  203. } else {
  204. echo(htmlentities($ppub->metadata["author"]));
  205. }
  206. ?>.
  207. <?php } if ($ppub->metadata["tags"] != null and USE_PPIX) { ?>
  208. <br/>Tagged with:
  209. <?php
  210. foreach(explode(" ", $ppub->metadata["tags"]) as $tag) {
  211. ?>
  212. <a href="<?php echo(SITE_URL);?>/?tag=<?php echo(urlencode($tag));?>" target="_blank"><?php echo(htmlentities($tag));?></a>
  213. <?php
  214. }
  215. ?>
  216. <?php } if ($ppub->metadata["date"] != null) { ?>
  217. <br/>Last updated on <?php echo(htmlentities((new DateTime($ppub->metadata["date"]))->format(DATE_FORMAT)));?>.
  218. <br/><?php } if ($ppub->metadata["copyright"] != null) { ?>
  219. <?php echo($ppub->metadata["copyright"]);?>
  220. <?php } if ($ppub->metadata["licence"] != null) { ?>
  221. <a href="<?php echo($ppub->metadata["licence"]);?>" target="_blank">See Licence</a>
  222. <?php } ?></p>
  223. <br/><small>Powered by <a href="https://github.com/Tilo15/php-ppub" target="_blank">php-ppub</a></small></p>
  224. </div>
  225. <div class="controls">
  226. <button value="cancel">Close</button>
  227. </div>
  228. </form>
  229. </dialog>
  230. <dialog id="share-modal">
  231. <form method="dialog">
  232. <div class="contents">
  233. <p><strong>Share this video</strong><br/>
  234. With your friends, colleagues, distant family, or strangers on the internet.
  235. </p>
  236. <div>
  237. <label>Link:</label>
  238. <pre><?php echo(SITE_URL);?>/<?php echo($_GET["ppub"]);?>/<?php echo($_GET["asset"]);?></pre>
  239. </div>
  240. <div>
  241. <label>Embed:</label><br/>
  242. <textarea readonly rows="3"><?php generate_embed($path, $video);?></textarea>
  243. </div>
  244. </div>
  245. <div class="controls">
  246. <button value="cancel" autofocus>Close</button>
  247. </div>
  248. </form>
  249. </dialog>
  250. <dialog id="unplayable-modal">
  251. <form method="dialog">
  252. <div class="contents">
  253. <p><strong>Unable to playback content</strong><br/>
  254. Your browser does not appear to support any of the available codecs.
  255. </p>
  256. </div>
  257. <div class="controls">
  258. <button value="cancel">Close</button>
  259. </div>
  260. </form>
  261. </dialog>
  262. <script type="text/javascript">
  263. setup_playback({
  264. entries: [
  265. <?php
  266. foreach ($video->entries as $entry) {
  267. $entry_asset = $ppub->asset_index[$entry->filename];
  268. echo(" { type: \"" . $entry->type . "\", mimetype: \"" . $entry_asset->mimetype . "\", path: \"" . $entry->filename . "\", label: \"" . $entry->label . "\", metadata: { ");
  269. foreach ($entry->metadata as $key => $val) {
  270. echo($key . ": \"" . $val . "\", ");
  271. }
  272. echo("}},\n");
  273. }
  274. ?>
  275. ]
  276. });
  277. </script>
  278. </body>
  279. </html>
  280. <?php
  281. }
  282. function generate_embed($path, $video) {
  283. $percent = 56.25;
  284. if(isset($video->metadata["ratio"])) {
  285. $ratio = explode(":", $video->metadata["ratio"]);
  286. $percent = (min($ratio[0], $ratio[1]) / max($ratio[0], $ratio[1])) * 100;
  287. }
  288. ?>
  289. <div class="ppvm-player" style="position: relative; height:0; background: #2d2d2d; padding-bottom: <?php echo($percent);?>%">
  290. <iframe src="<?php echo(SITE_URL);?>/<?php echo($_GET["ppub"]);?>/<?php echo($_GET["asset"]);?>?embed=true/" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"></iframe>
  291. </div><?php
  292. }
  293. ?>