YouTube Enhancer from YouTube2009Year

Download Link + Quality Selector + Rollover Preview + Media Controller

  1. // <![CDATA[
  2. // ==UserScript==
  3. // @name YouTube Enhancer from YouTube2009Year
  4. // @fullname YouTube Enhancer from YouTube2009Year
  5. // @author VoxelBeet129
  6. // @version 2014-12-29
  7. // @licence (CC) by-nc-sa
  8. // @namespace http://gf.qytechs.cn/scripts/show/33042
  9. // @description Download Link + Quality Selector + Rollover Preview + Media Controller
  10. // @include http://youtube2009year.weebly.com
  11. // ==/UserScript==
  12.  
  13. // fmt=0 -> flv: 320x240 (flv1) / mp3 1.0 22KHz
  14. // fmt=5 -> flv: 320x240 (flv1) / mp3 1.0 22KHz
  15. // fmt=6 -> flv: 480x360 (flv1) / mp3 1.0 44KHz (No more...)
  16. // fmt=13 -> 3gp: 176x144 (mpg4) / ??? 2.0 8KHz
  17. // fmt=17 -> 3gp: 176x144 (mpg4) / ??? 1.0 22KHz
  18. // fmt=18 -> mp4: 480x360 (H264) / AAC 2.0 44KHz
  19. // fmt=22 -> mp4: 1280x720 (H264) / AAC 2.0 44KHz
  20. // fmt=34 -> flv: 320x180 (flv?) / ??? 2.0 44KHz (default now)
  21. // fmt=35 -> flv: 640x380 (flv?) / ??? 2.0 44KHz
  22.  
  23. // YouTube URL: http://www.youtube.com/watch?v=[video_id] &fmt=[selected_fmt] &hl=[lang]
  24. // YouTube download link: http://www.youtube.com/get_video?video_id=[video_id]&t=[t_id]&fmt=[download_fmt]
  25.  
  26. ( function() {
  27.  
  28. //======================================== USER SETTING ==================================================//
  29.  
  30. // Updater
  31. const YOUTUBE_ENHANCER_UPDATER_STATUS = 0; // -1=Disable / 0=No change / 1=Enable
  32.  
  33. // Cleanning flashvars...
  34. const CLEAN_FLASHVARS = 1; // 0=disable / 1=enable cleanning
  35. const DISABLE_ANNOTATIONS = 0; // work only when CLEAN_FLASHVARS is enabled
  36. const DISABLE_SUBTITLES = 0; // work only when CLEAN_FLASHVARS is enabled
  37.  
  38. // Video display Config
  39. const ENABLE_4DV3_VIDEO_RESIZING = 1; // 0=Normal size / 1=More height / 2=Largest size
  40. const ENABLE_WIDE_VIDEO_RESIZING = 1; // 0=Normal size / 1=Largest size
  41. const ENABLE_TITLE_HIDING = 1; // 0=Show Title / 1=Hide Title
  42.  
  43.  
  44.  
  45. //======================================== ADVANCED SETTING ==============================================//
  46.  
  47. // light or dark ? // false=Light colors / true=Dark colors
  48. const USE_DARK_COLORS=(GetLuminosity(window.getComputedStyle(document.body, null).backgroundColor)<128);
  49.  
  50. // Color for Download Link
  51. var COLOR_DL_OPTIONS_BORDER = '#DDDDDD';
  52. var COLOR_DL_OPTIONS_BACKGROUND = '#F8E0E0';
  53. var COLOR_DL_OPTIONS_TEXT = '#6666FF';
  54. var COLOR_DL_POPUP_BORDER = '#000000';
  55. var COLOR_DL_POPUP_ARROW = '#000000';
  56. var COLOR_DL_POPUP_TEXT = '#000000';
  57. var COLOR_DL_POPUP_BG_BLUE_OUT = '#DDDDFF';
  58. var COLOR_DL_POPUP_BG_BLUE_IN = '#CCCCFF';
  59. var COLOR_DL_POPUP_BG_RED_OUT = '#FFDDDD';
  60. var COLOR_DL_POPUP_BG_RED_IN = '#FFCCCC';
  61. // Color for Media Controller
  62. var COLOR_MC_BORDER = '#CCCCCC';
  63. var COLOR_MC_BACKGROUND = '#E8E8E8';
  64. var COLOR_MC_TEXT_OUT = '#000000';
  65. var COLOR_MC_TEXT_ACTION_IN = '#E00000';
  66. var COLOR_MC_TEXT_TOGGLE_IN = '#00C040';
  67. var COLOR_MC_TOGGLE_BEG_END = '#FFDD00';
  68. var COLOR_MC_TOGGLE_LOOP = '#BBBBFF';
  69. var COLOR_MC_BG_RED = '#FFF0F0';
  70. var COLOR_MC_BG_BLUE_OUT = '#F0F0FF';
  71. var COLOR_MC_BG_BLUE_IN = '#E0E0FF';
  72. var COLOR_MC_TEXT_BLUE = '#0033CC';
  73.  
  74. if (USE_DARK_COLORS==true) {
  75. // Color for Download Link
  76. COLOR_DL_OPTIONS_BORDER = '#666666';
  77. COLOR_DL_OPTIONS_BACKGROUND = '#5C3C3C';
  78. COLOR_DL_OPTIONS_TEXT = '#9999FF';
  79. COLOR_DL_POPUP_BORDER = '#888888';
  80. COLOR_DL_POPUP_ARROW = '#FFFFFF';
  81. COLOR_DL_POPUP_TEXT = '#FFFFFF';
  82. COLOR_DL_POPUP_BG_BLUE_OUT = '#444466';
  83. COLOR_DL_POPUP_BG_BLUE_IN = '#222266';
  84. COLOR_DL_POPUP_BG_RED_OUT = '#664444';
  85. COLOR_DL_POPUP_BG_RED_IN = '#662222';
  86. // Color for Media Controller
  87. COLOR_MC_BORDER = '#666666';
  88. COLOR_MC_BACKGROUND = '#3C3C3C';
  89. COLOR_MC_TEXT_OUT = '#B06000';
  90. COLOR_MC_TEXT_ACTION_IN = '#FF0000';
  91. COLOR_MC_TEXT_TOGGLE_IN = '#00C040';
  92. COLOR_MC_TOGGLE_BEG_END = '#888800';
  93. COLOR_MC_TOGGLE_LOOP = '#4444BB';
  94. COLOR_MC_BG_RED = '#5C3C3C';
  95. COLOR_MC_BG_BLUE_OUT = '#3C3C5C';
  96. COLOR_MC_BG_BLUE_IN = '#3C3C8C';
  97. COLOR_MC_TEXT_BLUE = '#0066FF';
  98. }
  99.  
  100. // RollOver Config
  101. const ROLLOVER_DELAY_INIT = 200; // Initial delay
  102. const ROLLOVER_DELAY_LOAD = 50; // Small delay for testing if all images is loaded
  103. const ROLLOVER_DELAY_CONT = 800; // Normal delay of the rollover
  104.  
  105. // Constants (Not important)
  106. const WATCH_VIDEO_INFO = 'watch-channel-vids-div'; // To get his background and border color
  107. const WATCH_MORE_FROM = 'watch-channel-vids-body'; // To add a load event in change_link()
  108. const WATCH_RELATED_VIDS = 'watch-related-vids-body'; // To add a load event in change_link()
  109. const PLAYLIST_PANEL = 'playlist-panel'; // To add a load event in change_link()
  110. const WATCH_SEARCH_RES = 'watch_search_results'; // To add a load event in change_link()
  111. const WATCH_PROMOTED = 'watch-promoted-videos-container'; // Used to remove the parent
  112. const WATCH_QUAL_SETTING = 'watch-video-quality-setting'; // Used to remove it
  113. const DEFAULT_LANG_BOX = 'default-language-box'; // Used to remove it
  114. const WATCH_URL_FIELD = 'watch-url-field'; // Add fmt
  115.  
  116. // Constants (Better to have)
  117. const WATCH_PLAYER_DIV = 'watch-player-div'; // Used to retrieve the Video Embed if not found
  118. const WATCH_RATINGS_VIEW = 'watch-main-area'; // Used to append the Quality Selector
  119.  
  120. // Constants (Important)
  121. const WATCH_TITLE_DIV = 'watch-vid-title'; // Div id of the video title
  122. const YT_PLAYER_EMBED = 'movie_player'; // Default Video Embed id
  123. const FMT_HIGH_QUALITY_FLV = 35;
  124.  
  125.  
  126. //*************************************** Languages support **********************************************//
  127. function get_text_DL(lang,variable) {
  128. switch(variable) {
  129. case "dlink": switch (lang) {
  130. // from Youtube Setting or Youtube URL (17 Languages actually)
  131. case "zh-cn": return "&#19979;&#36733;";
  132. case "zh-tw": return "&#19979;&#36617;";
  133. case "ja": return "&#12480;&#12454;&#12531;&#12525;&#12540;&#12489;";
  134. case "ko": return "&#45796;&#50868;&#47196;&#46300;";
  135. case "de": return "Herunterladen";
  136. default: // Default is set to English
  137. case "en": case "en-gb": return "Download";
  138. case "es": case "es-mx": return "Descargar";
  139. case "fr": return "T&#233;l&#233;charger";
  140. case "it": return "Scaricare";
  141. case "nl": return "Downloaden";
  142. case "pl": return "Pobra&#263;";
  143. case "pt": return "Baixar";
  144. case "ru": return "&#1089;&#1082;&#1072;&#1095;&#1072;&#1090;&#1100;";
  145. case "cs": return "St&#225;hnout";
  146. case "sv": return "H&#228;mta";
  147. // from Browser Setting...
  148. case "ar": return "&#1578;&#1581;&#1605;&#1610;&#1604;";
  149. }
  150. case "omenu": switch (lang) {
  151. case "zh-cn": return "&#36873;&#39033;";
  152. case "zh-tw": return "&#36984;&#38917;";
  153. case "ja": return "&#12458;&#12503;&#12471;&#12519;&#12531;";
  154. case "ko": return "&#50741;&#49496;";
  155. case "de": return "Optionen";
  156. default:
  157. case "en": case "en-gb": return "Options";
  158. case "es": case "es-mx": return "Opciones";
  159. case "fr": return "Options";
  160. case "it": return "Opzioni";
  161. case "nl": return "Opties";
  162. case "pl": return "Opcje";
  163. case "pt": return "Op&#231;&#245;es";
  164. case "ru": return "&#1042;&#1072;&#1088;&#1080;&#1072;&#1085;&#1090;&#1086;&#1074;";
  165. case "ar": return "&#1582;&#1610;&#1575;&#1585;&#1575;&#1578;";
  166. }
  167. case "qual1": switch (lang) {
  168. case "zh-cn": return "1: &#38598;&#19979;&#36733;&#38142;&#25509;&#21040;&#21516;&#19968;&#36136;&#37327;&#30340;&#35270;&#39057;&#35266;&#30475;";
  169. case "zh-tw": return "1: &#38598;&#19979;&#36617;&#37832;&#25509;&#21040;&#21516;&#19968;&#36074;&#37327;&#30340;&#35222;&#38971;&#35264;&#30475;";
  170. case "ja": return "1: &#12480;&#12454;&#12531;&#12525;&#12540;&#12489;&#12522;&#12531;&#12463;&#12434;&#35373;&#23450;&#12377;&#12427;&#12398;&#38322;&#35239;&#12289;&#12499;&#12487;&#12458;&#12398;&#21697;&#36074;&#12392;&#21516;&#12376;";
  171. case "ko": return "1: &#49444;&#51221; &#45796;&#50868;&#47196;&#46300; &#47553;&#53356;&#47484; &#48380; &#48708;&#46356;&#50724;&#51032; &#54408;&#51656;&#51008; &#46041;&#51068;";
  172. case "de": return "1: Gesetzte Downloadverbindung zur gleichen Qualit&#228;t des gesehenen Videos";
  173. default:
  174. case "en": case "en-gb": return "1: Set download link to the same Quality of the viewed video";
  175. case "es": case "es-mx": return "1: Acoplamiento de la transferencia directa a la misma calidad del v&#237;deo visto";
  176. case "fr": return "1: Lien de t&#233;l&#233;chargement vers la vid&#233;o de m&#234;me qualit&#233; que celle affich&#233;";
  177. case "it": return "1: Impostare link per scaricare la stessa qualit&#224; dei video visualizzati";
  178. case "nl": return "1: Stel download link naar dezelfde kwaliteit van de video bekeken";
  179. case "pl": return "1: Ustaw link do pobierania takiej samej jako&#347;ci na ogl&#261;dany film wideo";
  180. case "pt": return "1: Liga&#231;&#227;o ajustada de transfer&#234;ncia &#224; mesma qualidade do v&#237;deo visto";
  181. case "ru": return "1: &#1059;&#1089;&#1090;&#1072;&#1085;&#1086;&#1074;&#1080;&#1090;&#1100; &#1089;&#1089;&#1099;&#1083;&#1082;&#1091; &#1085;&#1072; &#1090;&#1086;&#1090; &#1078;&#1077; &#1082;&#1072;&#1095;&#1077;&#1089;&#1090;&#1074;&#1072; &#1088;&#1072;&#1089;&#1089;&#1084;&#1072;&#1090;&#1088;&#1080;&#1074;&#1072;&#1077;&#1090;&#1089;&#1103; &#1074;&#1080;&#1076;&#1077;&#1086;";
  182. case "ar": return "1: &#1578;&#1581;&#1605;&#1610;&#1604; &#1606;&#1601;&#1587; &#1606;&#1608;&#1593;&#1610;&#1577; &#1605;&#1604;&#1601; &#1575;&#1604;&#1601;&#1610;&#1583;&#1610;&#1608; &#1575;&#1604;&#1581;&#1575;&#1604;&#1610;&#1607;";
  183. }
  184. case "qual2": switch (lang) {
  185. case "zh-cn": return "2: &#38598;&#19979;&#36733;&#38142;&#25509;&#21040;&#19968;&#20010;&#39640;&#21697;&#36136;&#30340;&#35270;&#39057;&#25991;&#20214;&#65288;&#30340;FLV&#25110;&#30340;MP4&#65289;";
  186. case "zh-tw": return "2: &#38598;&#19979;&#36617;&#37832;&#25509;&#21040;&#19968;&#20491;&#39640;&#21697;&#36074;&#30340;&#35222;&#38971;&#25991;&#20214;&#65288;&#30340;FLV&#25110;&#30340;MP4&#65289;";
  187. case "ja": return "2: &#39640;&#21697;&#36074;&#12398;&#12499;&#12487;&#12458;&#12501;&#12449;&#12452;&#12523;&#65288;FLV&#12398;&#12458;&#12524;&#12468;&#12531;&#12398;MP4&#65289;&#12395;&#35373;&#23450;&#12480;&#12454;&#12531;&#12525;&#12540;&#12489;&#12522;&#12531;&#12463;";
  188. case "ko": return "2: &#45458;&#51008; &#54408;&#51656;&#51032; &#48708;&#46356;&#50724; &#54028;&#51068; (&#45824;&#54620; FLV &#46608;&#45716;&#45716; MP4)&#47196; &#49444;&#51221; &#45796;&#50868;&#47196;&#46300; &#47553;&#53356;";
  189. case "de": return "2: Gesetzte Downloadverbindung zu einer videoakte der Qualit&#228;ts (FLV oder MP4)";
  190. default:
  191. case "en": case "en-gb": return "2: Set download link to a High Quality video file (FLV or MP4)";
  192. case "es": case "es-mx": return "2: Acoplamiento de la transferencia directa a un archivo video de la alta calidad (FLV o MP4)";
  193. case "fr": return "2: Lien de t&#233;l&#233;chargement vers la vid&#233;o en haute qualit&#233; (FLV ou MP4)";
  194. case "it": return "2: Impostare il download link ad un alta qualit&#224; di file video (FLV o MP4)";
  195. case "nl": return "2: Stel download link naar een High Quality video bestand (of MP4 FLV)";
  196. case "pl": return "2: Ustaw link do wysokiej jako&#347;ci plik&#243;w wideo (MP4 lub FLV)";
  197. case "pt": return "2: Liga&#231;&#227;o ajustada de transfer&#234;ncia a uma lima video da alta qualidade (FLV ou MP4)";
  198. case "ru": return "2: &#1059;&#1089;&#1090;&#1072;&#1085;&#1086;&#1074;&#1082;&#1072; &#1089;&#1077;&#1090;&#1080; &#1089;&#1074;&#1103;&#1079;&#1080; &#1089; &#1074;&#1099;&#1089;&#1086;&#1082;&#1080;&#1084; &#1082;&#1072;&#1095;&#1077;&#1089;&#1090;&#1074;&#1086;&#1084; &#1074;&#1080;&#1076;&#1077;&#1086; &#1092;&#1072;&#1081;&#1083;&#1086;&#1074; (FLV &#1080;&#1083;&#1080; MP4)";
  199. case "ar": return "2: &#1578;&#1581;&#1605;&#1610;&#1604; &#1580;&#1608;&#1583;&#1577; &#1593;&#1575;&#1604;&#1610;&#1577; &#1604;&#1605;&#1604;&#1601; &#1575;&#1604;&#1601;&#1610;&#1583;&#1610;&#1608; &#1576;&#1589;&#1610;&#1594;&#1577; (FLV &#1571;&#1608; MP4)";
  200. }
  201. case "qual3": switch (lang) {
  202. case "zh-cn": return "3: &#38598;&#19979;&#36733;&#38142;&#25509;&#21040;&#19968;&#20010;&#39640;&#21697;&#36136;&#30340;MP4&#35270;&#39057;&#25991;&#20214;";
  203. case "zh-tw": return "3: &#38598;&#19979;&#36617;&#37832;&#25509;&#21040;&#19968;&#20491;&#39640;&#21697;&#36074;&#30340;MP4&#35222;&#38971;&#25991;&#20214;";
  204. case "ja": return "3: &#12399;&#12289;&#39640;&#21697;&#36074;&#12398;&#12499;&#12487;&#12458;&#12434;&#35373;&#23450;&#12377;&#12427;&#12398;MP4&#12501;&#12449;&#12452;&#12523;&#12398;&#12480;&#12454;&#12531;&#12525;&#12540;&#12489;&#12522;&#12531;&#12463;";
  205. case "ko": return "3: a&#45716; MP4 &#44256;&#54408;&#51656; &#46041;&#50689;&#49345;&#51004;&#47196; &#49444;&#51221; &#54028;&#51068; &#45796;&#50868;&#47196;&#46300; &#47553;&#53356;";
  206. case "de": return "3: Gesetzte Downloadverbindung zu einer videoakte der Qualit&#228;ts MP4";
  207. default:
  208. case "en": case "en-gb": return "3: Set download link to a MP4 High Quality video file";
  209. case "es": case "es-mx": return "3: Acoplamiento de la transferencia directa a un archivo video de la alta calidad MP4";
  210. case "fr": return "3: Lien de t&#233;l&#233;chargement vers la vid&#233;o en MP4 de haute qualit&#233;";
  211. case "it": return "3: Impostare il download link a un MP4 alta qualit&#224; di file video";
  212. case "nl": return "3: Stel download link naar een MP4 High Quality video bestand";
  213. case "pl": return "3: Ustaw link do pobrania MP4 wysokiej jako&#347;ci plik&#243;w wideo";
  214. case "pt": return "3: Liga&#231;&#227;o ajustada de transfer&#234;ncia a uma lima video da alta qualidade MP4";
  215. case "ru": return "3: &#1059;&#1089;&#1090;&#1072;&#1085;&#1086;&#1074;&#1080;&#1090;&#1100; &#1089;&#1089;&#1099;&#1083;&#1082;&#1091; &#1085;&#1072; MP4 &#1074;&#1099;&#1089;&#1086;&#1082;&#1086;&#1075;&#1086; &#1082;&#1072;&#1095;&#1077;&#1089;&#1090;&#1074;&#1072; &#1074;&#1080;&#1076;&#1077;&#1086;-&#1092;&#1072;&#1081;&#1083;";
  216. case "ar": return "3: &#1578;&#1581;&#1605;&#1610;&#1604; &#1575;&#1604;&#1605;&#1604;&#1601; &#1576;&#1580;&#1608;&#1583;&#1577; &#1593;&#1575;&#1604;&#1610;&#1577; &#1576;&#1589;&#1610;&#1594;&#1577; MP4";
  217. }
  218. case "auto1": switch (lang) {
  219. case "zh-cn": return "1: &#25163;&#20876;";
  220. case "zh-tw": return "1: &#25163;&#20874;";
  221. case "ja": return "1: &#12510;&#12491;&#12517;&#12450;&#12523;";
  222. case "ko": return "1: &#47588;&#45684;&#50620;";
  223. case "de": return "1: Manueller Start";
  224. default:
  225. case "en": case "en-gb": return "1: Set Autoplay to OFF";
  226. case "es": case "es-mx": return "1: Comienzo manual";
  227. case "fr": return "1: D&#233;marrage manuel";
  228. case "it": return "1: Avviamento manuale";
  229. case "nl": return "1: Zet autoplay uit";
  230. case "pl": return "1: Podr&#281;cznik";
  231. case "pt": return "1: Arranque manual";
  232. case "ru": return "1: &#1056;&#1091;&#1082;&#1086;&#1074;&#1086;&#1076;&#1089;&#1090;&#1074;&#1086;";
  233. case "ar": return "1: &#1578;&#1588;&#1594;&#1610;&#1604; &#1578;&#1604;&#1602;&#1575;&#1574;&#1610; &#1610;&#1593;&#1605;&#1604;";
  234. }
  235. case "auto2": switch (lang) {
  236. default:
  237. case "en": case "en-gb": return "2: Set Autoplay to Buffering";
  238. case "fr": return "2: Mise en buffer";
  239. }
  240. case "auto3": switch (lang) {
  241. case "zh-cn": return "3: &#33258;&#21160;";
  242. case "zh-tw": return "3: &#33258;&#21205;";
  243. case "ja": return "3: &#33258;&#21205;&#36215;&#21205;";
  244. case "ko": return "3: &#51088;&#46041;";
  245. case "de": return "3: Automatischer Start";
  246. default:
  247. case "en": case "en-gb": return "3: Set Autoplay to ON";
  248. case "es": case "es-mx": return "3: Comienzo autom&#225;tico";
  249. case "fr": return "3: D&#233;marrage automatique";
  250. case "it": return "3: Avviamento automatico";
  251. case "nl": return "3: Zet autoplay aan";
  252. case "pl": return "3: automatyczne rozpocz&#281;cie";
  253. case "pt": return "3: Arranque autom&#225;tico";
  254. case "ru": return "3: &#1040;&#1074;&#1090;&#1086;&#1084;&#1072;&#1090;&#1080;&#1095;&#1077;&#1089;&#1082;&#1080;&#1081; &#1087;&#1091;&#1089;&#1082;";
  255. case "ar": return "3: &#1578;&#1588;&#1594;&#1610;&#1604; &#1578;&#1604;&#1602;&#1575;&#1574;&#1610; &#1604;&#1575;&#1610;&#1593;&#1605;&#1604;";
  256. }
  257. }
  258. return "";
  259. }
  260. function get_text_QS(lang,variable) {
  261. switch(variable) {
  262. case "link1": switch (lang) {
  263. case "zh-cn": return "&#26597;&#30475;&#20302;&#36136;&#37327; (flv)";
  264. case "zh-tw": return "&#26597;&#30475;&#20302;&#36074;&#37327; (flv)";
  265. case "ja": return "&#23550;&#35937;&#20302;&#21697;&#36074; (flv)";
  266. case "ko": return "&#51200;&#44032;&#50640; &#54408;&#51656;&#48372;&#44592; (flv)";
  267. case "de": return "Ansicht in niedrige Qualit&#228;t (flv)";
  268. default:
  269. case "en": case "en-gb": return "View in Low Quality (flv)";
  270. case "es": case "es-mx": return "Visi&#243;n en la baja calidad (flv)";
  271. case "fr": return "Voir en Basse Qualit&#233; (flv)";
  272. case "it": return "Visualizza in bassa qualit&#224; (flv)";
  273. case "nl": return "Bekijk in lage kwaliteit (flv)";
  274. case "pl": return "Widok w niskiej jako&#347;ci (flv)";
  275. case "pt": return "Vista na m&#225; qualidade (flv)";
  276. case "ru": return "&#1055;&#1086;&#1089;&#1084;&#1086;&#1090;&#1088;&#1077;&#1090;&#1100; &#1089; &#1085;&#1080;&#1079;&#1082;&#1080;&#1084; &#1082;&#1072;&#1095;&#1077;&#1089;&#1090;&#1074;&#1086;&#1084; (flv)";
  277. case "ar": return "&#1593;&#1585;&#1590; &#1580;&#1608;&#1583;&#1577; &#1605;&#1606;&#1582;&#1601;&#1590;&#1577; (flv)";
  278. }
  279. case "link2": switch (lang) {
  280. case "zh-cn": return "&#35266;&#39640;&#21697;&#36136; (flv)";
  281. case "zh-tw": return "&#35264;&#39640;&#21697;&#36074; (flv)";
  282. case "ja": return "&#39640;&#21697;&#36074;&#34920;&#31034; (flv)";
  283. case "ko": return "&#48372;&#44592;&#50640; &#54408;&#51656; &#45458;&#51008; (flv)";
  284. case "de": return "Ansicht in hoher Qualit&#228;t (flv)";
  285. default:
  286. case "en": case "en-gb": return "View in High Quality (flv)";
  287. case "es": case "es-mx": return "Visi&#243;n en la alta calidad (flv)";
  288. case "fr": return "Voir en Haute Qualit&#233; (flv)";
  289. case "it": return "Visualizza in alta qualit&#224; (flv)";
  290. case "nl": return "Bekijk in hoge kwaliteit (flv)";
  291. case "pl": return "Widok w wysokiej jako&#347;ci (flv)";
  292. case "pt": return "Vista na alta qualidade (flv)";
  293. case "ru": return "&#1055;&#1086;&#1089;&#1084;&#1086;&#1090;&#1088;&#1077;&#1090;&#1100; &#1089; &#1074;&#1099;&#1089;&#1086;&#1082;&#1080;&#1084; &#1082;&#1072;&#1095;&#1077;&#1089;&#1090;&#1074;&#1086;&#1084; (flv))";
  294. case "ar": return "&#1593;&#1585;&#1590; &#1580;&#1608;&#1583;&#1577; &#1593;&#1575;&#1604;&#1610;&#1607; (flv)";
  295. }
  296. case "link3": switch (lang) {
  297. case "zh-cn": return "&#35266;&#39640;&#21697;&#36136; (mp4)";
  298. case "zh-tw": return "&#35264;&#39640;&#21697;&#36074; (mp4)";
  299. case "ja": return "&#39640;&#21697;&#36074;&#34920;&#31034; (mp4)";
  300. case "ko": return "&#48372;&#44592;&#50640; &#54408;&#51656; &#45458;&#51008; (mp4)";
  301. case "de": return "Ansicht in hoher Qualit&#228;t (mp4)";
  302. default:
  303. case "en": case "en-gb": return "View in High Quality (mp4)";
  304. case "es": case "es-mx": return "Visi&#243;n en la alta calidad (mp4)";
  305. case "fr": return "Voir en Haute Qualit&#233; (mp4)";
  306. case "it": return "Visualizza in alta qualit&#224; (mp4)";
  307. case "nl": return "Bekijk in hoge kwaliteit (mp4)";
  308. case "pl": return "Widok w wysokiej jako&#347;ci (mp4)";
  309. case "pt": return "Vista na alta qualidade (mp4)";
  310. case "ru": return "&#1055;&#1086;&#1089;&#1084;&#1086;&#1090;&#1088;&#1077;&#1090;&#1100; &#1089; &#1074;&#1099;&#1089;&#1086;&#1082;&#1080;&#1084; &#1082;&#1072;&#1095;&#1077;&#1089;&#1090;&#1074;&#1086;&#1084; (mp4)";
  311. case "ar": return "&#1593;&#1585;&#1590; &#1580;&#1608;&#1583;&#1577; &#1593;&#1575;&#1604;&#1610;&#1607; (mp4)";
  312. }
  313. case "link4": switch (lang) {
  314. case "zh-cn": return "&#26816;&#35270;HD&#36136;&#37327; (mp4)";
  315. case "zh-tw": return "&#27298;&#35222;HD&#36074;&#37327; (mp4)";
  316. case "ja": return "HD&#12391;&#12398;&#34920;&#31034;&#21697;&#36074; (mp4)";
  317. case "ko": return "HD&#50640;&#49436; &#54408;&#51656; &#54217;&#44032;&#48372;&#44592; (mp4)";
  318. case "de": return "Ansicht in HD-Qualit&#228;t (mp4)";
  319. default:
  320. case "en": case "en-gb": return "View in HD Quality (mp4)";
  321. case "es": case "es-mx": return "Visi&#243;n en la HD calidad (mp4)";
  322. case "fr": return "Voir en Qualit&#233; HD (mp4)";
  323. case "it": return "Visualizza in qualit&#224; HD (mp4)";
  324. case "nl": return "Bekijk in HD kwaliteit (mp4)";
  325. case "pl": return "Wy&#347;wietl w jako&#347;ci HD (mp4)";
  326. case "pt": return "Ver na qualidade HD (mp4)";
  327. case "ru": return "&#1055;&#1086;&#1089;&#1084;&#1086;&#1090;&#1088;&#1077;&#1090;&#1100; &#1074; HD &#1082;&#1072;&#1095;&#1077;&#1089;&#1090;&#1074;&#1072; (mp4)";
  328. case "ar": return "&#1585;&#1571;&#1610; &#1601;&#1610; &#1606;&#1608;&#1593;&#1610;&#1577; HD (mp4)"
  329. }
  330. }
  331. return "";
  332. }
  333. function get_text_MC(lang,variable) {
  334. switch(variable) {
  335. case "stepback": switch (lang) {
  336. case "zh-cn": return "&#36864;&#21518;&#19968;&#27493;";
  337. case "zh-tw": return "&#36864;&#24460;&#19968;&#27493;";
  338. case "ja": return "&#24460;&#36864;";
  339. case "ko": return "&#46244;&#47196; &#47932;&#47084;&#49436;";
  340. case "de": return "Schritt zur&#252;ck";
  341. default:
  342. case "en": case "en-gb": return "Step back";
  343. case "es": case "es-mx": return "Paso atr&#225;s";
  344. case "fr": return "Pas arri&#232;re";
  345. case "it": return "Passo indietro";
  346. case "nl": return "Stap terug";
  347. case "pl": return "Krok wstecz";
  348. case "pt": return "Passo para tr&#225;s";
  349. case "ru": return "&#1096;&#1072;&#1075; &#1085;&#1072;&#1079;&#1072;&#1076;";
  350. case "ar": return "&#1582;&#1591;&#1608;&#1577; &#1573;&#1604;&#1609; &#1575;&#1604;&#1608;&#1585;&#1575;&#1569;";
  351. }
  352. case "stop": switch (lang) {
  353. case "zh-cn": return "&#20572;&#27490;";
  354. case "zh-tw": return "&#20572;&#27490;";
  355. case "ja": return "&#20572;&#27490;&#12377;&#12427;";
  356. case "ko": return "&#47688;&#52628;&#45796;";
  357. case "de": return "Erlass";
  358. default:
  359. case "en": case "en-gb": return "Stop";
  360. case "es": case "es-mx": return "Paro";
  361. case "fr": return "Arr&#234;t";
  362. case "it": return "Arresto";
  363. case "nl": return "Stop";
  364. case "pl": return "Zatrzyma&#263;";
  365. case "pt": return "Ac&#243;rd&#227;o";
  366. case "ru": return "&#1054;&#1089;&#1090;&#1072;&#1085;&#1086;&#1074;&#1082;&#1072;";
  367. case "ar": return "&#1578;&#1608;&#1602;&#1601;";
  368. }
  369. case "step": switch (lang) {
  370. case "zh-cn": return "&#21521;&#21069;&#36808;&#20986;&#30340;&#19968;&#27493;";
  371. case "zh-tw": return "&#21521;&#21069;&#36993;&#20986;&#30340;&#19968;&#27493;";
  372. case "ja": return "&#19968;&#27497;&#21069;&#36914;";
  373. case "ko": return "&#50526;&#51004;&#47196;";
  374. case "de": return "Schritt nach vorn";
  375. default:
  376. case "en": case "en-gb": return "Step forward";
  377. case "es": case "es-mx": return "Paso adelante";
  378. case "fr": return "Pas avant";
  379. case "it": return "Passo in avanti";
  380. case "nl": return "Stap voorwaarts";
  381. case "pl": return "Krok naprz&#243;d";
  382. case "pt": return "Passo em frente";
  383. case "ru": return "&#1096;&#1072;&#1075; &#1074;&#1087;&#1077;&#1088;&#1077;&#1076;";
  384. case "ar": return "&#1582;&#1591;&#1608;&#1577; &#1573;&#1604;&#1609; &#1575;&#1604;&#1571;&#1605;&#1575;&#1605;";
  385. }
  386. case "play": switch (lang) {
  387. case "zh-cn": return "&#35835; / &#37325;&#26032;&#21551;&#21160;";
  388. case "zh-tw": return "&#35712; / &#37325;&#26032;&#21855;&#21205;";
  389. case "ja": return "&#35501;&#21462;&#12426; / &#20877;&#36215;&#21205;";
  390. case "ko": return "&#51069;&#44592; / &#45796;&#49884; &#49884;&#51089;";
  391. case "de": return "Lesen / ankurbeln";
  392. default:
  393. case "en": case "en-gb": return "Play / Revive";
  394. case "es": case "es-mx": return "Leer / Reactivar";
  395. case "fr": return "Lire / Relancer";
  396. case "it": return "Giochi / Faccia rivivere";
  397. case "nl": return "Lees / Restart";
  398. case "pl": return "Odczyt / Uruchom";
  399. case "pt": return "Ler / relan&#231;ar";
  400. case "ru": return "&#1055;&#1088;&#1086;&#1095;&#1080;&#1090;&#1072;&#1090;&#1100; / &#1055;&#1077;&#1088;&#1077;&#1079;&#1072;&#1075;&#1088;&#1091;&#1079;&#1082;&#1072;";
  401. case "ar": return "&#1578;&#1588;&#1594;&#1610;&#1604; / &#1575;&#1587;&#1578;&#1574;&#1606;&#1575;&#1601;";
  402. }
  403. case "pause": switch (lang) {
  404. case "zh-cn": return "&#20241;&#24687;";
  405. case "zh-tw": return "&#20241;&#24687;";
  406. case "ja": return "&#22730;&#12377;";
  407. case "ko": return "&#55092;&#49885;";
  408. case "de": return "Pause";
  409. default:
  410. case "en": case "en-gb": return "Pause";
  411. case "es": case "es-mx": return "Pausa";
  412. case "fr": return "Pause";
  413. case "it": return "Pausa";
  414. case "nl": return "Pauze";
  415. case "pl": return "Z&#322;ama&#263;";
  416. case "pt": return "Pausa";
  417. case "ru": return "&#1055;&#1077;&#1088;&#1077;&#1088;&#1099;&#1074;";
  418. case "ar": return "&#1575;&#1610;&#1602;&#1575;&#1601; &#1605;&#1572;&#1602;&#1578;";
  419. }
  420. case "begin": switch (lang) {
  421. case "zh-cn": return "&#24320;&#22987;";
  422. case "zh-tw": return "&#38283;&#22987;";
  423. case "ja": return "&#38283;&#22987;&#12377;&#12427;";
  424. case "ko": return "&#49884;&#51089;";
  425. case "de": return "Beginn";
  426. default:
  427. case "en": case "en-gb": return "Begin";
  428. case "es": case "es-mx": return "Comience";
  429. case "fr": return "D&#233;but";
  430. case "it": return "Cominci";
  431. case "nl": return "Beginnen";
  432. case "pl": return "Zacz&#261;&#263;";
  433. case "pt": return "Comece";
  434. case "ru": return "&#1053;&#1072;&#1095;&#1072;&#1090;&#1100;";
  435. case "ar": return "&#1610;&#1576;&#1583;&#1571;";
  436. }
  437. case "loop": switch (lang) {
  438. case "zh-cn": return "&#29615;";
  439. case "zh-tw": return "&#29872;";
  440. case "ja": return "&#12523;&#12540;&#12503;";
  441. case "ko": return "&#47336;&#54532;";
  442. case "de": return "Schleife";
  443. default:
  444. case "en": case "en-gb": return "Loop";
  445. case "es": case "es-mx": return "Lazo";
  446. case "fr": return "En boucle";
  447. case "it": return "Ciclo";
  448. case "nl": return "Loop";
  449. case "pl": return "P&#281;tla";
  450. case "pt": return "La&#231;o";
  451. case "ru": return "&#1055;&#1077;&#1090;&#1083;&#1103;";
  452. case "ar": return "&#1575;&#1604;&#1578;&#1601;&#1575;&#1601;";
  453. }
  454. case "rewind": switch (lang) {
  455. case "zh-cn": return "&#20498;&#24102;";
  456. case "zh-tw": return "&#20498;&#24118;";
  457. case "ja": return "&#24059;&#12365;&#25147;&#12375;";
  458. case "ko": return "&#46104;&#44048;&#44592;";
  459. case "de": return "R&#252;ckspulen";
  460. default:
  461. case "en": case "en-gb": return "Rewind";
  462. case "es": case "es-mx": return "Rebobinado";
  463. case "fr": return "Retour arri&#232;re";
  464. case "it": return "Riavvolgere";
  465. case "nl": return "Rewind";
  466. case "pl": return "Rewind";
  467. case "pt": return "Rebobina&#231;&#227;o";
  468. case "ru": return "&#1055;&#1077;&#1088;&#1077;&#1084;&#1086;&#1090;&#1082;&#1072;";
  469. case "ar": return "&#1585;&#1580;&#1608;&#1593;";
  470. }
  471. case "end": switch (lang) {
  472. case "zh-cn": return "&#23436;";
  473. case "zh-tw": return "&#23436;";
  474. case "ja": return "&#32066;&#12431;&#12426;";
  475. case "ko": return "&#45149;";
  476. case "de": return "Ende";
  477. default:
  478. case "en": case "en-gb": return "End";
  479. case "es": case "es-mx": return "Final";
  480. case "fr": return "Fin";
  481. case "it": return "Fine";
  482. case "nl": return "Eindigen";
  483. case "pl": return "Koniec";
  484. case "pt": return "Fim";
  485. case "ru": return "&#1050;&#1086;&#1085;&#1077;&#1094;";
  486. case "ar": return "&#1575;&#1604;&#1606;&#1607;&#1575;&#1610;&#1577;";
  487. }
  488. case "kill": switch (lang) {
  489. case "zh-cn": return "&#21452;&#20987;&#26432;&#23475;&#32593;&#27969;&#21644;&#25773;&#25918;&#22120;";
  490. case "zh-tw": return "&#38617;&#25802;&#27578;&#23475;&#32178;&#27969;&#21644;&#25773;&#25918;&#22120;";
  491. case "ja": return "&#12480;&#12502;&#12523;&#12463;&#12522;&#12483;&#12463;&#12377;&#12427;&#12392;&#12289; NetStream&#12392;&#12399;&#12289;&#12503;&#12524;&#12540;&#12516;&#12540;&#12434;&#27578;&#12377;&#12383;&#12417;&#12395;";
  492. case "ko": return "NetStream&#51012; &#45908;&#48660; &#53364;&#47533;&#54616;&#44256; &#54540;&#47112;&#51060;&#50612;&#47484; &#51453;&#51060;&#44256;";
  493. case "de": return "Doppeltes Klicken, zum des NetStream und des Spielers zu t&#246;ten";
  494. default:
  495. case "en": case "en-gb": return "Double click to kill the NetStream and the player";
  496. case "es": case "es-mx": return "Tecleo doble para matar el NetStream y al jugador";
  497. case "fr": return "Double click pour stopper le NetStream et le lecteur Vid&#233;o";
  498. case "it": return "Fare doppio clic su di uccidere il NetStream e il giocatore";
  499. case "nl": return "Dubbelklik tot de dood van de NetStream en de speler";
  500. case "pl": return "Dwukrotnie kliknij, aby zabi&#263; NetStream i odtwarzacz";
  501. case "pt": return "Clique dobro para matar o NetStream e o jogador";
  502. case "ru": return "&#1044;&#1074;&#1072;&#1078;&#1076;&#1099; &#1097;&#1077;&#1083;&#1082;&#1085;&#1080;&#1090;&#1077; &#1091;&#1073;&#1080;&#1090;&#1100; NetStream &#1080; &#1080;&#1075;&#1088;&#1086;&#1082;";
  503. case "ar": return "&#1575;&#1606;&#1602;&#1585; &#1606;&#1602;&#1585;&#1607; &#1605;&#1586;&#1583;&#1608;&#1580;&#1607; &#1604;&#1575;&#1610;&#1602;&#1575;&#1601; &#1575;&#1604;&#1593;&#1585;&#1590;";
  504. }
  505. case "embed": switch (lang) {
  506. case "zh-cn": return "Embed &#38142;&#25509;";
  507. case "zh-tw": return "Embed &#37832;&#25509;";
  508. case "ja": return "Embed &#12522;&#12531;&#12463;";
  509. case "ko": return "Embed &#47553;&#53356;";
  510. case "de": return "Embed Verbindung";
  511. default:
  512. case "en": case "en-gb": return "Embed Link";
  513. case "es": case "es-mx": return "Acoplamiento de Embed";
  514. case "fr": return "Lien Embed";
  515. case "it": return "Collegamento di Embed";
  516. case "nl": return "Embed Koppelen";
  517. case "pl": return "Embed &#321;&#261;cze";
  518. case "pt": return "Ligação de Embed";
  519. case "ru": return "Embed &#1057;&#1089;&#1099;&#1083;&#1082;&#1072;";
  520. case "ar": return "&#1601;&#1578;&#1581; &#1601;&#1610; &#1604;&#1587;&#1575;&#1606; &#1580;&#1583;&#1610;&#1583;";
  521. }
  522. case "fscr": switch (lang) {
  523. case "zh-cn": return "&#20840;&#23631;&#38142;&#25509;";
  524. case "zh-tw": return "&#20840;&#23631;&#37832;&#25509;";
  525. case "ja": return "&#12501;&#12523;&#12473;&#12463;&#12522;&#12540;&#12531;&#12398;&#12522;&#12531;&#12463;";
  526. case "ko": return "&#51204;&#52404; &#47553;&#53356;";
  527. case "de": return "Auf dem ganzen Bildschirmverbindung";
  528. default:
  529. case "en": case "en-gb": return "Fullscreen Link";
  530. case "es": case "es-mx": return "Acoplamiento de plena pantalla";
  531. case "fr": return "Lien plein &#233;cran";
  532. case "it": return "Collegamento a schermo pieno";
  533. case "nl": return "Fullscreen Link";
  534. case "pl": return "Link do fullscreen";
  535. case "pt": return "Liga&#231;&#227;o da tela cheia";
  536. case "ru": return "Fullscreen &#1089;&#1089;&#1099;&#1083;&#1082;&#1072;";
  537. case "ar": return "&#1605;&#1604;&#1569; &#1575;&#1604;&#1588;&#1575;&#1588;&#1577;";
  538. }
  539. }
  540. return "";
  541. }
  542.  
  543. function get_text_Updater(lang,variable) {
  544. switch(variable) {
  545. case "disa": switch (lang) {
  546. default:
  547. case "en": case "en-gb": return "Updater Is Now Disabled";
  548. case "fr": return "La mise à jour est maintenant désactivé";
  549. }
  550. case "enab": switch (lang) {
  551. default:
  552. case "en": case "en-gb": return "Updater Is Now Enabled";
  553. case "fr": return "La mise à jour est maintenant activé";
  554. }
  555. case "foun": switch (lang) {
  556. default:
  557. case "en": case "en-gb": return "New Update Found";
  558. case "fr": return "Nouvelle mise &#224; jour trouv&#233;e";
  559. }
  560. case "dnow": switch (lang) {
  561. default:
  562. case "en": case "en-gb": return "Visit&nbsp;Install&nbsp;Page";
  563. case "fr": return "Visiter&nbsp;la&nbsp;page&nbsp;d'installation";
  564. }
  565. case "dlat": switch (lang) {
  566. default:
  567. case "en": case "en-gb": return "Later";
  568. case "fr": return "Plus&nbsp;tard";
  569. }
  570. }
  571. return "";
  572. }
  573.  
  574.  
  575. function test_lang(lang) {
  576. switch(lang) {
  577. case "zh-cn": case "zh-tw": case "ja": case "ko": case "de":
  578. case "en": case "en-gb": case "es": case "es-mx": case "fr":
  579. case "it": case "nl": case "pl": case "pt": case "ru":
  580. case "cs": case "sv": // Tchèque & Suédois
  581. case "ar": case "www": return true;
  582. }
  583. return false;
  584. }
  585.  
  586. //***************************************** Page settings ************************************************//
  587. // Get youtube locale (for languages support)
  588. function get_page_lang() {
  589. //== Use Mozilla browser language when youtube don't support it...
  590. var lang=String.substr(window.navigator.language,0,2).toLowerCase();
  591. if(lang=="ar") { // Arabic (ar)
  592. return lang;
  593. }
  594.  
  595. //== via URL
  596. var language=window.location.search.match(/[?&]hl=([^(\&|$)]*)/i);
  597. if(language!=null) {
  598. lang=language[1].replace(/_/,"-").toLowerCase();
  599. if(test_lang(lang)) {
  600. GM_setValue("Youtube_Download_Locale_Setting",lang);
  601. return lang;
  602. }
  603. lang=String.substr(lang,0,2);
  604. if(test_lang(lang)) {
  605. GM_setValue("Youtube_Download_Locale_Setting",lang);
  606. return lang;
  607. }
  608. }
  609.  
  610. //== via watch page
  611. var language=unsafeWindow.ytLocale;
  612. if(isDefined(language)) {
  613. lang=language.replace(/_/,"-").toLowerCase();
  614. if(test_lang(lang)) {
  615. GM_setValue("Youtube_Download_Locale_Setting",lang);
  616. return lang;
  617. }
  618. lang=String.substr(lang,0,2);
  619. if(test_lang(lang)) {
  620. GM_setValue("Youtube_Download_Locale_Setting",lang);
  621. return lang;
  622. }
  623. }
  624.  
  625. //== via old watch page setting
  626. lang=GM_getValue("Youtube_Download_Locale_Setting","www");
  627. return lang;
  628. }
  629.  
  630. function get_page_fmt() {
  631. var selected_fmt=window.location.search.match(/[?&]fmt=(\d*)/i);
  632. if(selected_fmt==null) { selected_fmt=0; } else { selected_fmt=selected_fmt[1]; }
  633. if(!(isPositiveInteger(selected_fmt))) { selected_fmt=0; }
  634. return(selected_fmt);
  635. }
  636.  
  637. function check_on_youtube() {
  638. if(window.location.host.match(/^\w+?\.youtube\.\w+$/i)) { return 1; }
  639. return 0;
  640. }
  641. function check_on_watchpage() {
  642. if(window.location.pathname.match(/^\/watch$/i)) { return 1; }
  643. return 0;
  644. }
  645. function check_on_youtubewatchpage() {
  646. return check_on_youtube() && check_on_watchpage();
  647. }
  648. function get_PlayerEmbed_element() {
  649. var playerEmbed = document.getElementById(YT_PLAYER_EMBED);
  650. if(playerEmbed) { return playerEmbed; }
  651. var wpd = document.getElementById(WATCH_PLAYER_DIV);
  652. if(wpd) {
  653. var temp=null;
  654. try { temp=wpd.getElementsByTagName("embed"); } catch(err) { temp=null; }
  655. if(temp && temp[0]) { temp[0].setAttribute('id',YT_PLAYER_EMBED); return temp[0]; }
  656. }
  657. return null;
  658. }
  659.  
  660. //************************************************************
  661. //***** Download Link ****************************************
  662. //************************************************************
  663. function clean_filename(filename) {
  664. // Clean filename (UNICODE Method)
  665. //filename = filename.replace(/\ /g,String.fromCharCode(65279));
  666. filename = filename.replace(/\:/g,String.fromCharCode(65306));
  667. filename = filename.replace(/\\/g,String.fromCharCode(65340));
  668. filename = filename.replace(/\//g,String.fromCharCode(65295));
  669. filename = filename.replace(/\</g,String.fromCharCode(65308));
  670. filename = filename.replace(/\>/g,String.fromCharCode(65310));
  671. filename = filename.replace(/\*/g,String.fromCharCode(65290));
  672. filename = filename.replace(/\?/g,String.fromCharCode(65311));
  673. filename = filename.replace(/\"/g,String.fromCharCode(65282));
  674. filename = filename.replace(/\|/g,String.fromCharCode(65372));
  675. // Clean filename (Underline Method)
  676. //filename = filename.replace(/[\:\\\/\<\>\?\*\"\|]/g, "_");
  677. return filename;
  678. }
  679.  
  680. function get_clean_flashvars(flashvars) {
  681. if(CLEAN_FLASHVARS<=0) { return flashvars; }
  682.  
  683. flashvars=flashvars+'&';
  684. var res; var res_annotations; var res_subtitles; var newfv='';
  685. do {
  686. res=flashvars.match(/^([^=]+?)\=([^\&]*?)\&(.*?)$/i);
  687. if(!res) { break; }
  688. var variable=res[1];
  689. var value=res[2];
  690. flashvars=res[3];
  691. if(DISABLE_ANNOTATIONS>0) { res_annotations=false; } else { res_annotations=variable.match(/^(iv_module|iv_storage_server)$/i); }
  692. if(DISABLE_SUBTITLES>0) { res_subtitles=false; } else { res_subtitles=variable.match(/^(subtitle_module|ttsurl)$/i); }
  693. res=variable.match(/^(BASE_YT_URL|rel|vq|ftm_map|video_id|t|sk|hl|fs|playnext|enablejsapi|autoplay)$/i)
  694. if(res || res_annotations || res_subtitles) {
  695. if(newfv!='') newfv+='&';
  696. newfv+=variable+'='+value;
  697. }
  698. } while(true);
  699.  
  700. return newfv;
  701. }
  702.  
  703. function add_ext(filename,fmt) {
  704. if(fmt==13 || fmt==17) { return(filename+".3gp"); }
  705. if(fmt==18 || fmt==22) { return(filename+".mp4"); }
  706. return(filename+".flv");
  707. }
  708.  
  709. function url_fmt(fmt) {
  710. if(fmt==0) { return(""); }
  711. return("&fmt="+fmt);
  712. }
  713.  
  714. function get_fmt_array(flashvars) {
  715. var fmt_array=[]; fmt_array[0]=true;
  716. if(!flashvars) { return fmt_array; }
  717. var fmt_map = flashvars.match(/fmt_map\=([^(\&|$)]*)/i);
  718. if(!fmt_map) { return fmt_array; }
  719. if(fmt_map[1]=='') { return fmt_array; }
  720. fmt_array[0]=false;
  721. fmt_map = fmt_map[1]+',';
  722. while(fmt_map=fmt_map.match(/^(\d+)[^,]*,(.*)$/)) {
  723. fmt_array[fmt_map[1]]=true;
  724. fmt_map=fmt_map[2];
  725. }
  726. return fmt_array;
  727. }
  728.  
  729. function get_dl_fmt(fmt,flashvars,quality_setting) {
  730. var wide=(unsafeWindow.isWidescreen==true);
  731. var HDAvailable=(unsafeWindow.isHDAvailable==true);
  732. var fmt_first = flashvars.match(/fmt_map\=(\d+)/i);
  733. if(fmt_first) { fmt_first=fmt_first[1]; } else { fmt_first=0; }
  734. var fmt_array=get_fmt_array(flashvars);
  735. var dl_fmt=fmt;
  736. switch(quality_setting) {
  737. case 1:
  738. if(fmt_array[ 0]) { dl_fmt= 0; } // If no fmt_map, then the displayed video is LQ-FLV1
  739. if(fmt_array[ 5]) { dl_fmt= 5; }
  740. if(fmt_array[34]) { dl_fmt=34; } // fmt_map=34 is the new default
  741. break;
  742. case 2:
  743. dl_fmt=fmt_first; // Set the quality to the first one detected in the fmt_map
  744. if(HDAvailable || fmt_array[22]) { dl_fmt=22; } // Set to HD if available
  745. break;
  746. case 3:
  747. dl_fmt=18; // Default -> Set HQ-MPG4
  748. if((fmt==22) && (!fmt_array[22])) { dl_fmt=18; } // No HD-MPG4 -> Set HQ-MPG4
  749. if((fmt==18) && (!fmt_array[18])) { dl_fmt=FMT_HIGH_QUALITY_FLV; } // No HQ-MPG4 -> Set HQ-FLV1
  750. if(fmt_array[22] || HDAvailable) { dl_fmt=22; } // HD Available -> Set HD-MPG4
  751. break;
  752. }
  753. return dl_fmt;
  754. }
  755.  
  756. function add_dl_qual_links(page_lang, selected_fmt) {
  757. var wvt = document.getElementById(WATCH_TITLE_DIV);
  758. if(!(wvt)) { show_alert('Download Link Disabled : "'+WATCH_TITLE_DIV+'" not found'); return; }
  759. var playerEmbed = get_PlayerEmbed_element();
  760. var flashvars='';
  761. if(playerEmbed) { // Get flashvars from the embed video
  762. flashvars = playerEmbed.getAttribute('flashvars');
  763. } else { // Get flashvars from the fullscreen link
  764. flashvars = get_fullscreenURL();
  765. }
  766. if(!flashvars) { show_alert('Download Link Disabled : "flashvars" not found'); return; }
  767.  
  768. var Options_title = HtmlUnicodeDecode(get_text_DL(page_lang,"omenu"));
  769.  
  770. var t_id = flashvars.match(/\&t=([^(\&|$)]*)/i)[1];
  771. var video_id = flashvars.match(/video_id=([^(\&|$)]*)/i)[1];
  772. var video_url = window.location.protocol+'//'+window.location.host+'/get_video?video_id='+video_id+'&t='+t_id;
  773.  
  774. // Retrieve fmt
  775. var download_fmt = get_dl_fmt(selected_fmt,flashvars,GM_getValue("Youtube_Download_Quality_Setting",2));
  776.  
  777. // === Add the download link and the filename ready to copy
  778. // Retrieve filename
  779. var filename = clean_filename(wvt.getElementsByTagName("h1")[0].textContent);
  780. if(filename.length<1) {filename="video";}
  781.  
  782. // Getting BackgroundColor and BorderColor
  783. var title_bg_color="#EEEEEE";
  784. var title_border_color="#CCCCCC";
  785. var wcvd = document.getElementById(WATCH_VIDEO_INFO);
  786. if (wcvd) {
  787. title_bg_color=window.getComputedStyle(wcvd, null).backgroundColor;
  788. title_border_color=window.getComputedStyle(wcvd, null).borderTopColor;
  789. }
  790.  
  791. // Insert the new element code
  792. var newElement = document.createElement('div');
  793. newElement.setAttribute('style','margin:6px 0 6px 0; padding:3px 2px; border: 1px solid transparent');
  794. newElement.style.backgroundColor=title_bg_color;
  795. newElement.style.borderColor=title_border_color;
  796. var newElement1 = document.createElement('div');
  797. newElement1.setAttribute('style','position:absolute');
  798. newElement.appendChild(newElement1);
  799. var newElement2 = document.createElement('table');
  800. //newElement2.setAttribute('class','vListBox');
  801. newElement2.setAttribute('style','width:100%; height:18px; padding:0px');
  802. var newElement2tr = document.createElement('tr');
  803. var newElement2td1 = document.createElement('td');
  804. newElement2td1.setAttribute('style','width:18px; padding-left:2px;');
  805. newElement2td1.setAttribute('lang','fr');
  806. var newElement2td1Div = document.createElement('div');
  807. newElement2td1Div.setAttribute('title',Options_title);
  808. newElement2td1Div.setAttribute('style','line-height:18px;font-size:18px;cursor:pointer; color:'+COLOR_DL_OPTIONS_TEXT+' !important; background:'+COLOR_DL_OPTIONS_BACKGROUND+' !important; border: 1px solid '+COLOR_DL_OPTIONS_BORDER+' !important; margin:-2px;');
  809. newElement2td1Div.textContent=String.fromCharCode(10070);
  810. user_select(newElement2td1,'none');
  811. newElement2td1.appendChild(newElement2td1Div);
  812. newElement2tr.appendChild(newElement2td1);
  813. var newElement2td2 = document.createElement('td');
  814. newElement2td2.setAttribute('style','width:auto; padding:0 3px 0 5px; white-space:nowrap;');
  815. var newElement2td2A = document.createElement('a');
  816. newElement2td2A.setAttribute('target','_blank');
  817. newElement2td2A.setAttribute('class','hLink');
  818. newElement2td2A.setAttribute('title',filename);
  819. newElement2td2A.setAttribute('href',video_url+url_fmt(download_fmt));
  820. newElement2td2A.textContent=HtmlUnicodeDecode(get_text_DL(page_lang,"dlink"));
  821. newElement2td2.appendChild(newElement2td2A);
  822. user_select(newElement2td2,'none');
  823. newElement2tr.appendChild(newElement2td2);
  824. var newElement2td3 = document.createElement('td');
  825. newElement2td3.setAttribute('style','width:100%;');
  826. var newElement2td3Div = document.createElement('div');
  827. var newElement2td3Input = document.createElement('input');
  828. newElement2td3Input.setAttribute('style','border:0; width:500px; background:inherit !important; color:inherit !important;');
  829. newElement2td3Input.setAttribute('type','text');
  830. newElement2td3Input.setAttribute('readonly','readonly');
  831. newElement2td3Input.setAttribute('onClick','this.focus();this.select();');
  832. newElement2td3Input.setAttribute('value',add_ext(filename,download_fmt));
  833. //user_select(newElement2td3Input,'all');
  834. newElement2td3Div.appendChild(newElement2td3Input);
  835. newElement2td3.appendChild(newElement2td3Div);
  836. newElement2tr.appendChild(newElement2td3);
  837. newElement2.appendChild(newElement2tr);
  838. newElement.appendChild(newElement2);
  839. wvt.parentNode.insertBefore(newElement, wvt);
  840. // Resize the inputbox
  841. newElement2td3Input.style.width=newElement2td3Input.parentNode.clientWidth+"px";
  842.  
  843. // Hiding the title
  844. if (ENABLE_TITLE_HIDING) { wvt.style.display = 'none'; }
  845.  
  846. return Array(newElement1,newElement2td1);
  847. }
  848.  
  849. function set_quality(quality, download_link_table, selected_fmt) {
  850. // Set new quality value
  851. GM_setValue("Youtube_Download_Quality_Setting",quality);
  852.  
  853. // Retrieve fmt
  854. var download_fmt=0;
  855. var playerEmbed = get_PlayerEmbed_element();
  856. var flashvars='';
  857. if(playerEmbed) { // Get flashvars from the embed video
  858. flashvars = playerEmbed.getAttribute('flashvars');
  859. } else { // Get flashvars from the fullscreen link
  860. flashvars = get_fullscreenURL();
  861. }
  862. if(flashvars) {
  863. download_fmt = get_dl_fmt(selected_fmt,flashvars,quality);
  864. }
  865.  
  866. // Change download link
  867. var linkdl = download_link_table.getElementsByTagName('a')[0];
  868. if (linkdl) {
  869. var linktext = linkdl.href.replace(/(\&?fmt\=\d+)/gi,"");
  870. linkdl.href=linktext+url_fmt(download_fmt);
  871. }
  872.  
  873. // Change filename
  874. var YDF = download_link_table.getElementsByTagName('input')[0];
  875. if (YDF) {
  876. var filename= YDF.value.match(/^(.*)\.[\w\d]{3,4}$/);
  877. if(filename!=null) { YDF.value=add_ext(filename[1],download_fmt); }
  878. }
  879. }
  880.  
  881. function menu_quality(quality_menu, quality) {
  882. // Change the position of the ">" in the menu box and close it
  883. if(quality_menu) {
  884. var div_Elem=quality_menu.getElementsByTagName("div");
  885. div_Elem[0].style.visibility="hidden";
  886. div_Elem[1].style.visibility="hidden";
  887. div_Elem[2].style.visibility="hidden";
  888. div_Elem[quality-1].style.visibility="visible";
  889. }
  890. }
  891.  
  892. function menu_autoplay(autoplay_menu, select) {
  893. // Change the position of the ">" in the menu box and close it
  894. if(autoplay_menu) {
  895. var div_Elem=autoplay_menu.getElementsByTagName("div");
  896. div_Elem[0].style.visibility="hidden";
  897. div_Elem[1].style.visibility="hidden";
  898. div_Elem[2].style.visibility="hidden";
  899. div_Elem[select].style.visibility="visible";
  900. }
  901. }
  902.  
  903. function event_setQuality(quality_select, selected_fmt) {
  904. var quality=quality_select.value;
  905. var quality_menu=quality_select.parentNode;
  906. switch (quality) {
  907. case 1: case 2: case 3:
  908. menu_quality(quality_menu, quality);
  909. set_quality(quality, quality_menu.parentNode.parentNode.nextSibling, selected_fmt);
  910. quality_menu.parentNode.style.display="none";
  911. }
  912. }
  913.  
  914. function event_autoplay(autoplay_select) {
  915. var select=autoplay_select.value;
  916. var autoplay_menu=autoplay_select.parentNode;
  917. switch (select) {
  918. case 0: case 1: case 2:
  919. menu_autoplay(autoplay_menu, select);
  920. GM_setValue("Youtube_Download_Autoplay_Setting",select);
  921. autoplay_menu.parentNode.style.display="none";
  922. }
  923. }
  924.  
  925. function make_options_menu(page_lang, selected_fmt, posMenuelem, OpenMenuElem) {
  926. if(posMenuelem && OpenMenuElem) {
  927. //== Make a menubox for Quality setting
  928. var MenuElem = document.createElement('div');
  929. MenuElem.setAttribute("style", "display:none; position: absolute; z-index: 99; margin:0; padding:0; width: 890px");
  930.  
  931. var arrow = document.createElement('div')
  932. arrow.setAttribute('style','float:left; width:1em; font-weight:bold; color:'+COLOR_DL_POPUP_ARROW+' !important;');
  933. arrow.textContent='>';
  934.  
  935. var u1_Elem = document.createElement('ul');
  936. u1_Elem.setAttribute("style","float:left; list-style-type:none; cursor:pointer; margin:1px; padding:0; border: 1px solid "+COLOR_DL_POPUP_BORDER+" !important; background-color: "+COLOR_DL_POPUP_BG_BLUE_OUT+";width:540px;");
  937. var li_Elem1=new Array();
  938. for(var h=0;h<=2;h++) {
  939. li_Elem1[h] = document.createElement('li');
  940. li_Elem1[h].setAttribute("style","margin:0; padding:5px; color:"+COLOR_DL_POPUP_TEXT+" !important;");
  941. li_Elem1[h].appendChild(arrow.cloneNode(true));
  942. li_Elem1[h].appendChild(document.createTextNode(HtmlUnicodeDecode(get_text_DL(page_lang,"qual"+(h+1)))));
  943. li_Elem1[h].addEventListener('mouseover' , function() { this.style.backgroundColor=COLOR_DL_POPUP_BG_BLUE_IN; }, true);
  944. li_Elem1[h].addEventListener('mouseout' , function() { this.style.backgroundColor=""; }, true);
  945. li_Elem1[h].setAttribute('value',h+1);
  946. li_Elem1[h].addEventListener('click' , function() { event_setQuality(this, selected_fmt); }, true);
  947. u1_Elem.appendChild(li_Elem1[h]);
  948. }
  949. MenuElem.appendChild(u1_Elem);
  950.  
  951. //== Make a menubox for autostart
  952. var u2_Elem = document.createElement('ul');
  953. u2_Elem.setAttribute("style","float:left; list-style-type:none; cursor:pointer; margin:1px; padding:0; border: 1px solid "+COLOR_DL_POPUP_BORDER+" !important; background-color: "+COLOR_DL_POPUP_BG_RED_OUT+"; width:340px;");
  954. var li_Elem2=new Array();
  955. for(var h=0;h<=2;h++) {
  956. li_Elem2[h] = document.createElement('li');
  957. li_Elem2[h].setAttribute("style","margin:0; padding:5px; color:"+COLOR_DL_POPUP_TEXT+" !important;");
  958. if(h<2) { li_Elem2[h].appendChild(arrow.cloneNode(true)); } else { li_Elem2[h].appendChild(arrow); }
  959. li_Elem2[h].appendChild(document.createTextNode(HtmlUnicodeDecode(get_text_DL(page_lang,"auto"+(h+1)))));
  960. li_Elem2[h].addEventListener('mouseover' , function() { this.style.backgroundColor=COLOR_DL_POPUP_BG_RED_IN; }, true);
  961. li_Elem2[h].addEventListener('mouseout' , function() { this.style.backgroundColor=""; }, true);
  962. li_Elem2[h].setAttribute('value',h);
  963. li_Elem2[h].addEventListener('click' , function() { event_autoplay(this); }, true);
  964. u2_Elem.appendChild(li_Elem2[h]);
  965. }
  966. MenuElem.appendChild(u2_Elem);
  967.  
  968. // Select position of the menubox on top of the button
  969. user_select(MenuElem,'none');
  970. posMenuelem.appendChild(MenuElem);
  971. MenuElem.style.left = "-4px";
  972. MenuElem.style.top = (-2-getDisplayHeight(MenuElem))+"px";
  973.  
  974. //== Make the openbutton to link to the menubox (with display update of the autoplay setting)
  975. OpenMenuElem.addEventListener('click', function() { menu_autoplay(u2_Elem, GM_getValue("Youtube_Download_Autoplay_Setting",2)); swap_display(MenuElem); }, true);
  976.  
  977. // Update the menubox from the setting
  978. menu_quality (u1_Elem, GM_getValue("Youtube_Download_Quality_Setting" ,2));
  979. menu_autoplay(u2_Elem, GM_getValue("Youtube_Download_Autoplay_Setting",2));
  980. }
  981. }
  982.  
  983. //** === Download Link === **//
  984. function add_download_link(page_lang, selected_fmt) {
  985. if(check_on_youtubewatchpage()) {
  986. els=add_dl_qual_links(page_lang, selected_fmt);
  987. if(els) { make_options_menu(page_lang, selected_fmt, els[0], els[1]); }
  988. }
  989. }
  990.  
  991. //************************************************************
  992. //***** Quality Selector *************************************
  993. //************************************************************
  994. function add_quality_selector(page_lang, selected_fmt) {
  995. if(!check_on_youtubewatchpage()) { return; }
  996. var playerEmbed = get_PlayerEmbed_element();
  997. var wrv=document.getElementById(WATCH_RATINGS_VIEW);
  998. if(!wrv && playerEmbed) { wrv=playerEmbed.parentNode.nextSibling; }
  999. if(!wrv) { show_alert('Quality Selector Disabled : "'+WATCH_RATINGS_VIEW+'" and "'+YT_PLAYER_EMBED+'" not found'); return; }
  1000.  
  1001. // Delete the original video quality setting switch (Cosmetic change)
  1002. remove_watch_element(WATCH_QUAL_SETTING);
  1003.  
  1004. // Clean URL
  1005. var vurl = window.location.href;
  1006. //vurl=vurl.replace(/\#$/,"");
  1007. vurl=vurl.replace(/\&?fmt\=\d+(\&|$)/gi,"");
  1008. vurl=vurl.replace(/\&?feature\=(channel|relate|user|search)[^(\&|$)]*/gi,"");
  1009.  
  1010. var flashvars='';
  1011. if(playerEmbed) { // Get flashvars from the embed video
  1012. flashvars = playerEmbed.getAttribute('flashvars');
  1013. } else { // Get flashvars from the fullscreen link
  1014. flashvars = get_fullscreenURL();
  1015. }
  1016. var fmt_array=get_fmt_array(flashvars);
  1017.  
  1018. // Create links
  1019. var HDAvailable=(unsafeWindow.isHDAvailable==true);
  1020. var link1=null; var link2=null; var link3=null; var link4=null;
  1021. if(selected_fmt!=0) {
  1022. link1=document.createElement("a");
  1023. link1.setAttribute('class','hLink');
  1024. link1.setAttribute('href',vurl+url_fmt(0));
  1025. } else { link1=document.createElement("span"); link1.style.setProperty('color','inherit','important'); }
  1026. if(selected_fmt!=FMT_HIGH_QUALITY_FLV) {
  1027. link2=document.createElement("a");
  1028. if((fmt_array[FMT_HIGH_QUALITY_FLV]) || (selected_fmt!=0)) {
  1029. link2.setAttribute('class','hLink');
  1030. } else {
  1031. link2.style.setProperty('color',window.getComputedStyle(window.document.body,null).color,'important');
  1032. }
  1033. link2.setAttribute('href',vurl+url_fmt(FMT_HIGH_QUALITY_FLV));
  1034. } else { link2=document.createElement("span"); link2.style.setProperty('color','inherit','important'); }
  1035. if(selected_fmt!=18) {
  1036. link3=document.createElement("a");
  1037. link3.setAttribute('class','hLink');
  1038. link3.setAttribute('href',vurl+url_fmt(18));
  1039. } else { link3=document.createElement("span"); link3.style.setProperty('color','inherit','important'); }
  1040. if(selected_fmt!=22) {
  1041. link4=document.createElement("a");
  1042. if(fmt_array[22] || HDAvailable || (selected_fmt!=0)) {
  1043. link4.setAttribute('class','hLink');
  1044. } else {
  1045. link4.style.setProperty('color',window.getComputedStyle(window.document.body,null).color,'important');
  1046. }
  1047. link4.setAttribute('href',vurl+url_fmt(22));
  1048. } else { link4=document.createElement("span"); link4.style.setProperty('color','inherit','important'); }
  1049.  
  1050. link1.textContent = HtmlUnicodeDecode(get_text_QS(page_lang,"link1"));
  1051. link2.textContent = HtmlUnicodeDecode(get_text_QS(page_lang,"link2"));
  1052. link3.textContent = HtmlUnicodeDecode(get_text_QS(page_lang,"link3"));
  1053. link4.textContent = HtmlUnicodeDecode(get_text_QS(page_lang,"link4"));
  1054.  
  1055. link1.style.setProperty('font-weight','normal','important');
  1056. link2.style.setProperty('font-weight','normal','important');
  1057. link3.style.setProperty('font-weight','normal','important');
  1058. link4.style.setProperty('font-weight','normal','important');
  1059.  
  1060. if((selected_fmt== 0 ) || (!fmt_array[selected_fmt])) { link1.style.setProperty('font-weight','bold','important'); }
  1061. if((selected_fmt==FMT_HIGH_QUALITY_FLV) && (fmt_array[selected_fmt] )) { link2.style.setProperty('font-weight','bold','important'); }
  1062. if((selected_fmt==18 ) && (fmt_array[selected_fmt] )) { link3.style.setProperty('font-weight','bold','important'); }
  1063. if((selected_fmt==22 ) && (fmt_array[selected_fmt] )) { link4.style.setProperty('font-weight','bold','important'); }
  1064.  
  1065. // Change video size
  1066. var wide=(unsafeWindow.isWidescreen==true);
  1067. var low_quality=(selected_fmt<=6) || (selected_fmt==13) || (selected_fmt==17) || (selected_fmt==34);
  1068. if(playerEmbed) {
  1069. if(wide) {
  1070. if(ENABLE_WIDE_VIDEO_RESIZING && !(low_quality)) {
  1071. playerEmbed.parentNode.parentNode.style.width ='960px';
  1072. playerEmbed.parentNode.parentNode.style.height='606px';
  1073. playerEmbed.style.width ='960px';
  1074. playerEmbed.style.height='566px';
  1075. }
  1076. } else {
  1077. if(ENABLE_4DV3_VIDEO_RESIZING) {
  1078. if((ENABLE_4DV3_VIDEO_RESIZING==1) || (low_quality)) {
  1079. playerEmbed.style.height='505px';
  1080. } else {
  1081. playerEmbed.parentNode.parentNode.style.width ='960px';
  1082. playerEmbed.parentNode.parentNode.style.height='785px';
  1083. playerEmbed.style.width ='960px';
  1084. playerEmbed.style.height='745px';
  1085. }
  1086. }
  1087. }
  1088. }
  1089.  
  1090. // Add the Quality Video links
  1091. var newElement = document.createElement('div');
  1092. newElement.setAttribute('style','width:100%; margin:3px 0 10px 0;');
  1093. var table = document.createElement('table');
  1094. table.setAttribute('class','watch-comment-head');
  1095. table.setAttribute('style','text-align:center; width:100%; color:#880000 !important; border: 1px solid transparent');
  1096. table.style.backgroundColor="#F8F8F8";
  1097. table.style.borderColor="#CCCCCC";
  1098. newElement.appendChild(table);
  1099. var tr1 = document.createElement('tr');
  1100. tr1.setAttribute('style','color:inherit !important; border: none');
  1101. table.appendChild(tr1);
  1102. var td1 = document.createElement('td'); td1.appendChild(link1); tr1.appendChild(td1);
  1103. td1.setAttribute('style','color:inherit !important; padding-top:3px !important; padding-bottom:2px !important');
  1104. var td2 = document.createElement('td'); td2.appendChild(link3); tr1.appendChild(td2);
  1105. td2.setAttribute('style','color:inherit !important; padding-top:3px !important; padding-bottom:2px !important');
  1106.  
  1107. var tr2 = document.createElement('tr');
  1108. tr2.setAttribute('style','color:inherit !important');
  1109. table.appendChild(tr2);
  1110. var td3 = document.createElement('td'); td3.appendChild(link2); tr2.appendChild(td3);
  1111. td3.setAttribute('style','color:inherit !important; padding-bottom:3px !important; padding-top:2px !important');
  1112. var td4 = document.createElement('td'); td4.appendChild(link4); tr2.appendChild(td4);
  1113. td4.setAttribute('style','color:inherit !important; padding-bottom:3px !important; padding-top:2px !important');
  1114. user_select(newElement,'none');
  1115. wrv.parentNode.insertBefore(newElement, wrv);
  1116. }
  1117.  
  1118. //******************************
  1119. //*** Image Preview Rollover ***
  1120. //******************************
  1121. var image_state=new Array;
  1122. var image_count=new Array;
  1123. var image_cache=new Array;
  1124.  
  1125. function change_image(element) {
  1126. const MAX_IMG=3;
  1127. const colorlist=["#CC88FF","#CC0000","#00AA00","#0000DD"];
  1128. var idvideo=element.getAttribute('qlicon');
  1129. if(!idvideo) { return; }
  1130.  
  1131. image_count[idvideo]=(image_count[idvideo] % 3)+1;
  1132.  
  1133. if(isUndefined(image_cache[idvideo])) {
  1134. var url_img=element.getAttribute('src');
  1135. var imgpath=url_img.match(/^(.*\/).*?(\.jpg)$/i);
  1136. if(!imgpath) { return; }
  1137.  
  1138. image_cache[idvideo]=new Array;
  1139. image_cache[idvideo][0]=false;
  1140. for(var h=1;h<=MAX_IMG;h++) {
  1141. url_img=imgpath[1]+h+imgpath[2];
  1142. image_cache[idvideo][h]=new Image();
  1143. image_cache[idvideo][h].src=url_img;
  1144. }
  1145. }
  1146.  
  1147. if(!(image_cache[idvideo][0])) {
  1148. var nbcomplete=0;
  1149. for(var h=1;h<=MAX_IMG;h++) { if (image_cache[idvideo][h].complete == true) { nbcomplete++; } }
  1150. if(nbcomplete==0) {
  1151. image_count[idvideo]=0;
  1152. } else {
  1153. if(nbcomplete>=MAX_IMG) {
  1154. image_cache[idvideo][0]=true;
  1155. } else {
  1156. while (image_cache[idvideo][image_count[idvideo]].complete != true) { image_count[idvideo]=(image_count[idvideo] % 3)+1; }
  1157. }
  1158. }
  1159. }
  1160.  
  1161. element.style.borderColor="#F0F0F0";
  1162. if(element.className=='vimg50') { element.parentNode.parentNode.style.borderColor=colorlist[image_count[idvideo]]; }
  1163. else { element.parentNode.parentNode.parentNode.style.borderColor=colorlist[image_count[idvideo]]; }
  1164.  
  1165.  
  1166. if(image_count[idvideo]>0) {
  1167. element.src=image_cache[idvideo][image_count[idvideo]].src;
  1168. if(image_state[idvideo]) { image_state[idvideo]=setTimeout( function() { change_image(element); }, ROLLOVER_DELAY_CONT); }
  1169. } else {
  1170. if(image_state[idvideo]) { image_state[idvideo]=setTimeout( function() { change_image(element); }, ROLLOVER_DELAY_LOAD); }
  1171. }
  1172. }
  1173.  
  1174. function start_rollover_event() {
  1175. var elImg=this;
  1176. var idvideo=elImg.getAttribute('qlicon');
  1177. if(!idvideo) { return; }
  1178. if(!(image_state[idvideo])) { image_state[idvideo]=setTimeout( function() { change_image(elImg); }, ROLLOVER_DELAY_INIT); }
  1179. }
  1180.  
  1181. function stop_rollover_event() {
  1182. var elImg=this;
  1183. var idvideo=elImg.getAttribute('qlicon');
  1184. if(!idvideo) { return; }
  1185. image_state[idvideo]=clearTimeout(image_state[idvideo]);
  1186. }
  1187.  
  1188. function bind_image_preview_rollover(elImg) {
  1189. var idvideo=elImg.getAttribute('qlicon');
  1190. if(!idvideo) {
  1191. var imgpath=elImg.getAttribute('src');
  1192. if(!imgpath) { return; }
  1193. var temp=imgpath.match(/^.*\/(.*?)\/default\.jpg$/);
  1194. if(!temp) { return; }
  1195. idvideo=temp[1];
  1196. elImg.setAttribute('qlicon',idvideo);
  1197. }
  1198. if(idvideo) {
  1199. elImg.setAttribute('title',''); // Clear title
  1200. if(isUndefined(image_state[idvideo])) { image_state[idvideo]=0; }
  1201. if(isUndefined(image_count[idvideo])) { image_count[idvideo]=0; }
  1202. elImg.addEventListener('mouseover' , start_rollover_event, true);
  1203. elImg.addEventListener('mouseout' , stop_rollover_event , true);
  1204. }
  1205. }
  1206.  
  1207. function image_preview_rollover(element) {
  1208. if(!(element)) { return; }
  1209. var links=null;
  1210. try { links=document.evaluate('.//img[@src]',element,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null); } catch(err) { links=null; }
  1211. if(links) {
  1212. var links_lg=links.snapshotLength;
  1213. for(var h=0;h<links_lg;h++) {
  1214. var image=links.snapshotItem(h);
  1215. if(image) { bind_image_preview_rollover(image); }
  1216. }
  1217. return;
  1218. }
  1219. try { links=element.getElementsByTagName("img"); } catch(err) { links=null; }
  1220. if(links) {
  1221. var links_nb=links.length;
  1222. for(var h=0;h<links_nb;h++) {
  1223. var image=links[h];
  1224. if(image) { bind_image_preview_rollover(image); }
  1225. }
  1226. return;
  1227. }
  1228. var msg="image_preview_rollover: Impossible to get links (XPath and getElementsByTagName failed)";
  1229. if(arguments.callee.getlink_fail) { show_alert(msg,0); }
  1230. else { arguments.callee.getlink_fail=1; show_alert(msg,1); }
  1231. }
  1232.  
  1233. //**********************
  1234. //*** change_links() ***
  1235. //**********************
  1236. function clean_link_and_add_fmt(link,fmt) {
  1237. // Clean URL
  1238. //link=link.replace(/\#$/,'');
  1239. link=link.replace(/\&?fmt\=\d+(\&|$)/gi,'');
  1240. link=link.replace(/\&?search\=[^(\&|$)]*/gi,'');
  1241. link=link.replace(/\&?feature\=(channel|relate|user|search)[^(\&|$)]*/gi,'');
  1242. // Add fmt to URL
  1243. return link+url_fmt(fmt);
  1244. }
  1245.  
  1246. function change_links_with_fmt(element,fmt) {
  1247. if(!(element)) { return; }
  1248. var links=null;
  1249. try { links=document.evaluate('.//a[@href]',element,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null); } catch(err) { links=null; }
  1250. if(links) {
  1251. var links_lg=links.snapshotLength;
  1252. for(var h=0;h<links_lg;h++) {
  1253. var link=links.snapshotItem(h).href;
  1254. if(link.match(/youtube\.\w+\/watch\?/i)) { links.snapshotItem(h).href=clean_link_and_add_fmt(link,fmt); }
  1255. }
  1256. return;
  1257. }
  1258. try { links=element.getElementsByTagName("a"); } catch(err) { links=null; }
  1259. if(links) {
  1260. var links_nb=links.length;
  1261. for(var h=0;h<links_nb;h++) {
  1262. var link=links[h].href;
  1263. if(link.match(/youtube\.\w+\/watch\?/i)) { links[h].href=clean_link_and_add_fmt(link,fmt); }
  1264. }
  1265. return;
  1266. }
  1267. var msg="change_links: Impossible to get links (XPath and getElementsByTagName failed)";
  1268. if(arguments.callee.getlink_fail) { show_alert(msg,0); }
  1269. else { arguments.callee.getlink_fail=1; show_alert(msg,1); }
  1270. }
  1271.  
  1272. function change_links_event() {
  1273. var el=this;
  1274. var fmt=GM_getValue("Youtube_Download_fmt",0);
  1275. change_links_with_fmt(el,fmt);
  1276. image_preview_rollover(el);
  1277. }
  1278.  
  1279. //** === change_links & image_preview_rollover === **//
  1280. function change_links(selected_fmt) {
  1281. var last_fmt=GM_getValue("Youtube_Download_fmt",0);
  1282. if(check_on_youtubewatchpage()) { //== Watch pages
  1283. if(last_fmt!=0) {
  1284. var wurl=window.location.href;
  1285. // Link from the Flash player ? (NR=1)
  1286. if (wurl.search(/[?&]NR\=\d+/i)>=0) {
  1287. wurl=wurl.replace(/\&?NR\=\d+(\&|$)/gi,'');
  1288. wurl=clean_link_and_add_fmt(wurl,last_fmt);
  1289. window.location.replace(wurl);
  1290. return;
  1291. }
  1292. }
  1293. GM_setValue("Youtube_Download_fmt",selected_fmt);
  1294. // Add fmt to watch-url-field
  1295. var wuf=document.getElementById(WATCH_URL_FIELD);
  1296. if(wuf) { wuf.setAttribute('value',clean_link_and_add_fmt(wuf.getAttribute('value'),selected_fmt)); }
  1297. // Change all links in the page
  1298. change_links_with_fmt(window.document.body, selected_fmt);
  1299. // Change links of User videos after loading it
  1300. var wmf=document.getElementById(WATCH_MORE_FROM);
  1301. if(wmf) { wmf.addEventListener ('load', change_links_event, true); }
  1302. // Change links of Related videos box after loading it
  1303. var wrvb=document.getElementById(WATCH_RELATED_VIDS);
  1304. if(wrvb) { wrvb.addEventListener('load', change_links_event, true); }
  1305. // Change links of Search box after loading it
  1306. var wsr=document.getElementById(WATCH_SEARCH_RES);
  1307. if(wsr) { wsr.addEventListener ('load', change_links_event, true); }
  1308. // Playlist panel support
  1309. var plst=document.getElementById(PLAYLIST_PANEL);
  1310. if(plst) { plst.addEventListener('load', change_links_event, true); }
  1311. image_preview_rollover(window.document.body);
  1312. } else { //== Other pages
  1313. // Change all links in the page
  1314. if(last_fmt!=0) { change_links_with_fmt(window.document.body, last_fmt); }
  1315. // == Youtube
  1316. if(check_on_youtube()) { image_preview_rollover(window.document.body); }
  1317. }
  1318. }
  1319.  
  1320. //************************************************************
  1321. //***** Media Controller *************************************
  1322. //************************************************************
  1323.  
  1324. function get_movie_player(ytplayer_name) {
  1325. if(!ytplayer_name) { ytplayer_name=YT_PLAYER_EMBED; }
  1326. ytplayer=unsafeWindow.document.getElementById(ytplayer_name);
  1327. if(!ytplayer) {
  1328. var msg='Media Controller warning : "'+ytplayer_name+'" not found';
  1329. if(arguments.callee.movie_player_fail) { show_alert(msg,0); }
  1330. else { arguments.callee.movie_player_fail=1; show_alert(msg); }
  1331. }
  1332. return ytplayer;
  1333. }
  1334.  
  1335. // N/A (-2), unstarted (-1), ended (0), playing (1), paused (2), buffering (3), video cued (5).
  1336. function get_player_state(ytplayer) {
  1337. var state=-1; try { state=ytplayer.getPlayerState(); } catch(err) { state=-2; }
  1338. if(state<=-2) {
  1339. show_alert('Media Controller warning : "'+ytplayer.id+'" state not available',0);
  1340. if(ytplayer.getAttribute('mc_embedtype')==1) {
  1341. // Check allowscriptaccess (must be 'always')
  1342. var allowScript=ytplayer.getAttribute('allowscriptaccess');
  1343. if(!(allowScript) || !(allowScript.match(/^always$/i))) {
  1344. ytplayer.setAttribute('allowscriptaccess','always');
  1345. show_alert('Media Controller Notice: Reloading the player "'+ytplayer.id+'" to allow script access');
  1346. player_revive(ytplayer.id); // Revive it...
  1347. }
  1348. }
  1349. }
  1350. return state;
  1351. }
  1352.  
  1353. // §§§ Step back §§§
  1354. var player_Step_back_timerid=new Array;
  1355. function player_stepback(ytplayer_name) {
  1356. if(player_Step_back_timerid[ytplayer_name]) { return; }
  1357. function player_stepback_check(ytplayer_name,frame_cursor,new_frame_cursor) {
  1358. player_Step_back_timerid[ytplayer_name]=null;
  1359. var ytplayer=get_movie_player(ytplayer_name);
  1360. if(ytplayer) {
  1361. var state=get_player_state(ytplayer);
  1362. if(state!=0 && state<2) { return; }
  1363. cur_frame_cursor=ytplayer.getCurrentTime();
  1364. if(cur_frame_cursor<frame_cursor) { return; }
  1365. new_frame_cursor=new_frame_cursor-0.05; if(new_frame_cursor<0) { new_frame_cursor=0; }
  1366. ytplayer.seekTo(new_frame_cursor,0);
  1367. if(new_frame_cursor<=0) { return; }
  1368. if(frame_cursor-new_frame_cursor>5) { return; } // Test for the Loading-start of the video
  1369. player_Step_back_timerid[ytplayer_name]=window.setTimeout( function() { player_stepback_check(ytplayer_name,frame_cursor,new_frame_cursor); }, 50);
  1370. }
  1371. }
  1372. var ytplayer=get_movie_player(ytplayer_name);
  1373. if(ytplayer) {
  1374. var state=get_player_state(ytplayer);
  1375. if(state<0) { return; }
  1376. ytplayer.pauseVideo();
  1377. state=get_player_state(ytplayer);
  1378. if(state!=0 && state<2) { return; }
  1379. frame_cursor=ytplayer.getCurrentTime();
  1380. if(frame_cursor<=0) { return; }
  1381. new_frame_cursor=frame_cursor-0.05; if(new_frame_cursor<0) { new_frame_cursor=0; }
  1382. ytplayer.seekTo(new_frame_cursor,0);
  1383. ytplayer.pauseVideo();
  1384. if(new_frame_cursor<=0) { return; }
  1385. player_Step_back_timerid[ytplayer_name]=window.setTimeout( function() { player_stepback_check(ytplayer_name,frame_cursor,new_frame_cursor); }, 50);
  1386. }
  1387. }
  1388.  
  1389. // §§§ Stop §§§
  1390. function player_stop(ytplayer_name) {
  1391. var ytplayer=get_movie_player(ytplayer_name);
  1392. if(ytplayer) {
  1393. var state=get_player_state(ytplayer);
  1394. if(state==-1) { window.setTimeout( function() { player_stop(); }, 50); return; }
  1395. if(state<0 || state>3) { return; }
  1396. ytplayer.pauseVideo(); ytplayer.seekTo(0,1); player_pause(ytplayer_name);
  1397. }
  1398. }
  1399.  
  1400. // §§§ Step forward §§§
  1401. function player_frame(ytplayer_name) {
  1402. var frame_cursor=0;
  1403. var ytplayer=get_movie_player(ytplayer_name);
  1404.  
  1405. function player_frame_pause(ytplayer) {
  1406. var state=get_player_state(ytplayer);
  1407. if(state<=0) { return; }
  1408. var new_pos=ytplayer.getCurrentTime();
  1409. //show_alert(frame_cursor+"/"+new_pos,0);
  1410. if(new_pos==frame_cursor || state==3) {
  1411. window.setTimeout( function() { player_frame_pause(ytplayer); }, 2);
  1412. return;
  1413. }
  1414. ytplayer.pauseVideo(ytplayer.id);
  1415. }
  1416.  
  1417. if(ytplayer) {
  1418. var state=get_player_state(ytplayer);
  1419. if(state<=0 || state==3) { return; }
  1420. frame_cursor=ytplayer.getCurrentTime();
  1421. ytplayer.playVideo(ytplayer_name);
  1422. player_frame_pause(ytplayer);
  1423. }
  1424. }
  1425.  
  1426. // §§§ Play §§§
  1427. function player_play(ytplayer_name) {
  1428. if(player_killed[ytplayer_name]==1) { player_revive(ytplayer_name); return; }
  1429. var ytplayer=get_movie_player(ytplayer_name);
  1430. if(ytplayer) {
  1431. var state=get_player_state(ytplayer);
  1432. if(state==-1) { window.setTimeout( function() { player_play(); }, 50); return; }
  1433. if(state<0) { return; }
  1434. ytplayer.playVideo();
  1435. }
  1436. }
  1437. // Revive the player
  1438. var player_killed=new Array;
  1439. function player_revive(ytplayer_name) {
  1440. var ytplayer = document.getElementById(ytplayer_name);
  1441. if(!(ytplayer)) { show_alert('Revive Failed : "'+ytplayer_name+'" not found'); return; }
  1442.  
  1443. // Make autoplay on
  1444. if(ytplayer.getAttribute('mc_embedtype')==1) {
  1445. var flashvars = ytplayer.getAttribute('flashvars');
  1446. var autoplay = flashvars.match(/autoplay\=(\d+)/i);
  1447. if(autoplay) { flashvars=flashvars.replace(/autoplay\=\d+/i,"autoplay=1"); }
  1448. else { flashvars=flashvars+'&autoplay=1'; }
  1449. ytplayer.setAttribute('flashvars',flashvars);
  1450. } else { // mc_embedtype==2
  1451. var srcvars = ytplayer.getAttribute('src');
  1452. var autoplay = srcvars.match(/autoplay\=(\d+)/i);
  1453. if(autoplay) { srcvars=srcvars.replace(/autoplay\=\d+/i,"autoplay=1"); }
  1454. else { srcvars=srcvars+'&autoplay=1'; }
  1455. ytplayer.setAttribute('src',srcvars);
  1456. }
  1457.  
  1458. // Revive the video player
  1459. flushNode(ytplayer);
  1460. player_killed[ytplayer_name]=0;
  1461.  
  1462. // Test if a loop is set
  1463. player_check_limit(ytplayer_name);
  1464. }
  1465.  
  1466. // §§§ Pause §§§
  1467. function player_pause(ytplayer_name) {
  1468. var ytplayer=get_movie_player(ytplayer_name);
  1469. if(ytplayer) {
  1470. var state=get_player_state(ytplayer);
  1471. if(state==-1 || state==3) { window.setTimeout( function() { player_pause(ytplayer_name); }, 50); return; }
  1472. if(state<=0) { return; }
  1473. ytplayer.pauseVideo();
  1474. }
  1475. }
  1476.  
  1477.  
  1478. // §§§ Begin §§§
  1479. function player_memo(ytplayer_name) {
  1480. var ytplayer=get_movie_player(ytplayer_name);
  1481. if(get_player_state(ytplayer)<-1) { return; }
  1482. var bt_state=document.getElementById(ytplayer_name+'-Memo_state');
  1483. if(ytplayer && bt_state) {
  1484. if(get_player_state(ytplayer)<=0) {
  1485. bt_state.style.display="none";
  1486. bt_state.setAttribute('value',0);
  1487. return;
  1488. }
  1489. if(bt_state.style.display=="none") {
  1490. var new_pos=ytplayer.getCurrentTime();
  1491. ytplayer.seekTo(new_pos,1); // Get real seek time
  1492. new_pos=ytplayer.getCurrentTime();
  1493. if(new_pos<0) { new_pos=0; }
  1494. bt_state.style.display="block";
  1495. bt_state.setAttribute('value',new_pos.toString());
  1496. } else {
  1497. bt_state.style.display="none";
  1498. bt_state.setAttribute('value',0);
  1499. }
  1500. }
  1501. }
  1502.  
  1503. // §§§ Loop §§§
  1504. function player_loop(ytplayer_name) {
  1505. var bt_state=document.getElementById(ytplayer_name+'-Loop_state');
  1506. if(bt_state) {
  1507. if(bt_state.style.display=="none") {
  1508. var ytplayer=get_movie_player(ytplayer_name);
  1509. if(!ytplayer) { return; }
  1510. if(get_player_state(ytplayer)<-1) { return; }
  1511. bt_state.style.display="block";
  1512. player_check_limit(ytplayer_name);
  1513. } else {
  1514. bt_state.style.display="none";
  1515. }
  1516. }
  1517. }
  1518.  
  1519. // §§§ Rewind §§§
  1520. function player_rewind(ytplayer_name) {
  1521. var ytplayer=get_movie_player(ytplayer_name);
  1522. if(ytplayer) {
  1523. var state=get_player_state(ytplayer);
  1524. if(state<0) { return; }
  1525. var memo_pos=0;
  1526. var memo_state=document.getElementById(ytplayer_name+'-Memo_state');
  1527. if(memo_state) { memo_pos=parseFloat(memo_state.getAttribute('value'),9); }
  1528. var player_pos=ytplayer.getCurrentTime();
  1529. if(memo_pos>=player_pos) {
  1530. ytplayer.seekTo(0,1);
  1531. } else {
  1532. ytplayer.seekTo(memo_pos,1);
  1533. }
  1534. }
  1535. }
  1536.  
  1537. // §§§ End §§§
  1538. function player_limit(ytplayer_name) {
  1539. var ytplayer=get_movie_player(ytplayer_name);
  1540. if(get_player_state(ytplayer)<-1) { return; }
  1541. var bt_state=document.getElementById(ytplayer_name+'-Limit_state');
  1542. if(ytplayer && bt_state) {
  1543. if(get_player_state(ytplayer)<0) {
  1544. bt_state.style.display="none";
  1545. bt_state.setAttribute('value',0);
  1546. return;
  1547. }
  1548. if(bt_state.style.display=="none") {
  1549. var new_pos=ytplayer.getCurrentTime();
  1550. if(new_pos<0) { new_pos=0; }
  1551. bt_state.style.display="block";
  1552. bt_state.setAttribute('value',new_pos.toString());
  1553. player_check_limit(ytplayer_name);
  1554. } else {
  1555. bt_state.style.display="none";
  1556. bt_state.setAttribute('value',0);
  1557. }
  1558. }
  1559. }
  1560.  
  1561. // §§§ Kill §§§ (Double click for this one)
  1562. function player_freeze(ytplayer_name) {
  1563. if(isUndefined(ytplayer_name)) { arguments.callee.freeze=0; return; }
  1564. if(arguments.callee.freeze==1) {
  1565. var ytplayer=get_movie_player(ytplayer_name);
  1566. if(!ytplayer) { return; }
  1567. if(get_player_state(ytplayer)>=-1) { ytplayer.pauseVideo(); ytplayer.stopVideo(); }
  1568. player_killed[ytplayer_name]=1;
  1569. return;
  1570. }
  1571. arguments.callee.freeze=1; window.setTimeout( function() { player_freeze(); }, 250);
  1572. }
  1573.  
  1574. // Need a serial of interrupts to check the end of the selection
  1575. var player_check_limit_timerid=new Array;
  1576. function player_check_limit_routine(ytplayer_name) {
  1577. if(player_killed[ytplayer_name]==1) { return; }
  1578. var ytplayer=get_movie_player(ytplayer_name);
  1579. if(!ytplayer) { return; }
  1580.  
  1581. var M_state=document.getElementById(ytplayer_name+'-Memo_state');
  1582. var L_state=document.getElementById(ytplayer_name+'-Limit_state');
  1583. var Loop_state=document.getElementById(ytplayer_name+'-Loop_state');
  1584. if(L_state && M_state && Loop_state) {
  1585. if(Loop_state.style.display=='none') { return; }
  1586.  
  1587. var state=get_player_state(ytplayer);
  1588. if(state<0) { player_check_limit_timerid[ytplayer_name]=window.setTimeout( function() { player_check_limit_timerid[ytplayer_name]=null; player_check_limit_routine(ytplayer_name); }, 1000); return; }
  1589.  
  1590. var pos=ytplayer.getCurrentTime();
  1591. // Test Infinite buffering
  1592. if(state==3) { // video buffering
  1593. if(pos>ytplayer.getDuration()-0.5) {
  1594. if(ytplayer.getVideoStartBytes()+ytplayer.getVideoBytesLoaded()>=ytplayer.getVideoBytesTotal())
  1595. { state=0; }
  1596. }
  1597. }
  1598.  
  1599. var vmemo=parseFloat(M_state.getAttribute('value'),9);
  1600. var vlimit=parseFloat(L_state.getAttribute('value'),9);
  1601. if((pos>=vlimit && L_state.style.display!='none') || state==0) { ytplayer.seekTo(vmemo,1); if(state==0) { player_play(ytplayer_name); } }
  1602.  
  1603. // On watch page, onMediaControllerPlayerStateChange take care of the video end, so we end here
  1604. if(L_state.style.display=='none' && check_on_youtubewatchpage()) { return; }
  1605. player_check_limit_timerid[ytplayer_name]=window.setTimeout( function() { player_check_limit_timerid[ytplayer_name]=null; player_check_limit_routine(ytplayer_name); }, 50);
  1606. return;
  1607. }
  1608. }
  1609. function player_check_limit(ytplayer_name) {
  1610. window.clearTimeout(player_check_limit_timerid[ytplayer_name]);
  1611. player_check_limit_routine(ytplayer_name);
  1612. }
  1613.  
  1614.  
  1615.  
  1616. function get_fullscreenURL() {
  1617. var url=unsafeWindow.fullscreenUrl;
  1618. if(url) { return window.location.protocol+"//"+window.location.host+url.toString(); }
  1619. return null;
  1620. }
  1621.  
  1622. function get_embedURL() {
  1623. var url=unsafeWindow.embedUrl;
  1624. if(url) { return url.toString(); }
  1625. return null;
  1626. }
  1627.  
  1628. // *********************************************************************************************************** //
  1629. // Bind Player Event for the End of video
  1630. function bind_movie_player_event() {
  1631. // Only for youtube watch pages
  1632. if(!check_on_youtubewatchpage()) { return; }
  1633.  
  1634. //~~~~~~~~ Startof innerscript ~~~~~~//
  1635. var innerscript = function() {
  1636.  
  1637. function check_movie_player() {
  1638. var playerEmbed = document.getElementById('__movie_player');
  1639. var wpd = document.getElementById('__watch-player-div');
  1640. if(wpd) {wpd.style.setProperty('padding-left','0','important');}
  1641. if(playerEmbed) { return; }
  1642. if(!wpd) { return; }
  1643. var temp=null;
  1644. try { temp=wpd.getElementsByTagName("embed"); } catch(err) { temp=null; }
  1645. if(temp && temp[0]) { temp[0].setAttribute('id','__movie_player'); }
  1646. }
  1647.  
  1648. function check_allowscriptaccess(ytplayer) { // Check for allowscriptaccess (must be 'always')
  1649. allowScript=ytplayer.getAttribute('allowscriptaccess');
  1650. if(!(allowScript) || !(allowScript.match(/^always$/i))) {
  1651. ytplayer.setAttribute('allowscriptaccess','always');
  1652. return 1;
  1653. }
  1654. return 0;
  1655. }
  1656.  
  1657. function set_autoplay(ytplayer,new_autoplay) {
  1658. var flashvars = ytplayer.getAttribute('flashvars');
  1659. var autoplay=flashvars.match(/autoplay\=(\d+)/i);
  1660. if(new_autoplay=="0") {
  1661. if(!(autoplay)) {
  1662. ytplayer.setAttribute('flashvars',flashvars+'&autoplay=0');
  1663. return 1;
  1664. } else if (autoplay[1]!=0) {
  1665. ytplayer.setAttribute('flashvars',flashvars.replace(/autoplay\=\d+/i,"autoplay=0"));
  1666. return 1;
  1667. }
  1668. } else {
  1669. if(new_autoplay=="1") { // Mode: Buffering at start...
  1670. try { ytplayer.pauseVideo(); } catch(err) {}
  1671. onMediaControllerPlayerStateChange.Buffering_StopPlayer=true;
  1672. }
  1673. if(autoplay) {
  1674. if(autoplay[1]!=1) {
  1675. ytplayer.setAttribute('flashvars',flashvars.replace(/autoplay\=\d+/i,"autoplay=1"));
  1676. return 1;
  1677. }
  1678. }
  1679. }
  1680. return 0;
  1681. }
  1682.  
  1683. function check_for_loop(ytplayer) {
  1684. var loop_state=window.document.getElementById('__movie_player-Loop_state');
  1685. if(loop_state.style.display!="none") {
  1686. var memo_state=window.document.getElementById('__movie_player-Memo_state');
  1687. if(memo_state) {
  1688. var memo_pos=parseFloat(memo_state.getAttribute('value'),9);
  1689. ytplayer.seekTo(memo_pos,1);
  1690. ytplayer.playVideo();
  1691. window.setTimeout( function() { ytplayer.pauseVideo(); ytplayer.playVideo(); }, 100);
  1692. return 1;
  1693. }
  1694. }
  1695. return 0;
  1696. }
  1697.  
  1698. function check_still_buffering() {
  1699. var player=window.document.getElementById('__movie_player');
  1700. if(!player) { return; }
  1701. var state=-1; try { state=player.getPlayerState(); } catch(err) { state=-2; }
  1702. if(state==3) {
  1703. if(player.getCurrentTime()>player.getDuration()-0.5) {
  1704. if(check_for_loop(player)) { return; }
  1705. // Original Youtube Script (if no loop)
  1706. try { handleWatchPagePlayerStateChange(0); } catch(err) {}
  1707. }
  1708. }
  1709. }
  1710.  
  1711. onMediaControllerPlayerStateChange = function(newState) {
  1712. var player=window.document.getElementById('__movie_player');
  1713. if(!player) { return; }
  1714. if(arguments.callee.Buffering_StopPlayer==true) { // Mode: Buffering at start...
  1715. if(newState<0 || newState>=3) {
  1716. try { ytplayer.pauseVideo(); } catch(err) {}
  1717. } else {
  1718. arguments.callee.Buffering_StopPlayer=false;
  1719. }
  1720. }
  1721. // Test Infinite buffering
  1722. if(newState==3) { // video is buffering
  1723. if(player.getCurrentTime()>player.getDuration()-0.5) {
  1724. if(player.getVideoStartBytes()+player.getVideoBytesLoaded()>=player.getVideoBytesTotal()) {
  1725. newState=0;
  1726. } else {
  1727. window.setTimeout( function() { check_still_buffering(); }, 1500);
  1728. }
  1729. }
  1730. }
  1731. // Check for Loop
  1732. if(newState==0) { if(check_for_loop(player)) { return; } }
  1733. // Original Youtube Script (if no loop)
  1734. try { handleWatchPagePlayerStateChange(newState); } catch(err) {}
  1735. }
  1736.  
  1737. function bind_MediaControllerPlayerStateChange() {
  1738. function isUndefined(x) { return x == null && x !== null; }
  1739. check_movie_player();
  1740. var ytplayer=window.document.getElementById('__movie_player');
  1741. if(ytplayer) {
  1742. // Flush to remove the initial event since there no removeEventListener ?
  1743. if(isUndefined(arguments.callee.initialflush)) { arguments.callee.initialflush=0; } // Don't do it since i see no problem :p
  1744. var flush=arguments.callee.initialflush; arguments.callee.initialflush=0;
  1745. flush += check_allowscriptaccess(ytplayer);
  1746. flush += set_autoplay(ytplayer,'__autoplay');
  1747. if(flush) { ytplayer.parentNode.replaceChild(ytplayer.cloneNode(true),ytplayer); }
  1748. var state=-1; try { state=ytplayer.getPlayerState(); } catch(err) { state=-2; }
  1749. if(state<0) { // Still loading the player...
  1750. window.setTimeout( function() { bind_MediaControllerPlayerStateChange(); }, 500);
  1751. } else { // Loaded, so add an event
  1752. try { g_YouTubePlayerIsReady=true; pollLocationHash(); if ('__autoplay'!=2) { ytplayer.pauseVideo(); } } catch(err) {}
  1753. ytplayer.addEventListener("onStateChange", "onMediaControllerPlayerStateChange");
  1754. try { ytplayer.addEventListener("onPlaybackQualityChange","onPlayerFormatChanged"); } catch(err) {}
  1755. }
  1756. }
  1757. }
  1758.  
  1759. // Redefine onYouTubePlayerReady (warning: can cause conflict with an other script)
  1760. onYouTubePlayerReady = function(playerid) {
  1761. bind_MediaControllerPlayerStateChange();
  1762. }
  1763. bind_MediaControllerPlayerStateChange();
  1764. } //~~~~~~~ Endof innerscript ~~~~~~~//
  1765.  
  1766. innerscript=innerscript.toString().replace(/__movie_player/g,YT_PLAYER_EMBED)
  1767. .replace(/__watch-player-div/,WATCH_PLAYER_DIV)
  1768. .replace(/__autoplay/g,GM_getValue("Youtube_Download_Autoplay_Setting",2));
  1769.  
  1770. var script=document.createElement("script");
  1771. //script.setAttribute('id','Youtube_Enhancer-PlayerStateChange');
  1772. script.setAttribute('type','text/javascript');
  1773. script.textContent="("+innerscript+")();";
  1774. document.body.appendChild(script);
  1775. }
  1776. // *********************************************************************************************************** //
  1777.  
  1778.  
  1779. //** === Media Controller === **//
  1780. function media_controller(page_lang,ytplayer_name,tag) {
  1781. var ytplayer = document.getElementById(ytplayer_name);
  1782. if(!ytplayer) { show_alert('Media Controller Disabled : "'+ytplayer_name+'" not found'); return; }
  1783. ytplayer.setAttribute('mc_embedtype',tag);
  1784.  
  1785. // Media Controller display mode
  1786. var lgref=480;
  1787. var ytplayer_width=getWidth(ytplayer);
  1788. if (check_on_youtubewatchpage()) { lgref=ytplayer_width; }
  1789.  
  1790. var MC_height=26; var MC_leftB2=167; var MC_topB2=-1; var MC_leftB3=lgref-166;
  1791. if(ytplayer_width<lgref-126) { MC_leftB2=(ytplayer_width-244)/2+117; MC_leftB3=ytplayer_width-30; }
  1792. if(ytplayer_width<300) { MC_leftB2=19; MC_leftB3=145; MC_topB2=26; }
  1793.  
  1794. var yt_p=ytplayer.parentNode; var yt_ns; var yt_c=ytplayer;
  1795. if(yt_p.tagName=="OBJECT") { yt_c=yt_p; yt_p.setAttribute('mc_embedtype',3); yt_ns=yt_p.nextSibling; yt_p=yt_p.parentNode; }
  1796. else { yt_ns=ytplayer.nextSibling; }
  1797.  
  1798. mediabar=document.createElement('div');
  1799. //mediabar.setAttribute('id','Media_Controller-'+ytplayer_name);
  1800. mediabar.setAttribute('style','position:relative; width:'+ytplayer_width+'px; margin-bottom:3px; padding-bottom:3px; '
  1801. +'height:'+(MC_height+MC_topB2-1)+'px; border:0px; font-family:Arial,sans-serif !important; color:'+COLOR_MC_TEXT_OUT+' !important;');
  1802. mediabar.setAttribute('lang','fr');
  1803.  
  1804. var loop_display_init='none'; // use 'block' (loop enabled at start) or 'none' (loop disabled at start)
  1805.  
  1806. // === Unicode player buttons ===
  1807.  
  1808. // Stop
  1809. var buttonStopDiv=document.createElement('div');
  1810. buttonStopDiv.setAttribute('style','position:absolute; top:-9px; left:6px; font-size:26px; line-height:38px; color:inherit !important;');
  1811. buttonStopDiv.textContent=String.fromCharCode(9632);
  1812.  
  1813. // Step back
  1814. var buttonDiv1=document.createElement('div');
  1815. buttonDiv1.setAttribute('style','position:absolute; top:0px; left:2px; font-size:18px; line-height:26px; color:inherit !important;');
  1816. buttonDiv1.textContent=String.fromCharCode(9668);
  1817. var buttonDiv2=document.createElement('div');
  1818. buttonDiv2.setAttribute('style','position:absolute; top:0px; left:20px; font-size:12px; line-height:26px; color:inherit !important;');
  1819. buttonDiv2.textContent=String.fromCharCode(9613);
  1820. var buttonStepBackDiv=document.createElement('div');
  1821. buttonStepBackDiv.setAttribute('style','color:inherit !important;');
  1822. buttonStepBackDiv.appendChild(buttonDiv1);
  1823. buttonStepBackDiv.appendChild(buttonDiv2);
  1824.  
  1825. // Step forward
  1826. var buttonDiv1=document.createElement('div');
  1827. buttonDiv1.setAttribute('style','position:absolute; top:0px; left:5px; font-size:12px; line-height:26px; color:inherit !important;');
  1828. buttonDiv1.textContent=String.fromCharCode(9613);
  1829. var buttonDiv2=document.createElement('div');
  1830. buttonDiv2.setAttribute('style','position:absolute; top:0px; left:8px; font-size:18px; line-height:26px; color:inherit !important;');
  1831. buttonDiv2.textContent=String.fromCharCode(9658);
  1832. var buttonStepForwardDiv=document.createElement('div');
  1833. buttonStepForwardDiv.setAttribute('style','color:inherit !important;');
  1834. buttonStepForwardDiv.appendChild(buttonDiv1);
  1835. buttonStepForwardDiv.appendChild(buttonDiv2);
  1836.  
  1837. // Play
  1838. var buttonPlayDiv=document.createElement('div');
  1839. buttonPlayDiv.setAttribute('style','position:absolute; top:-2px; left:5px; font-size:20px; line-height:30px; color:inherit !important;');
  1840. buttonPlayDiv.textContent=String.fromCharCode(9658);
  1841.  
  1842. // Pause
  1843. var buttonDiv1=document.createElement('div');
  1844. buttonDiv1.setAttribute('style','position:absolute; top:3px; left:8px; font-size:16px; line-height:21px; color:inherit !important;');
  1845. buttonDiv1.textContent=String.fromCharCode(9613);
  1846. var buttonDiv2=document.createElement('div');
  1847. buttonDiv2.setAttribute('style','position:absolute; top:3px; left:16px; font-size:16px; line-height:21px; color:inherit !important;');
  1848. buttonDiv2.textContent=String.fromCharCode(9613);
  1849. var buttonPauseDiv=document.createElement('div');
  1850. buttonPauseDiv.setAttribute('style','color:inherit !important;');
  1851. buttonPauseDiv.appendChild(buttonDiv1);
  1852. buttonPauseDiv.appendChild(buttonDiv2);
  1853.  
  1854. // Begin
  1855. var buttonDiv1=document.createElement('div');
  1856. buttonDiv1.setAttribute('style','position:absolute; top:-1px; left:6px; font-size:18px; line-height:28px; z-index:2; color:inherit !important;');
  1857. buttonDiv1.textContent=String.fromCharCode(12302);
  1858. var buttonDiv2=document.createElement('div');
  1859. buttonDiv2.setAttribute('id',ytplayer_name+'-Memo_state');
  1860. buttonDiv2.setAttribute('style','display:none; position:absolute; left:1px; top:1px; width:26px; height:'+(MC_height-2)+'px; z-index:1; background:'+COLOR_MC_TOGGLE_BEG_END+';');
  1861. buttonDiv2.setAttribute('value',0);
  1862. var buttonBeginDiv=document.createElement('div');
  1863. buttonBeginDiv.setAttribute('style','color:inherit !important;');
  1864. buttonBeginDiv.appendChild(buttonDiv1);
  1865. buttonBeginDiv.appendChild(buttonDiv2);
  1866.  
  1867. // Loop
  1868. var buttonDiv1=document.createElement('div');
  1869. buttonDiv1.setAttribute('style','position:absolute; top:1px; width:35px; left:4px; font-size:42px; line-height:28px; height:26px; text-align:left; z-index:2; color:inherit !important;');
  1870. buttonDiv1.textContent=String.fromCharCode(8617);
  1871. var buttonDiv2=document.createElement('div');
  1872. buttonDiv2.setAttribute('id',ytplayer_name+'-Loop_state');
  1873. buttonDiv2.setAttribute('style','display:'+loop_display_init+'; position:absolute; left:1px; top:1px; width:35px; height:'+(MC_height-2)+'px; z-index:1; background:'+COLOR_MC_TOGGLE_LOOP+';');
  1874. var buttonLoopDiv=document.createElement('div');
  1875. buttonLoopDiv.setAttribute('style','color:inherit !important;');
  1876. buttonLoopDiv.appendChild(buttonDiv1);
  1877. buttonLoopDiv.appendChild(buttonDiv2);
  1878.  
  1879. // Rewind
  1880. var buttonDiv1=document.createElement('div');
  1881. buttonDiv1.setAttribute('style','position:absolute; top:-1px; left:7px; font-size:14px; line-height:25px; color:inherit !important;');
  1882. buttonDiv1.textContent='|';
  1883. var buttonDiv2=document.createElement('div');
  1884. buttonDiv2.setAttribute('style','position:absolute; top:1px; left:9px; font-size:24px; line-height:26px; color:inherit !important;');
  1885. buttonDiv2.textContent=String.fromCharCode(9664);
  1886. var buttonRewindDiv=document.createElement('div');
  1887. buttonRewindDiv.setAttribute('style','color:inherit !important;');
  1888. buttonRewindDiv.appendChild(buttonDiv1);
  1889. buttonRewindDiv.appendChild(buttonDiv2);
  1890.  
  1891. // End
  1892. var buttonDiv1=document.createElement('div');
  1893. buttonDiv1.setAttribute('style','position:absolute; top:-1px; left:14px; font-size:18px; line-height:26px; z-index:2; color:inherit !important;');
  1894. buttonDiv1.textContent=String.fromCharCode(12303);
  1895. var buttonDiv2=document.createElement('div');
  1896. buttonDiv2.setAttribute('id',ytplayer_name+'-Limit_state');
  1897. buttonDiv2.setAttribute('style','display:none; position:absolute; left:1px; top:1px; width:26px; height:'+(MC_height-2)+'px; z-index:1; background:'+COLOR_MC_TOGGLE_BEG_END+';');
  1898. buttonDiv2.setAttribute('value',0);
  1899. var buttonEndDiv=document.createElement('div');
  1900. buttonEndDiv.setAttribute('style','color:inherit !important;');
  1901. buttonEndDiv.appendChild(buttonDiv1);
  1902. buttonEndDiv.appendChild(buttonDiv2);
  1903.  
  1904. // Kill
  1905. var buttonKillDiv=document.createElement('div');
  1906. buttonKillDiv.setAttribute('style','position:absolute; top:0px; left:2px; font-size:24px; line-height:27px; color:inherit !important;');
  1907. buttonKillDiv.textContent=String.fromCharCode(9760);
  1908.  
  1909.  
  1910. // === Media Controller Bar ===
  1911. // 1st group
  1912. var buttonStop=document.createElement('div');
  1913. buttonStop.setAttribute('title',HtmlUnicodeDecode(get_text_MC(page_lang,"stop")));
  1914. buttonStop.setAttribute('style','left: 0px; position:absolute; width:28px; height:'+MC_height+'px; border: 1px solid '+COLOR_MC_BORDER+' !important; cursor:pointer; background:'+COLOR_MC_BACKGROUND+' !important; color:inherit !important; border-top:0; overflow:hidden;');
  1915. buttonStop.appendChild(buttonStopDiv);
  1916. buttonStop.addEventListener('mouseover', function() { this.style.setProperty("color", COLOR_MC_TEXT_ACTION_IN, "important"); }, true);
  1917. buttonStop.addEventListener('mouseout', function() { this.style.setProperty("color", "inherit", "important"); }, true);
  1918. buttonStop.addEventListener('click', function() { player_stop(ytplayer_name); }, true);
  1919. user_select(buttonStop,'none');
  1920. mediabar.appendChild(buttonStop);
  1921.  
  1922. var buttonStepBack=document.createElement('div');
  1923. buttonStepBack.setAttribute('title',HtmlUnicodeDecode(get_text_MC(page_lang,"stepback")));
  1924. buttonStepBack.setAttribute('style','left:29px; position:absolute; width:28px; height:'+MC_height+'px; border: 1px solid '+COLOR_MC_BORDER+' !important; cursor:pointer; background:'+COLOR_MC_BACKGROUND+' !important; color:inherit !important; border-top:0; overflow:hidden;');
  1925. buttonStepBack.appendChild(buttonStepBackDiv);
  1926. buttonStepBack.addEventListener('mouseover', function() { this.style.setProperty("color", COLOR_MC_TEXT_ACTION_IN, "important"); }, true);
  1927. buttonStepBack.addEventListener('mouseout', function() { this.style.setProperty("color", "inherit", "important"); }, true);
  1928. buttonStepBack.addEventListener('click', function() { player_stepback(ytplayer_name); }, true);
  1929. user_select(buttonStepBack,'none');
  1930. mediabar.appendChild(buttonStepBack);
  1931.  
  1932. var buttonFrame=document.createElement('div');
  1933. buttonFrame.setAttribute('title',HtmlUnicodeDecode(get_text_MC(page_lang,"step")));
  1934. buttonFrame.setAttribute('style','left:58px; position:absolute; width:28px; height:'+MC_height+'px; border: 1px solid '+COLOR_MC_BORDER+' !important; cursor:pointer; background:'+COLOR_MC_BACKGROUND+' !important; color:inherit !important; border-top:0; overflow:hidden;');
  1935. buttonFrame.appendChild(buttonStepForwardDiv);
  1936. buttonFrame.addEventListener('mouseover', function() { this.style.setProperty("color", COLOR_MC_TEXT_ACTION_IN, "important"); }, true);
  1937. buttonFrame.addEventListener('mouseout', function() { this.style.setProperty("color", "inherit", "important"); }, true);
  1938. buttonFrame.addEventListener('click', function() { player_frame(ytplayer_name); }, true);
  1939. user_select(buttonFrame,'none');
  1940. mediabar.appendChild(buttonFrame);
  1941.  
  1942. var buttonPlay=document.createElement('div');
  1943. buttonPlay.setAttribute('title',HtmlUnicodeDecode(get_text_MC(page_lang,"play")));
  1944. buttonPlay.setAttribute('style','left:87px; position:absolute; width:28px; height:'+MC_height+'px; border: 1px solid '+COLOR_MC_BORDER+' !important; cursor:pointer; background:'+COLOR_MC_BACKGROUND+' !important; color:inherit !important; border-top:0; overflow:hidden;');
  1945. buttonPlay.appendChild(buttonPlayDiv);
  1946. buttonPlay.addEventListener('mouseover', function() { this.style.setProperty("color", COLOR_MC_TEXT_ACTION_IN, "important"); }, true);
  1947. buttonPlay.addEventListener('mouseout', function() { this.style.setProperty("color", "inherit", "important"); }, true);
  1948. buttonPlay.addEventListener('click', function() { player_play(ytplayer_name); }, true);
  1949. user_select(buttonPlay,'none');
  1950. mediabar.appendChild(buttonPlay);
  1951.  
  1952. var buttonPause=document.createElement('div');
  1953. buttonPause.setAttribute('title',HtmlUnicodeDecode(get_text_MC(page_lang,"pause")));
  1954. buttonPause.setAttribute('style','left:116px; position:absolute; width:28px; height:'+MC_height+'px; border: 1px solid '+COLOR_MC_BORDER+' !important; cursor:pointer; background:'+COLOR_MC_BACKGROUND+' !important; color:inherit !important; border-top:0; overflow:hidden;');
  1955. buttonPause.appendChild(buttonPauseDiv);
  1956. buttonPause.addEventListener('mouseover', function() { this.style.setProperty("color", COLOR_MC_TEXT_ACTION_IN, "important"); }, true);
  1957. buttonPause.addEventListener('mouseout', function() { this.style.setProperty("color", "inherit", "important"); }, true);
  1958. buttonPause.addEventListener('click', function() { player_pause(ytplayer_name); }, true);
  1959. user_select(buttonPause,'none');
  1960. mediabar.appendChild(buttonPause);
  1961.  
  1962.  
  1963. // 2nd group
  1964. var buttonMemo=document.createElement('div');
  1965. buttonMemo.setAttribute('title',HtmlUnicodeDecode(get_text_MC(page_lang,"begin")));
  1966. buttonMemo.setAttribute('style','left:'+MC_leftB2+'px; top:'+(MC_topB2+1)+'px; position:absolute; width:28px; height:'+MC_height+'px; border: 1px solid '+COLOR_MC_BORDER+' !important; cursor:pointer; background:'+COLOR_MC_BACKGROUND+' !important; color:inherit !important; border-top:0; overflow:hidden;');
  1967. buttonMemo.appendChild(buttonBeginDiv);
  1968. buttonMemo.addEventListener('mouseover', function() { this.style.setProperty("color", COLOR_MC_TEXT_TOGGLE_IN, "important"); }, true);
  1969. buttonMemo.addEventListener('mouseout', function() { this.style.setProperty("color", "inherit", "important"); }, true);
  1970. buttonMemo.addEventListener('click', function() { player_memo(ytplayer_name); }, true);
  1971. user_select(buttonMemo,'none');
  1972. mediabar.appendChild(buttonMemo);
  1973.  
  1974. var buttonLoop=document.createElement('div');
  1975. buttonLoop.setAttribute('title',HtmlUnicodeDecode(get_text_MC(page_lang,"loop")));
  1976. buttonLoop.setAttribute('style','left:'+(MC_leftB2+29)+'px; top:'+(MC_topB2+1)+'px; position:absolute; width:37px; height:'+MC_height+'px; border: 1px solid '+COLOR_MC_BORDER+' !important; cursor:pointer; background:'+COLOR_MC_BACKGROUND+' !important; color:inherit !important; border-top:0; overflow:hidden;');
  1977. buttonLoop.appendChild(buttonLoopDiv);
  1978. buttonLoop.addEventListener('mouseover', function() { this.style.setProperty("color", COLOR_MC_TEXT_TOGGLE_IN, "important"); }, true);
  1979. buttonLoop.addEventListener('mouseout', function() { this.style.setProperty("color", "inherit", "important"); }, true);
  1980. buttonLoop.addEventListener('click', function() { player_loop(ytplayer_name); }, true);
  1981. user_select(buttonLoop,'none');
  1982. mediabar.appendChild(buttonLoop);
  1983.  
  1984. var buttonRewind=document.createElement('div');
  1985. buttonRewind.setAttribute('title',HtmlUnicodeDecode(get_text_MC(page_lang,"rewind")));
  1986. buttonRewind.setAttribute('style','left:'+(MC_leftB2+67)+'px; top:'+(MC_topB2+1)+'px; position:absolute; width:28px; height:'+MC_height+'px; border: 1px solid '+COLOR_MC_BORDER+' !important; cursor:pointer; background:'+COLOR_MC_BACKGROUND+' !important; color:inherit !important; border-top:0; overflow:hidden;');
  1987. buttonRewind.appendChild(buttonRewindDiv);
  1988. buttonRewind.addEventListener('mouseover', function() { this.style.setProperty("color", COLOR_MC_TEXT_ACTION_IN, "important"); }, true);
  1989. buttonRewind.addEventListener('mouseout', function() { this.style.setProperty("color", "inherit", "important"); }, true);
  1990. buttonRewind.addEventListener('click', function() { player_rewind(ytplayer_name); }, true);
  1991. user_select(buttonRewind,'none');
  1992. mediabar.appendChild(buttonRewind);
  1993.  
  1994. var buttonLimit=document.createElement('div');
  1995. buttonLimit.setAttribute('title',HtmlUnicodeDecode(get_text_MC(page_lang,"end")));
  1996. buttonLimit.setAttribute('style','left:'+(MC_leftB2+96)+'px; top:'+(MC_topB2+1)+'px; position:absolute; width:28px; height:'+MC_height+'px; border: 1px solid '+COLOR_MC_BORDER+' !important; cursor:pointer; background:'+COLOR_MC_BACKGROUND+' !important; color:inherit !important; border-top:0; overflow:hidden;');
  1997. buttonLimit.appendChild(buttonEndDiv);
  1998. buttonLimit.addEventListener('mouseover', function() { this.style.setProperty("color", COLOR_MC_TEXT_TOGGLE_IN, "important"); }, true);
  1999. buttonLimit.addEventListener('mouseout', function() { this.style.setProperty("color", "inherit", "important"); }, true);
  2000. buttonLimit.addEventListener('click', function() { player_limit(ytplayer_name); }, true);
  2001. user_select(buttonLimit,'none');
  2002. mediabar.appendChild(buttonLimit);
  2003.  
  2004.  
  2005. // 3rd group
  2006. var buttonFreeze=document.createElement('div');
  2007. buttonFreeze.setAttribute('title',HtmlUnicodeDecode(get_text_MC(page_lang,"kill")));
  2008. buttonFreeze.setAttribute('style','left:'+MC_leftB3+'px; position:absolute; width:28px; height:'+MC_height+'px; border: 1px solid '+COLOR_MC_BORDER+' !important; cursor:pointer; background:'+COLOR_MC_BG_RED+' !important; color:inherit !important; border-top:0; overflow:hidden;');
  2009. buttonFreeze.appendChild(buttonKillDiv);
  2010. buttonFreeze.addEventListener('mouseover', function() { this.style.setProperty("color", COLOR_MC_TEXT_ACTION_IN, "important"); }, true);
  2011. buttonFreeze.addEventListener('mouseout', function() { this.style.setProperty("color", "inherit", "important"); }, true);
  2012. buttonFreeze.addEventListener('click', function() { player_freeze(ytplayer_name); }, true);
  2013. user_select(buttonFreeze,'none');
  2014. mediabar.appendChild(buttonFreeze);
  2015.  
  2016.  
  2017. // 4th group
  2018. if(check_on_youtubewatchpage()) {
  2019. var eurl=get_embedURL();
  2020. if(eurl) {
  2021. var buttonEUInner=document.createElement('div');
  2022. buttonEUInner.setAttribute('title',HtmlUnicodeDecode(get_text_MC(page_lang,"embed")));
  2023. buttonEUInner.setAttribute('style','color:#0000F0; font-size:14px; position:absolute; top:-1px; left:1px; width:38px; text-align:center; line-height:28px; color:'+COLOR_MC_TEXT_BLUE+' !important; text-decoration:none !important;');
  2024. buttonEUInner.textContent=String.fromCharCode(10065);
  2025.  
  2026. var buttonEU=document.createElement('div');
  2027. buttonEU.setAttribute('style','left:'+(lgref-108)+'px; position:absolute; width:39px; height:'+MC_height+'px; border: 1px solid '+COLOR_MC_BORDER+' !important; cursor:pointer; background:'+COLOR_MC_BG_BLUE_OUT+' !important; border-top:0;');
  2028. buttonEU.appendChild(buttonEUInner);
  2029. buttonEU.addEventListener('mouseover' , function() { this.style.setProperty("background",COLOR_MC_BG_BLUE_IN ,'important'); buttonEUInner.style.setProperty("text-decoration","underline","important"); }, true);
  2030. buttonEU.addEventListener('mouseout' , function() { this.style.setProperty("background",COLOR_MC_BG_BLUE_OUT,'important'); buttonEUInner.style.setProperty("text-decoration","none","important"); }, true);
  2031. buttonEU.addEventListener('click' , function() { player_pause(ytplayer_name); }, true);
  2032. user_select(buttonEU,'none');
  2033.  
  2034. var buttonEULink=document.createElement('a');
  2035. buttonEULink.setAttribute('href',eurl);
  2036. buttonEULink.setAttribute('target','_blank');
  2037. buttonEULink.appendChild(buttonEU);
  2038. mediabar.appendChild(buttonEULink);
  2039. } else { show_alert('Media Controller : Global variable for "Embed URL" not found',0); }
  2040.  
  2041. var fsurl=get_fullscreenURL();
  2042. if(fsurl) {
  2043. var buttonFSInner=document.createElement('div');
  2044. buttonFSInner.setAttribute('title',HtmlUnicodeDecode(get_text_MC(page_lang,"fscr")));
  2045. buttonFSInner.setAttribute('style','color:#0000F0; font-size:14px; position:absolute; top:-1px; left:1px; width:60px; text-align:center; line-height:28px; color:'+COLOR_MC_TEXT_BLUE+' !important; text-decoration:none !important;');
  2046. buttonFSInner.textContent=String.fromCharCode(8738,8194,8194,8194,10065);
  2047.  
  2048. var buttonFS=document.createElement('div');
  2049. buttonFS.setAttribute('style','left:'+(lgref-68)+'px; position:absolute; width:66px; height:'+MC_height+'px; border: 1px solid '+COLOR_MC_BORDER+' !important; cursor:pointer; background:'+COLOR_MC_BG_BLUE_OUT+' !important; border-top:0;');
  2050. buttonFS.appendChild(buttonFSInner);
  2051. buttonFS.addEventListener('mouseover' , function() { this.style.setProperty("background",COLOR_MC_BG_BLUE_IN ,'important'); buttonFSInner.style.setProperty("text-decoration","underline","important"); }, true);
  2052. buttonFS.addEventListener('mouseout' , function() { this.style.setProperty("background",COLOR_MC_BG_BLUE_OUT,'important'); buttonFSInner.style.setProperty("text-decoration","none","important"); }, true);
  2053. buttonFS.addEventListener('click' , function() { player_pause(ytplayer_name); }, true);
  2054. user_select(buttonFS,'none');
  2055.  
  2056. var buttonFSLink=document.createElement('a');
  2057. buttonFSLink.setAttribute('href',fsurl);
  2058. buttonFSLink.setAttribute('target','_blank');
  2059. buttonFSLink.appendChild(buttonFS);
  2060. mediabar.appendChild(buttonFSLink);
  2061. } else { show_alert('Media Controller : Global variable for "Fullscreen URL" not found',0); }
  2062. }
  2063. yt_p.insertBefore(mediabar, yt_ns);
  2064.  
  2065. // Horizontal offset fix
  2066. var leftdiff=getAbsoluteLeft(mediabar)-getAbsoluteLeft(ytplayer);
  2067. if(leftdiff!=0) { mediabar.style.left=(-leftdiff)+'px'; }
  2068.  
  2069. // Vertical offset fix
  2070. var ytplayer_height=getHeight(ytplayer);
  2071. var topdiff=getAbsoluteTop(mediabar)-ytplayer_height-getAbsoluteTop(ytplayer);
  2072. if(topdiff!=0) { mediabar.style.top=(-topdiff)+'px'; }
  2073.  
  2074. player_check_limit(ytplayer_name);
  2075. }
  2076.  
  2077. function check_jsapi(vars) { // Force enabling JS
  2078. var temp=vars.match(/enablejsapi\s*\=\s*(\d+)/i);
  2079. if(temp) { if(temp[1]!="1") { return vars.replace(/enablejsapi\s*\=\s*\d+/i,'enablejsapi=1'); } }
  2080. else { return vars+'&enablejsapi=1'; }
  2081. return vars;
  2082. }
  2083.  
  2084. function check_autoplay(vars) { // If autoplay_setting = manual -> Force autoplay to manual
  2085. if(GM_getValue("Youtube_Download_Autoplay_Setting",2)==0) {
  2086. var temp=vars.match(/autoplay\s*\=\s*(\d+)/i);
  2087. if(temp) { if(temp[1]!="0") { return vars.replace(/autoplay\s*\=\s*\d+/i,'autoplay=0'); } }
  2088. else { return vars+'&autoplay=0'; }
  2089. }
  2090. return vars;
  2091. }
  2092.  
  2093. function bind_player_with_media_controller(page_lang,player,number) {
  2094. if(player.getAttribute('mc_embedtype')) { return; } // Already binded
  2095. var src_name="src"; // EMBED and VIDEO Tag
  2096. if(player.nodeName.toUpperCase()=="OBJECT") { src_name="data"; } // OBJECT Tag
  2097. var player_src=player.getAttribute(src_name);
  2098. var needflush=false;
  2099. if(player_src.match(/^http\:\/\/(\w+\.)?youtube\.com\/\w+\//i)) { // Object Embeded youtube video
  2100. if(!player.id) { player.setAttribute('id','Youtube_movie-'+number); }
  2101. var new_player_src=check_autoplay(check_jsapi(player_src));
  2102. if(new_player_src!=player_src) { player.setAttribute(src_name,new_player_src); needflush=true; }
  2103. var asa = player.getAttribute('allowscriptaccess');
  2104. if (asa!='always') { player.setAttribute('allowscriptaccess','always'); needflush=true; }
  2105. if (needflush) { flushNode(player); }
  2106. media_controller(page_lang,player.id,2);
  2107. } else if(player_src.match(/^http\:\/\/(\w+\.)?ytimg\.com\//i)) { // Normal youtube video
  2108. if(!player.id) { player.setAttribute('id','Youtube_movie-'+number); }
  2109. var flashvars = player.getAttribute('flashvars');
  2110. var new_flashvars = get_clean_flashvars(flashvars);
  2111. new_flashvars = check_autoplay(check_jsapi(new_flashvars));
  2112. if(new_flashvars!=flashvars) { player.setAttribute('flashvars',new_flashvars); needflush=true; }
  2113. var asa = player.getAttribute('allowscriptaccess');
  2114. if (asa!='always') { player.setAttribute('allowscriptaccess','always'); needflush=true; }
  2115. if (needflush) { flushNode(player); }
  2116. media_controller(page_lang,player.id,1);
  2117. }
  2118. }
  2119.  
  2120. function bind_media_players(page_lang) {
  2121. var players=null;
  2122. try { players=document.evaluate('//embed[@src]',document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null); } catch(err) { players=null; }
  2123. if(players) {
  2124. var players_lg=players.snapshotLength;
  2125. for(var h=0;h<players_lg;h++) { bind_player_with_media_controller(page_lang,players.snapshotItem(h),h); }
  2126. return;
  2127. }
  2128. try { players=document.getElementsByTagName("embed"); } catch(err) { players=null; }
  2129. if(players) {
  2130. var players_lg=players.length;
  2131. for(var h=0;h<players_lg;h++) { bind_player_with_media_controller(page_lang,players[h],h); }
  2132. return;
  2133. }
  2134. var msg="Media Controller: Impossible to get media players (XPath and getElementsByTagName failed)";
  2135. show_alert(msg,1);
  2136. }
  2137.  
  2138. function add_media_controller(page_lang) {
  2139. bind_media_players(page_lang);
  2140. }
  2141.  
  2142. //******************************************** Updater ***************************************************//
  2143. function YouTube_Enhancer_Update_install(updateelem,Date_Now,Updater_url_dl) {
  2144. GM_setValue("Youtube_Enhancer_Updater_Date", Date_Now)
  2145. remove_element(updateelem);
  2146. //GM_openInTab(Updater_url_dl);
  2147. document.location.href=Updater_url_dl;
  2148. }
  2149.  
  2150. function YouTube_Enhancer_Update_later(updateelem,Date_Now) {
  2151. GM_setValue("Youtube_Enhancer_Updater_Date", Date_Now)
  2152. remove_element(updateelem);
  2153. }
  2154.  
  2155. function YouTube_Enhancer_Update_Display(page_lang,Updater_url_dl,Date_Now) {
  2156. if ( top.location.href!=window.location.href ) { return; }
  2157. var updateelem=document.createElement('div');
  2158. updateelem.setAttribute('lang','fr');
  2159. updateelem.setAttribute("style","position:fixed; top:0px; left:0px; right:0px; z-index:9998; color:#FFFFFF !important; background:#C080C0 !important; width:auto; text-align:center; font-family:arial,sans-serif; font-size:24px; line-height:24px; margin:2px; border: 3px solid #CC0088; border-right-width:24px;");
  2160. updateelem.textContent='Youtube Enhancer - '+HtmlUnicodeDecode(get_text_Updater(page_lang,"foun"))+': ';
  2161. var aelem1=document.createElement('a');
  2162. aelem1.setAttribute('style','text-decoration:none; cursor:pointer; color:#0000CC !important; font-weight: normal; font-style:normal;');
  2163. aelem1.setAttribute('title',Updater_url_dl);
  2164. //aelem1.setAttribute('href',Updater_url_dl);
  2165. aelem1.textContent=HtmlUnicodeDecode(get_text_Updater(page_lang,"dnow"));
  2166. updateelem.appendChild(aelem1);
  2167. var textelem=document.createTextNode(' / ');
  2168. updateelem.appendChild(textelem);
  2169. var aelem2=document.createElement('a');
  2170. aelem2.setAttribute('style','text-decoration:none; cursor:pointer; color:#0000CC !important; font-weight: normal; font-style:normal;');
  2171. aelem2.textContent=HtmlUnicodeDecode(get_text_Updater(page_lang,"dlat"));
  2172. updateelem.appendChild(aelem2);
  2173. var aelemX=document.createElement('a');
  2174. aelemX.setAttribute('style','position:absolute; top:0px; height:26px; width: 20px; right:-21px; text-decoration:none; cursor:pointer; color:#0000CC !important; background:#CC0088 !important;');
  2175. aelemX.textContent='X';
  2176. updateelem.appendChild(aelemX);
  2177. user_select(updateelem,'none');
  2178. document.body.appendChild(updateelem);
  2179. aelem1.addEventListener('click', function() { YouTube_Enhancer_Update_install(updateelem,Date_Now,Updater_url_dl); }, true);
  2180. aelem2.addEventListener('click', function() { YouTube_Enhancer_Update_later(updateelem,Date_Now); }, true);
  2181. aelemX.addEventListener('click', function() { remove_element(updateelem); }, true);
  2182. }
  2183.  
  2184. function YouTube_Enhancer_Updater(page_lang) {
  2185. const scriptid='33042';
  2186. if(YOUTUBE_ENHANCER_UPDATER_STATUS<0) {
  2187. var LastVersion=GM_getValue("Youtube_Enhancer_Updater_Version", YOUTUBE_ENHANCER_UPDATER_STATUS);
  2188. if(LastVersion>=0) {
  2189. if(typeof GM_deleteValue == 'function') { GM_deleteValue("Youtube_Enhancer_Updater_Version"); GM_deleteValue("Youtube_Enhancer_Updater_Date"); }
  2190. else { GM_setValue("Youtube_Enhancer_Updater", -1); GM_setValue("Youtube_Enhancer_Updater_Date", 0); }
  2191. show_alert('Youtube Enhancer - Updater Disabled / Last_Version='+LastVersion,0);
  2192. show_messageBox('Youtube Enhancer - '+HtmlUnicodeDecode(get_text_Updater(page_lang,"disa")));
  2193. }
  2194. return;
  2195. }
  2196. var Updater_Version=GM_getValue("Youtube_Enhancer_Updater_Version", YOUTUBE_ENHANCER_UPDATER_STATUS);
  2197. if(Updater_Version<=0) { return; }
  2198. GM_setValue("Youtube_Enhancer_Updater_Version",Updater_Version);
  2199. var Updater_Date=GM_getValue("Youtube_Enhancer_Updater_Date", 0);
  2200. var Date_Now=new Date();
  2201. Date_Now=Date_Now.getFullYear()*10000+Date_Now.getMonth()*100+Date_Now.getDate();
  2202. if(Updater_Date>Date_Now) { GM_setValue("Youtube_Enhancer_Updater_Date", Date_Now); return; }
  2203. //var Updater_url_dl='https://userscripts.org/scripts/source/'+scriptid+'.user.js';
  2204. var Updater_url_dl='https://userscripts.org/scripts/show/'+scriptid;
  2205. if(Updater_Date<0) {
  2206. show_alert('Youtube Enhancer - Update Was Found: Last='+Math.abs(Updater_Date)+' / Now='+Date_Now,0);
  2207. YouTube_Enhancer_Update_Display(page_lang,Updater_url_dl,Date_Now);
  2208. return;
  2209. }
  2210. if(Date_Now-Updater_Date<1) { return; }
  2211.  
  2212. // Checking meta.js...
  2213. var Updater_url_check='https://userscripts.org/scripts/source/'+scriptid+'.meta.js';
  2214. GM_xmlhttpRequest({
  2215. method: 'GET',
  2216. url: Updater_url_check,
  2217. headers: { 'User-agent': 'GM_xmlhttpRequest Updater', 'Accept': 'text/*' },
  2218. onload: function(data) {
  2219. show_alert('Youtube Enhancer - Check Update: Last='+Updater_Date+' / Now='+Date_Now,0);
  2220. if(data.status!=200) { show_alert('Update check failed: HTTP Error '+data.status,0); return; }
  2221. res=data.responseText.match(/\@name\s+YouTube\s+Enhancer/i);
  2222. if(!res) { GM_setValue("Youtube_Enhancer_Updater_Date", Date_Now); return; }
  2223. res=data.responseText.match(/\@namespace\s+https?\:\/\/userscripts\.org\/scripts\/show\/(\d+)/i);
  2224. if(!res) { GM_setValue("Youtube_Enhancer_Updater_Date", Date_Now); return; }
  2225. if(res[1]!=scriptid) { return; }
  2226. res=data.responseText.match(/\@uso\:script\s+(\d+)/i);
  2227. if(!res) { return; }
  2228. if(res[1]!=scriptid) { return; }
  2229. res=data.responseText.match(/\@uso\:version\s+(\d+)/i);
  2230. if(!res) { return; }
  2231. res=res[1];
  2232. if(res==Updater_Version) {
  2233. show_alert('Youtube Enhancer - No change / Current_Version='+res,0);
  2234. GM_setValue("Youtube_Enhancer_Updater_Date", Date_Now)
  2235. return;
  2236. }
  2237.  
  2238. if(Updater_Version==YOUTUBE_ENHANCER_UPDATER_STATUS) {
  2239. show_alert('Youtube Enhancer - Updater Enabled / Current_Version='+res,0);
  2240. GM_setValue("Youtube_Enhancer_Updater_Version", res)
  2241. GM_setValue("Youtube_Enhancer_Updater_Date", Date_Now)
  2242. show_messageBox('Youtube Enhancer - '+HtmlUnicodeDecode(get_text_Updater(page_lang,"enab")));
  2243. } else {
  2244. show_alert('Youtube Enhancer - Update Found / Version: '+Updater_Version+' -> '+res,0);
  2245. GM_setValue("Youtube_Enhancer_Updater_Version", res)
  2246. GM_setValue("Youtube_Enhancer_Updater_Date", -Math.abs(Date_Now))
  2247. YouTube_Enhancer_Update_Display(page_lang,Updater_url_dl,Date_Now);
  2248. }
  2249. }
  2250. });
  2251. }
  2252.  
  2253. //************************************** Useful Sub-routines *********************************************//
  2254. function remove_watch_element(elementname) {
  2255. if(check_on_youtube()) {
  2256. var el=document.getElementById(elementname);
  2257. if(el) { el.parentNode.removeChild(el); }
  2258. }
  2259. }
  2260.  
  2261. function remove_watch_parent_element(elementname) {
  2262. if(check_on_youtube()) {
  2263. var el=document.getElementById(elementname);
  2264. if(el) { var elp=el.parentNode; elp.parentNode.removeChild(elp); }
  2265. }
  2266. }
  2267.  
  2268. function HtmlUnicodeDecode(str) {
  2269. // Change HTML code "&#xxxxx;" to Unicode
  2270. var out="";
  2271. if(str==null) { return(out); }
  2272. var l=str.length;
  2273. for (var i=0; i<l; i++) {
  2274. var ch=str.charAt(i);
  2275. if(ch=='&') {
  2276. var sci=str.indexOf(';',i+1);
  2277. if(sci>0) {
  2278. var entity=str.substring(i+1,sci);
  2279. if(entity.length>1 && entity.charAt(0)=='#') {
  2280. entity=entity.substring(1);
  2281. if(entity.charAt(0).toLowerCase()=='x') { ch=String.fromCharCode(parseInt('0'+entity)); }
  2282. else { ch=String.fromCharCode(parseInt(entity)); }
  2283. } else {
  2284. switch(entity) {
  2285. case "nbsp": ch=String.fromCharCode(160);
  2286. }
  2287. }
  2288. i=sci;
  2289. }
  2290. }
  2291. out+=ch;
  2292. }
  2293. return out;
  2294. }
  2295.  
  2296. function getDisplayHeight(element) {
  2297. var els = element.style;
  2298. var oVisibility = els.visibility;
  2299. var oPosition = els.position;
  2300. var oDisplay = els.display;
  2301. els.visibility = 'hidden';
  2302. els.position = 'absolute';
  2303. els.display = 'block';
  2304. var Result = element.clientHeight;
  2305. els.display = oDisplay;
  2306. els.position = oPosition;
  2307. els.visibility = oVisibility;
  2308. return Result;
  2309. }
  2310.  
  2311. function getHeight(element) {
  2312. //var Result=window.getComputedStyle(element,null).height.replace('px','');
  2313. //if (Result=='auto') { Result = element.clientHeight; }
  2314. return element.clientHeight;
  2315. }
  2316.  
  2317. function getWidth(element) {
  2318. var Result = window.getComputedStyle(element,null).width.replace('px','');
  2319. if (Result=='auto') { Result = element.clientWidth; }
  2320. return Result;
  2321. }
  2322.  
  2323. function getAbsoluteLeft(element) {
  2324. var AbsLeft = 0;
  2325. while (element) { AbsLeft = AbsLeft + element.offsetLeft; element = element.offsetParent; }
  2326. return(AbsLeft);
  2327. }
  2328.  
  2329. function getAbsoluteTop(element) {
  2330. var AbsTop = 0;
  2331. while (element) { AbsTop = AbsTop + element.offsetTop; element = element.offsetParent; }
  2332. return(AbsTop);
  2333. }
  2334.  
  2335. function isPositiveInteger(value) { return (value.toString().search(/^\d+$/)==0); }
  2336.  
  2337. function isDefined(x) { return !(x == null && x !== null); }
  2338. function isUndefined(x) { return x == null && x !== null; }
  2339.  
  2340. function flushNode(el) { el.parentNode.replaceChild(el.cloneNode(true),el); }
  2341.  
  2342. function swap_display(element) {
  2343. var els = element.style;
  2344. if(els.display=="none") { els.display="block"; } else { els.display="none"; }
  2345. }
  2346.  
  2347. function user_select(element,value) {
  2348. var els = element.style;
  2349. if(isDefined(els.userSelect)) {els.userSelect=value;} // CSS3
  2350. else if (isDefined(els.MozUserSelect)) {els.MozUserSelect=value;} // Mozilla
  2351. }
  2352.  
  2353. function GetLuminosity(color) {
  2354. var rgb=color.match(/rgb\s*\(\s*(\d+)\s*\,\s*(\d+)\s*\,\s*(\d+)\s*\)/i);
  2355. if (rgb) { return (rgb[1]+rgb[2]+rgb[3])/3; }
  2356. rgb=color.match(/\#\s*([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})/i);
  2357. if (rgb) { return (parseInt('0x'+rgb[1])+parseInt('0x'+rgb[2])+parseInt('0x'+rgb[3]))/3; }
  2358. return 255;
  2359. }
  2360.  
  2361. function remove_element(element) { element.parentNode.removeChild(element); }
  2362.  
  2363. function show_messageBox(msg) {
  2364. if ( top.location.href!=window.location.href ) { return; }
  2365. var element=document.createElement('div');
  2366. element.setAttribute('lang','fr');
  2367. element.setAttribute("style","position:fixed; top:0px; left:0px; right:0px; z-index:9998; height:26px; font-family:arial,sans-serif; font-size:24px; line-height:24px; text-align:center; vertical-align:middle; color:#FFFFFF !important; background:#C080C0 !important; margin:2px; border: 3px solid #CC0088; border-right-width:24px;");
  2368. element.textContent=msg;
  2369. var aelem=document.createElement('a');
  2370. aelem.setAttribute('style','position:absolute; top:0px; height:26px; width: 20px; right:-21px; text-decoration:none; cursor:pointer; color:#0000CC !important; background:#CC0088 !important;');
  2371. aelem.textContent='X';
  2372. element.appendChild(aelem);
  2373. user_select(element,'none');
  2374. document.body.appendChild(element);
  2375. aelem.addEventListener('click', function() { remove_element(element); }, true);
  2376. }
  2377.  
  2378. function show_alert(msg, force) {
  2379. if(arguments.callee.counter) { arguments.callee.counter++; } else { arguments.callee.counter=1; }
  2380. GM_log('('+arguments.callee.counter+') '+msg);
  2381. if(force==0) { return; }
  2382. // Show a HTML alert box (only for watch pages or if forced)
  2383. if(force==1 || check_on_youtubewatchpage()) {
  2384. warningelem=document.createElement('div');
  2385. warningelem.setAttribute("style","color:#FFFFFF; background:#FF8000; width:auto; text-align:center; font-size:24px; border: 3px solid #CC0088; margin:2px;");
  2386. warningelem.textContent=msg;
  2387. document.body.insertBefore(warningelem, document.body.firstChild);
  2388. }
  2389. }
  2390.  
  2391. /******************************************** Licence ******************************************************
  2392. *** Creative Commons 3.0 ***
  2393. *** by: BY-attribution (Requirement to acknowledge or credit the author "GIJoe") ***
  2394. *** nc: Non-Commercial (Use for commercial purpose is forbidden) ***
  2395. *** sa: Share Alike (Derivative works must be under the same or similar license to this one) ***
  2396. ***********************************************************************************************************/
  2397.  
  2398. //******************************************* Main() *****************************************************//
  2399. function mediacontrollermenu() {
  2400. var page_lang="www";
  2401. try { page_lang=get_page_lang(); } catch(err) { show_alert('Initialisation failed: '+err); }
  2402. try { add_media_controller(page_lang); } catch(err) { show_alert('media_controller => ' +err); }
  2403. }
  2404.  
  2405. function main() {
  2406. // Clear onYouTubePlayerReady
  2407. unsafeWindow.onYouTubePlayerReady=function() {};
  2408.  
  2409. // Bind event for loop and autoplay (YouTube Watch pages only)
  2410. try { bind_movie_player_event(); } catch(err) { show_alert('bind_movie_player_event => '+err); }
  2411.  
  2412. // Get page info
  2413. var page_lang="www"; var page_fmt=0;
  2414. try { page_fmt=get_page_fmt(); page_lang=get_page_lang(); } catch(err) { show_alert('Initialisation failed: '+err); }
  2415.  
  2416. // Miscellaneous (remove unneeded items)
  2417. remove_watch_parent_element(WATCH_PROMOTED);
  2418. remove_watch_element(DEFAULT_LANG_BOX);
  2419.  
  2420. // change_links (part of Quality Selector) (image_preview_rollover included) (change_links must be the first to run)
  2421. try { change_links(page_fmt); } catch(err) { show_alert('change_links => ' +err); }
  2422. // Download Link (YouTube Watch pages only)
  2423. try { add_download_link(page_lang, page_fmt); } catch(err) { show_alert('download_link => ' +err); }
  2424. // Quality Selector (YouTube Watch pages only)
  2425. try { add_quality_selector(page_lang, page_fmt); } catch(err) { show_alert('quality_selector => '+err); }
  2426. // Media Controller
  2427. try { add_media_controller(page_lang); } catch(err) { show_alert('media_controller => '+err); }
  2428.  
  2429. // Add menu to rebind Media Controller
  2430. GM_registerMenuCommand("Media Controller - Rebind", mediacontrollermenu );
  2431.  
  2432. // Update check
  2433. try { YouTube_Enhancer_Updater(page_lang); } catch(err) { show_alert('YouTube_Enhancer_Updater => '+err); }
  2434. }
  2435. main();
  2436.  
  2437. } )();
  2438. // ]]>

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址