Comment Smoother for niconico live

ニコニコ生放送のコメントをぬるぬるにします

  1. // ==UserScript==
  2. // @name Comment Smoother for niconico live
  3. // @description ニコニコ生放送のコメントをぬるぬるにします
  4. // @namespace https://rinsuki.net/
  5. // @match https://live.nicovideo.jp/watch/*
  6. // @grant none
  7. // @version 1.0
  8. // @author rinsuki
  9. // @license MIT
  10. // ==/UserScript==
  11.  
  12. (() => {
  13. if (!navigator.userAgent.includes("Firefox/")) return
  14. const origGetter = HTMLVideoElement.prototype.__lookupGetter__("currentTime")
  15. const origSetter = HTMLVideoElement.prototype.__lookupSetter__("currentTime")
  16. class Smoother {
  17. lastCurrentTime = 0
  18. lastNow = 0
  19. /**
  20. * @param {HTMLVideoElement} elm
  21. */
  22. currentTime(elm) {
  23. const currentTime = origGetter.call(elm)
  24. if (elm.paused) {
  25. return currentTime
  26. }
  27. if (this.lastCurrentTime !== currentTime) {
  28. // 更新された
  29. this.lastCurrentTime = currentTime
  30. this.lastNow = performance.now()
  31. return currentTime
  32. }
  33. const now = performance.now()
  34. const diff = now - this.lastNow
  35. if (diff > 1000) {
  36. // 一秒ずれてるというのはおかしい…ので帰る
  37. return currentTime
  38. }
  39. const currentNow = this.lastCurrentTime + (diff / 1000)
  40. return currentNow
  41. }
  42. }
  43. if (origGetter != null && origSetter != null) {
  44. HTMLVideoElement.prototype.__defineGetter__("currentTime", function() {
  45. if (!("__userjs_smoother" in this)) {
  46. console.log("new smoother", this)
  47. this.__userjs_smoother = new Smoother()
  48. }
  49. return this.__userjs_smoother.currentTime(this)
  50. })
  51. HTMLVideoElement.prototype.__defineSetter__("currentTime", function() {
  52. origSetter.apply(this, arguments)
  53. })
  54. } else {
  55. console.log("[nicolive-comment-smoother]", "origGetter/origSetter is not available", origGetter, origSetter)
  56. }
  57. })()