YouTube playback progress memory

memory and resume the playback progress

目前為 2024-12-05 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name YouTube playback progress memory
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.0
  5. // @description memory and resume the playback progress
  6. // @author hhst
  7. // @match https://www.youtube.com/watch?v=*
  8. // @match https://m.youtube.com/watch?v=*
  9. // @run-at document-start
  10. // @icon https://www.google.com/s2/favicons?sz=64&domain=youtube.com
  11. // @grant GM_getValue
  12. // @grant GM_setValue
  13. // @license MIT
  14. // ==/UserScript==
  15.  
  16. (function() {
  17. 'use strict';
  18.  
  19. // return the youtube video id like 'A9oByH9Ci24'
  20. const get_video_id = (url) => {
  21. try {
  22. const match = url.match(/watch\?v=([^&#]+)/)
  23. return match ? match[1] : null
  24. } catch (error) {
  25. console.error('Error getting video ID:', error)
  26. return null
  27. }
  28. }
  29.  
  30. const observer = new MutationObserver((mutationsList) => {
  31. for (const mutation of mutationsList) {
  32. if (mutation.type === 'childList') {
  33. mutation.addedNodes.forEach((node) => {
  34. if (node.nodeType === 1 && node.classList.contains('video-stream')){
  35. console.log("ready to record...")
  36. // memory progress
  37. node.addEventListener('timeupdate', () => {
  38. if (node.currentTime !== 0){
  39. GM_setValue('progress-' + get_video_id(location.href), node.currentTime.toString())
  40. }
  41. })
  42. }
  43.  
  44. if (node.id === 'movie_player') {
  45. window.last_player_state = -1
  46. node.addEventListener('onStateChange', (data) => {
  47. /* refers to https://developers.google.com/youtube/iframe_api_reference:
  48. onStateChange
  49. This event fires whenever the player's state changes. The data property of the event object that the API passes to your event listener function will specify an integer that corresponds to the new player state. Possible values are:
  50. -1 (unstarted)
  51. 0 (ended)
  52. 1 (playing)
  53. 2 (paused)
  54. 3 (buffering)
  55. 5 (video cued).
  56. */
  57. if(data in [1 , 3] && window.last_player_state === -1 ){
  58. console.log("ready to resume...")
  59. // resume progress
  60. // get the last progress time, default 0
  61. const saved_time = GM_getValue('progress-' + get_video_id(location.href)) || '0'
  62. console.log("resume to", saved_time)
  63. node.seekTo(parseInt(saved_time))
  64. }
  65. window.last_player_state = data
  66. })
  67. }
  68. })
  69. }
  70. }
  71. })
  72.  
  73. observer.observe(document.documentElement, {
  74. childList: true,
  75. subtree: true
  76. })
  77.  
  78. })();