ppvm_player.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt GPL-v3-or-Later
  2. function setup_playback(description) {
  3. document.getElementById("no-script").classList.remove("noscript");
  4. document.getElementById("controls").classList.add("javascript");
  5. video_manifest = description;
  6. console.log(description);
  7. player = document.getElementById("player");
  8. player.addEventListener("pause", (event) => playStateChanged(false));
  9. player.addEventListener("playing", (event) => playStateChanged(true));
  10. filteredOptions = filterOptions(description.entries);
  11. if(filteredOptions.length == 0){
  12. player.src = "invalid://invalid";
  13. document.getElementById("unplayable-modal").showModal();
  14. return;
  15. }
  16. player.src = filteredOptions[0].path;
  17. qualitySelector = document.getElementById("quality-selector");
  18. filteredOptions.forEach(option => {
  19. opt = document.createElement("option")
  20. opt.value = option.path;
  21. opt.innerHTML = option.label;
  22. qualitySelector.appendChild(opt);
  23. });
  24. startRes = findOptimalOptionForScreen(filteredOptions);
  25. qualitySelector.value = startRes.path
  26. qualitySelected();
  27. doSpeedTest(startRes, filteredOptions);
  28. }
  29. function qualitySelected() {
  30. qualitySelector = document.getElementById("quality-selector");
  31. player = document.getElementById("player");
  32. paused = player.paused;
  33. time = player.currentTime;
  34. player.src = qualitySelector.value;
  35. player.load();
  36. player.currentTime = time;
  37. if(!paused) {
  38. player.play();
  39. }
  40. }
  41. function filterOptions(options) {
  42. player = document.getElementById("player");
  43. return options.filter(o => o.type === "video" && canPlayStream(o) && (o.metadata.alternative_to == undefined || !canPlayStream(options.find(s => s.label == o.metadata.alternative_to))));
  44. }
  45. function canPlayStream(stream) {
  46. player = document.getElementById("player");
  47. return player.canPlayType(`${stream.mimetype}; codecs="${stream.metadata.codecs}"`);
  48. }
  49. function findOptimalOptionForScreen(options) {
  50. screenSize = Math.max(window.screen.width, window.screen.height);
  51. screenSize = screenSize * window.devicePixelRatio
  52. filtered = options.filter(o => o.type === "video" && Math.max(o.metadata.size.split("x")[0], o.metadata.size.split("x")[1]) <= screenSize);
  53. console.log(filtered);
  54. if(filtered.length == 0){
  55. return options[options.length - 1];
  56. }
  57. return filtered[0];
  58. }
  59. function downloadVideo() {
  60. document.getElementById("download-modal").showModal();
  61. }
  62. function showInfo() {
  63. document.getElementById("info-modal").showModal();
  64. }
  65. function shareVideo() {
  66. document.getElementById("share-modal").showModal();
  67. }
  68. function playStateChanged(playing) {
  69. controls = document.getElementById("controls")
  70. if(playing) {
  71. controls.classList.remove("paused")
  72. }
  73. else {
  74. controls.classList.add("paused")
  75. }
  76. }
  77. function doSpeedTest(currentOption, options) {
  78. startTime = window.performance.now();
  79. request = new XMLHttpRequest();
  80. request.onreadystatechange = function() {
  81. if(request.readyState === 2) {
  82. // Reset start time, headers received.
  83. startTime = window.performance.now();
  84. }
  85. if(request.readyState === 4 && (request.status === 200 || request.status === 206)) {
  86. endTime = window.performance.now();
  87. size = request.response.size;
  88. rate = size / ((endTime - startTime) / 1000)
  89. console.log(`Detected connection rate: ${rate} bytes/sec`);
  90. filtered = options.filter(o => o.type === "video" && o.byterate < rate);
  91. if(filtered.length == 0) {
  92. filtered = [options[options.length - 1]];
  93. }
  94. optimal = findOptimalOptionForScreen(filtered);
  95. if(optimal !== currentOption) {
  96. qualitySelector.value = optimal.path
  97. console.log("Switched res");
  98. qualitySelected();
  99. }
  100. else {
  101. console.log("Got it right first try B)");
  102. }
  103. }
  104. }
  105. requestSize = Math.min(options[0].filesize, Math.round(options[0].byterate));
  106. request.open("GET", options[0].path);
  107. request.responseType = "blob";
  108. request.setRequestHeader("Range", `bytes=0-${requestSize}`);
  109. request.send();
  110. }
  111. // @license-end