|
2 | 2 | // @name YouTube: Audio Only
|
3 | 3 | // @description No Video Streaming
|
4 | 4 | // @namespace UserScript
|
5 |
| -// @version 1.6.7 |
| 5 | +// @version 1.6.8 |
6 | 6 | // @author CY Fung
|
7 | 7 | // @match https://www.youtube.com/*
|
8 | 8 | // @match https://www.youtube.com/embed/*
|
|
876 | 876 | if (player_.__audio544__) return;
|
877 | 877 | player_.__audio544__ = 1;
|
878 | 878 | // console.log(1233, player_)
|
879 |
| - let ytdPlayerElement = null; |
| 879 | + const mediaCollection = document.getElementsByClassName('html5-main-video'); |
880 | 880 |
|
881 | 881 | const stopAndReloadFn = async () => {
|
882 | 882 | let isLive = false;
|
|
905 | 905 |
|
906 | 906 | const refreshAllStaleEntitiesForNonReadyAudio = async () => {
|
907 | 907 | try {
|
908 |
| - if (audio.readyState == 0) await player_.refreshAllStaleEntities(); |
| 908 | + if (audio.readyState == 0 && audio.isConnected === true) await player_.refreshAllStaleEntities(); |
909 | 909 | } catch (e) {
|
910 | 910 | }
|
911 | 911 | };
|
|
916 | 916 | };
|
917 | 917 | const seekToLiveHeadForLiveStream = async () => {
|
918 | 918 | try {
|
919 |
| - await player_.seekToLiveHead(); |
920 |
| - if ((await player_.isAtLiveHead()) === true) { |
921 |
| - await player_.seekToStreamTime(); |
| 919 | + audio.isConnected === true && await player_.seekToLiveHead(); |
| 920 | + if (audio.isConnected === true && (await player_.isAtLiveHead()) === true) { |
| 921 | + audio.isConnected === true && await player_.seekToStreamTime(); |
922 | 922 | return true;
|
923 | 923 | }
|
924 | 924 | } catch (e) {
|
|
930 | 930 | stopAndReload = false;
|
931 | 931 | await stopAndReloadFn();
|
932 | 932 | }
|
933 |
| - if (audio.paused === true) { |
| 933 | + if (audio.isConnected === true && audio.paused === true) { |
934 | 934 | await player_.clearVideo(); // avoid error in live streaming
|
935 | 935 | await player_.clearQueue(); // avoid error in live streaming
|
936 | 936 | await delayPn(300);
|
937 | 937 | for (let i = 0; i < 3; i++) {
|
938 |
| - if (audio.readyState === 0) { |
| 938 | + if (audio.readyState === 0 && audio.isConnected === true) { |
939 | 939 | if (await seekToLiveHeadForLiveStream()) await delayPn(60);
|
940 | 940 | }
|
941 | 941 | }
|
942 | 942 | if (k === -1) {
|
943 | 943 | await refreshAllStaleEntitiesForNonReadyAudio();
|
944 | 944 | } else if (k === 3) {
|
945 |
| - while (audio.readyState === 0) { |
| 945 | + while (audio.readyState === 0 && audio.isConnected === true) { |
946 | 946 | await refreshAllStaleEntitiesForNonReadyAudio();
|
947 | 947 | await triggerPlaying();
|
948 | 948 | await delayPn(300);
|
949 | 949 | }
|
950 | 950 | }
|
951 |
| - } else if (audio.paused === false) { |
952 |
| - if (!player_.isAtLiveHead()) { |
| 951 | + } else if (audio.isConnected === true && audio.paused === false) { |
| 952 | + if (!player_.isAtLiveHead() && audio.isConnected === true) { |
953 | 953 | if (await seekToLiveHeadForLiveStream()) await delayPn(60);
|
954 | 954 | }
|
955 |
| - while (audio.readyState === 0) { |
| 955 | + while (audio.readyState === 0 && audio.isConnected === true) { |
956 | 956 | await refreshAllStaleEntitiesForNonReadyAudio();
|
957 | 957 | await triggerPlaying();
|
958 | 958 | await delayPn(300);
|
959 | 959 | }
|
960 |
| - if (!player_.isAtLiveHead()) { |
| 960 | + if (!player_.isAtLiveHead() && audio.isConnected === true) { |
961 | 961 | if (await seekToLiveHeadForLiveStream()) await delayPn(60);
|
962 | 962 | }
|
963 | 963 | await refreshAllStaleEntitiesForNonReadyAudio();
|
964 |
| - if (audio.readyState > 0 && audio.paused === true) { |
| 964 | + if (audio.readyState > 0 && audio.paused === true && audio.isConnected === true) { |
965 | 965 | await triggerPlaying();
|
966 | 966 | }
|
967 | 967 | }
|
|
997 | 997 | };
|
998 | 998 | let mid = 0;
|
999 | 999 | const getAudioElement = () => {
|
1000 |
| - if (!ytdPlayerElement) { |
1001 |
| - ytdPlayerElement = [...document.querySelectorAll('ytd-player')].filter(e => !e.closest('[hidden]'))[0] |
| 1000 | + if (mediaCollection.length === 0) return null; |
| 1001 | + if (mediaCollection.length > 1) { |
| 1002 | + const audios = [...mediaCollection].filter(e => e && !e.closest('[hidden]') && e.closest('ytd-player')); |
| 1003 | + if (audios.length === 1) { |
| 1004 | + return audios[0]; |
| 1005 | + } |
| 1006 | + } else if (mediaCollection.length === 1) { |
| 1007 | + const e = mediaCollection[0]; |
| 1008 | + if (e && !e.closest('[hidden]') && e.closest('ytd-player')) return e; |
1002 | 1009 | }
|
1003 |
| - const audio = ytdPlayerElement ? HTMLElement.prototype.querySelector.call(ytdPlayerElement, '.video-stream.html5-main-video') : null; |
1004 |
| - return audio; |
1005 |
| - } |
| 1010 | + return null; |
| 1011 | + }; |
1006 | 1012 | const _onPlayerStateChange = (k_) => {
|
1007 | 1013 | const k = k_;
|
1008 | 1014 | const ps = player_.getPlayerState();
|
|
1016 | 1022 | });
|
1017 | 1023 | }
|
1018 | 1024 | }
|
1019 |
| - if (typeof k === 'number' && k === ps) { |
1020 |
| - const audio = getAudioElement(); |
1021 |
| - if (audio) { |
1022 |
| - if (mid > 1e9) mid = 9; |
1023 |
| - const t = ++mid; |
1024 |
| - prrPipeline(async () => { |
1025 |
| - if (t !== mid) return; |
1026 |
| - await prr.then(); |
1027 |
| - if (t !== mid) return; |
| 1025 | + if (typeof k === 'number' && k === ps && ps !== 5) { |
| 1026 | + |
| 1027 | + if (mid > 1e9) mid = 9; |
| 1028 | + const t = ++mid; |
| 1029 | + prrPipeline(async () => { |
| 1030 | + if (t !== mid) return; |
| 1031 | + await prr.then(); |
| 1032 | + if (t !== mid) return; |
| 1033 | + const audio = getAudioElement(); |
| 1034 | + |
| 1035 | + if (audio && player_.getPlayerState() === ps) { |
1028 | 1036 | await asyncStateChange(audio, k);
|
1029 |
| - }); |
1030 |
| - } |
| 1037 | + } |
| 1038 | + }); |
1031 | 1039 | }
|
1032 | 1040 | };
|
1033 | 1041 |
|
|
1265 | 1273 | (async () => {
|
1266 | 1274 |
|
1267 | 1275 | let player__;
|
1268 |
| - let elm; |
1269 | 1276 |
|
1270 | 1277 | const getAudioElement = () => {
|
1271 |
| - if (!elm) { |
1272 |
| - elm = player__; |
1273 |
| - } |
1274 |
| - const audio = elm ? HTMLElement.prototype.querySelector.call(elm, '.video-stream.html5-main-video') : null; |
| 1278 | + const elm = player__ || player0; |
| 1279 | + const audio = elm && elm.isConnected === true ? HTMLElement.prototype.querySelector.call(elm, '.video-stream.html5-main-video') : null; |
1275 | 1280 | return audio;
|
1276 | 1281 | }
|
1277 | 1282 |
|
|
0 commit comments