Tagged: Youtube Annoyances Remover

How to load a light version of Youtube? Welcome to YoutubeLite!

Also adds an RSS feed for the channel, direct link to videos page, and video/subtitle file downloads.

I installed Linux Mint with Mate desktop a few days ago. I hoped to move all my stuff to that the new OS but it has been delayed. I cannot use an OS unless it has been beefed up with my shell scripts, Nautilus Action Configuration scripts and my browser scripts. This is taking time.

So, I decided to switch back to my old obsolete OS and what do you know happened? The boot menu option failed to work. I then chrooted my old OS and reinstalled its boot menu. Now, that will not boot the new OS. I left it at that.

And, in my old browser, Youtube stopped its old-browser support and started loading slow heavy crappy pages with big text. My old Firefox browser is unable to load even one page!

Initially, I wrote a scrip to replace all Youtube links with Hooktube links. But their abilities are limited. So, I said “junk that” and wrote this new version of the Youtube Annoyance Remover. It is called Youtube Lite!. With it installed in the Greasemonkey add-on, I open videos in several tabs. The script waits for a while, lets the video load, mutes it, copies its video link, nukes the Youtube video player and then loads the link in a native video player of the browser. The old version used to remove the “Recommended for you” related videos but this one removes all related videos. If you want them, then open them in new tabs while the script is waiting. If you have good Internet speed, then the script may not wait at all.

YoutubeLite discards the custom video player that Youtube uses and loads the video in the native video player of the browser.

I could not load the video description in HTML. The links are not interactive. I will fix that soon.

Now, I can continue to download the videos using the DownThemAll extension. Because of persistent disturbances in the Internet and electrical connection and because of low speeds, I am unable to stream videos. I have to play them offline.

The GreaseMonkey code is available on GitHub. Use it with the GreaseMonkey Firefox add-on from the CA Archive.

If Youtube does not want to encourage these customizations, then they should do to Youtube video pages what they did to Youtube Studio pages that video uploaders have to use. That junk does not even load in my browser.

A big multinational tax-evading corporation should at least write their own Javascript code. Instead, these Google developers overload pages with hundreds of scripts from junk Javascript frameworks with their junk models-and-controllers junk! Only junk developers write this framework junk. Only junkier developers use it in their pages.

Please replace the word junk in the above paragraph with the street slang for crap.

YouTube Annoyances Remover (GreaseMonkey JavaScript) 2020.01 update

Format labels are now included in the download links

Recently, I found that the thumbnails were not loading and the alternative download links were not getting listed. Both problems have been fixed in this update.

Youtube video download links and thumbnail fixed

About this User JS

Disables ads, turns off autoload/autoplay, adds RSS link, deletes “recommended for you” videos, unhides description, displays all comments, changes profile link to videos page; changes region to US, displays video thumbnail image, and adds a link to the lighter version on Hooktube if video is not playable for codec reasons. Supports Firefox-based browser up to Firefox 36. Newer versions should use a UserAgent (UA) spoofer add-on. YouTube loads a lighter version of the YouTube page for older browsers. This script will require the GreaseMonkey add-on to be executed by the Firefox browser. For embedded YouTube videos, use the script com.vsubhash.js.embedded-video-catcher.user.js.

The download links can then be sent to the DownThemAll add-on with the file renaming mask set to “*text*.mp4”.

YouTube Annoyances Remover 2019.06 Update

Disables ads, turns off autoload/autoplay, adds RSS link, deletes “recommended for you” videos, unhides description, displays all comments, changes profile link to videos page; changes region to US, displays video thumbnail image, lists offline download links, and adds a link to the lighter version on Hooktube if video is not playable for codec reasons.

Youtube video download links

The current video link, the Hooktube video link, and other format/bitrates are linked. These links when used with DownThemAll add-on (file renaming option set to “*text*.mp4” will ensure the download is completed offline.

This script supports Firefox-based browser up to version 36. Newer versions should use a UserAgent (UA) spoofer add-on. YouTube loads a lighter version of the YouTube page for older browsers. This script will require the GreaseMonkey add-on to be executed by the Firefox browser. The download links can then be sent to the DownThemAll add-on with the file renaming mask “*text*.mp4”.

It seems that Mozilla has effectively destroyed its add-on ecosystem by switching over to Google Chrome’s WebExtensions format. I recently installed the latest version of Firefox and it has no add-ons worth naming in its download portal. DTA is not there and neither is Greasemonkey. If had Google had infiltrated Mozilla and decapitated its top management, Firefox couldn’t be worse. Mozilla’s own management is diluting its brand appeal, frustrating add-on developers, disappointing its user community and effectively throwing Internet users to the jaws of the Google spyware called Chrome. (https://www.thewindowsclub.com/microsoft-disabled-these-chromium-services-features-in-new-edge)

For embedded YouTube videos, use the new script com.vsubhash.js.embedded-video-catcher.user.js.

Unable to stream YouTube and other videos

I have lived in several houses in three South Indian states. In all of them, there are unusual electric disturbances. The net connection is also very unstable. (I wrote the NetCheck desktop and mobile application for this reason – http://vsubhash.com/netcheck-app-for-android.html) When the net connection seems to be stable, the electrical disturbances trips the Internet modem.

For this reason, I am unable to play videos as an online stream. I have to download them first and play them offline on the TV. The downloads have to be constantly restarted because the net connection stops intermittently.

The electrical disturbances destroys electrical appliances. I run the entertainment systems and computers on a UPS and this protects them. But, I can hear the UPS relay clicking incessantly. Earlier, the modem was on the mains directly. Now, it runs of the UPS. Even then, the modem stops net connection for some reason.

Apart from the electrical disturbances, the power supply is cut several dozen times a day – in all three states. In a month, they are off for an entire day or an entire night for at least three or four days. This always happens when I am visiting someone and trying to work on a computer. The UPS supports the modem and the network switch for about 20 minutes if my laptop is powered from the battery. If I am on the desktop, the backup lasts for just five minutes.

I rarely use the mobile now. Here too, the net connection is not stable.

In this video, you can hear the racket created by the relay. In the background, you can hear the fan speed going up and down with the voltage fluctuations.

GreaseMonkey Javascript Source Code


// ==UserScript==
// @name YouTubeAnnoyancesRemover
// @namespace com.vsubhash.js.youtube-annoyances-remover
// @description Disables ads, turns off autoload/autoplay, adds RSS link, deletes "recommended for you" videos, unhides description, displays all comments, changes profile link to videos page; changes region to US, displays video thumbnail image, and adds a link to the lighter version on Hooktube if video is not playable for codec reasons. Supports Firefox-based browser up to version 36. Newer versions should use a UserAgent (UA) spoofer add-on. YouTube loads a lighter version of the YouTube page for older browsers. This script will require the GreaseMonkey add-on to be executed by the Firefox browser. For embedded YouTube videos, use the script com.vsubhash.js.embedded-video-catcher.user.js.
// @include https://www.youtube.com/watch*
// @include https://www.youtube.com/channel*
// @include https://www.youtube.com/user*
// @version 2020.01
// @grant none
// ==/UserScript==
var sAdStyle = " { visibility: none!important; display: none!important; }";
var oDlDiv;
document.addEventListener("readystatechange", fixYouTubeAnnoyances, false);
try {
console.log("YAD: Page start");
window.setTimeout(pauseVideos, 2*1000);
window.setTimeout(pauseVideos, 4*1000);
window.setTimeout(pauseVideos, 6*1000);
} catch (e) { }
function fixYouTubeAnnoyances() {
if ((document.readyState == "interactive") || (document.readyState == "complete")) {
console.log("YAD: loaded");
try {
pauseVideos();
window.setTimeout(showDescription, 1*200);
window.setTimeout(closeVideoAds, 2*200);
window.setTimeout(changeRegion, 3*200);
window.setTimeout(addRssButton, 1*1000);
window.setTimeout(changeProfileLink, 2*1000);
window.setTimeout(pauseVideos, 3*1000);
window.setTimeout(removeRecommendedForYouAds, 4*1000);
window.setTimeout(disableAndHideAdContainers, 5*1000);
window.setTimeout(disableAutoPlay, 6*1000);
window.setTimeout(addVideoDownloadList, 7*1000);
window.setTimeout(loadAllComments, 15*1000);
window.setTimeout(removeRecommendedForYouAds, 16*1000);
} catch (e) {
console.error("YAD Error: " + e);
}
}
}
function addRssButton() {
console.log("YAD: addRssButton")
var oLink, oLinkEl, oChannelTag, oRssImg, oRssLink, sChannel, sChannelName, sUserName, sFeedUrl;
// Android 1.6
oLink = document.querySelector("div.tv span.gmb a");
oChannelTag = document.querySelector("div.tv span.gmb a span");
if (oLink == null) {
// Android 3+
oLink = document.querySelector("a.slim-owner-icon-and-title");
oChannelTag = document.querySelector("a.slim-owner-icon-and-title div h3");
}
if (oLink == null) {
// Android 46
oLink = document.querySelector("div.yt-user-info a");
oChannelTag = document.querySelector("div.yt-user-info a");
}
if (oLink == null) {
// Android 60
oLink = document.querySelector("div#owner-container *#owner-name a");
oChannelTag = document.querySelector("div#owner-container *#owner-name a");
}
if ((oLink ==null) || (oChannelTag == null)) { return; } else {
console.log("YAD: Channel name found.");
sChannelName = oChannelTag.textContent;
sChannelName = sChannelName.replace(/^\s+|\s+$/g, '');
console.log("YAD: Channel link found.");
if (oLink.getAttribute("href").indexOf("/channel/") == 0) {
sChannel = oLink.getAttribute("href").substr("/channel/".length);
sFeedUrl = "https://www.youtube.com/feeds/videos.xml?channel_id=" + sChannel;
console.log("YAD: RSS ~ " + sChannelName + " = " + sFeedUrl);
} else if (oLink.getAttribute("href").indexOf("/user/") == 0) {
sUserName = oLink.getAttribute("href").substr("/user/".length);
sFeedUrl = "https://www.youtube.com/feeds/videos.xml?user=" + sUserName;
console.log("YAD: RSS ~ " + sChannelName + " = " + sFeedUrl);
} else { return; }
oLinkEl = document.createElement("link");
oLinkEl.setAttribute("rel", "alternate");
oLinkEl.setAttribute("title", sChannelName);
oLinkEl.setAttribute("type", "application/rss+xml");
oLinkEl.setAttribute("href", sFeedUrl);
document.getElementsByTagName("head")[0].appendChild(oLinkEl);
oRssImg = document.createElement("img");
oRssImg.setAttribute("style", "margin: auto 1em; ");
oRssImg.setAttribute("alt", "RSS");
oRssImg.setAttribute("src", "https://www.google.com/images/rss.png");
oRssLink = document.createElement("a");
oRssLink.setAttribute("id", "mvytRssFeedLink");
oRssLink.setAttribute("href", sFeedUrl);
oRssLink.setAttribute("title", "RSS feed link for this channel");
oRssLink.setAttribute("style", "text-decoration: none; border-style: none; ");
oRssLink.appendChild(oRssImg);
if (document.getElementById("mvytRssFeedLink") == null) {
oChannelTag.insertAdjacentHTML('afterend', oRssLink.outerHTML);
}
}
}
function pauseVideos() {
console.log("YAD: Pausing videos");
try {
var oVideoEls = document.getElementsByTagName("video");
for (var i = 0; i < oVideoEls.length; i++) {
oVideoEls[i].pause();
oVideoEls[i].muted = true;
if (oVideoEls[i].src.indexOf("pltype=adhost") > -1) {
console.log("YAD: Video ad found… closing tab");
window.open(location.href, '_blank');
window.close();
}
console.log("YAD: Pausing video " + (i+1));
if (!oVideoEls[i].paused) {
oVideoEls[i].pause();
}
//oVideoEls[i].volume = 0.6; // custom controls do not update
oVideoEls[i].muted = true;
oVideoEls[i].removeAttribute("autoplay");
oVideoEls[i].removeAttribute("loop");
oVideoEls[i].removeAttribute("controls");
oVideoEls[i].setAttribute("preload", "none");
oVideoEls[i].pause();
}
var oButtons = document.getElementsByTagName("button");
for (var i = 0; i < oButtons.length; i++) {
if (oButtons[i].className) {
if (oButtons[i].className.indexOf("ytp-mute-button") > -1) {
console.log("YAD: Mute button " + oButtons[i].className);
oButtons[i].click();
oButtons[i].click();
}
}
}
} catch (e) {
console.error("YAD: Error – " + e);
}
}
function showDescription() {
console.log("YAD: Finding description…");
if (document.getElementById("action-panel-details") != null) {
document.getElementById("action-panel-details").className = "action-panel-content yt-uix-expander yt-card yt-card-has-padding";
}
console.log("YAD: Description unhidden.");
}
function closeVideoAds() {
console.log("YAD: Detecting video ads…");
if ((document.getElementsByClassName("videoAdUiTopButtons").length > 0) || (document.getElementsByClassName("videoAdUi").length > 0)) {
console.log("YAD: Video ad found");
window.open(location.href, '_blank');
window.close();
} else {
console.log("YAD: No video ad");
}
}
function disableAutoPlay() {
var oEl = document.getElementById("autoplay-checkbox");
if (oEl == null) {
console.log("YAD: Did not find autoplay button.");
} else if (oEl.hasAttribute("checked")) {
console.log("YAD: Disabling autoplay…");
oEl.click();
} else {
console.log("YAD: Autoplay already disabled.");
}
}
function removeRecommendedForYouAds() {
console.log("YAD: Removing recommended videos");
var oRelatedColumn = document.getElementById("watch-related");
if (oRelatedColumn != null) {
var arRelatedVids = oRelatedColumn.getElementsByTagName("li");
var j = 0;
if (arRelatedVids.length > 0) {
for (var i = arRelatedVids.length-1; i > -1; i–) {
if (arRelatedVids[i].textContent.indexOf("Recommended for you") != -1) {
//console.log("YAD: Removing " + arRelatedVids[i].textContent);
arRelatedVids[i].parentNode.removeChild(arRelatedVids[i]);
++j;
}
}
}
console.log("YAD: Removed " + j + " recommended videos");
}
oRelatedColumn = document.getElementById("watch7-sidebar-modules");
if (oRelatedColumn != null) {
var arRelatedVids = oRelatedColumn.getElementsByClassName("watch-sidebar-section");
var j = 0;
if (arRelatedVids.length > 0) {
for (var i = arRelatedVids.length-1; i > -1; i–) {
if (arRelatedVids[i].textContent.indexOf("Recommended for you") != -1) {
//console.log("YAD: Removing " + arRelatedVids[i].textContent);
arRelatedVids[i].parentNode.removeChild(arRelatedVids[i]);
++j;
}
}
}
console.log("YADN: Removed " + j + " new recommended videos");
}
}
function disableAndHideAdContainers() {
console.log("YAD: Disabling/deleting ad containers…");
var arDivIds = ["AdSense", "watch7-sidebar-ads", "promotion-shelf", "live-chat-iframe", "invideo-overlay:7", ];
var arDivClasses = [ "adDisplay", "annotation", "html5-endscreen", "iv-promo", "video-ads", "videoAdUiBottomBar", "ytp-ad-module", "ytp-endscreen-content", "ytp-cards-button", "ytp-cards-teaser", "ytp-ad-overlay-container", "ytp-ad-overlay-slot", "ytp-ad-text-overlay", "ytp-ad-overlay-ad-info-button-container", "ytp-ad-hover-text-button", "ytp-ad-info-hover-text-button", "ytp-ad-overlay-text-image", "ytp-ad-overlay-text-image", "ytp-ad-image-overlay", "ytp-ad-overlay-close-container", "ytp-ad-overlay-close-button" ];
for (var i = 0; i < arDivIds.length; i++) {
var oDiv = document.getElementById(arDivIds[i]);
if (oDiv != null) {
oDiv.style.visibility = "hidden!important";
oDiv.style.display = "none!important";
oDiv.parentNode.removeChild(oDiv);
console.log("YAD: Removed " + arDivIds[i] + " by ID");
} else {
console.log("YAD: Not found: " + arDivIds[i] + " by ID");
}
sAdStyle = "#" + arDivIds[i] + ((i==0)?" ":" , ") + sAdStyle;
}
for (var i = 0; i < arDivClasses.length; i++) {
var oDivs = document.getElementsByClassName(arDivClasses[i]);
if (oDivs != null) {
for (var j = 0; j < oDivs.length; j++) {
oDivs[j].style.visibility = "hidden!important";
oDivs[j].style.display = "none!important";
oDivs[j].parentNode.removeChild(oDivs[j]);
}
} else {
console.log("YAD: Not found: " + oDivs[j] + " by ID");
}
sAdStyle = "*." + arDivClasses[i] + " , " + sAdStyle;
}
document.getElementsByTagName("head")[0].innerHTML = document.getElementsByTagName("head")[0].innerHTML + "\n<style>" + sAdStyle + "\n</style>";
}
function changeRegion() {
var oLangButton = document.getElementById("yt-picker-country-button");
if (oLangButton != null) {
if (oLangButton.textContent.indexOf("United States") == -1) {
oLangButton.click();
window.setTimeout(
function() {
var arRegions = document.getElementsByClassName("yt-picker-item");
for (var i = 0; i < arRegions.length; i++) {
if (arRegions[i].textContent.indexOf("United States") > -1) {
arRegions[i].click();
break;
}
}
}, 3*1000);
}
}
}
function changeProfileLink() {
console.log("YAD: Changing profile link")
var oDivs = document.getElementsByTagName("div");
if ((oDivs != null) && (oDivs.length > 0)) {
for (var i = 0; i < oDivs.length; i++) { if (oDivs[i].className == "yt-user-info") {
var oAnchors = oDivs[i].getElementsByTagName("a");
if ((oAnchors != null) && (oDivs.length>1)) {
var bFound = false;
for (var j = 0; j < oAnchors.length; j++) {
if (oAnchors[j].href.substring(0, "https://www.youtube.com/channel/&quot;.length) == "https://www.youtube.com/channel/&quot;) {
oAnchors[j].href = oAnchors[j].href + "/videos";
oLatestVideosLink = document.createElement("a");
oLatestVideosLink.setAttribute("style", "background-image: url(https://s.ytimg.com/yts/imgbin/www-hitchhiker-vflYQU35a.png); width: 17px; height: 17px; background-position: -94px -472px; border-style: none; margin: 0; padding: 0; ");
oLatestVideosLink.setAttribute("id", "MvPopularLink");
oLatestVideosLink.setAttribute("href", oAnchors[j].href + "?view=0&sort=p&flow=grid");
oAnchors[j].insertAdjacentHTML("afterend", oLatestVideosLink.outerHTML);
bFound = true;
break;
}
}
if (bFound) { break; }
}
}
}
}
}
var iLoadAllCommentsTimeout = 0;
function loadAllComments() {
if (iLoadAllCommentsTimeout > 0) {
window.clearTimeout(iLoadAllCommentsTimeout);
}
var oDiv = document.getElementById("watch-discussion");
if (oDiv == null) { return; }
var oButtons = oDiv.getElementsByClassName("comment-section-renderer-paginator");
if (oButtons != null) {
console.log("YAD: Comments");
if (oButtons[0] != null) {
oButtons[0].click();
iLoadAllCommentsTimeout = window.setTimeout(loadAllComments, 20*1000);
}
}
}
function parseYTPlayer() {
console.log("YAD: Inside parser" );
console.log("YAD: Title" + ytplayer.config.args.title);
try {
if (document.getElementsByTagName("video")[0] && (document.getElementsByTagName("video")[0].pause)) {
document.getElementsByTagName("video")[0].pause();
}
} catch (e) {
window.alert(e);
}
var arFormatParams, arFormats, i, j, sURL, sQuality, sMimeType, sExtension;
var oDlList, oDlListItem;
oDlList = document.getElementById("mvyJsList");
if (oDlList == null) {
return;
}
oDlList.innerHTML += "<li><a href=\"" + location.href.replace("www.you", "www.hook") + "\" style=\"color: navy; font-weight: bold; \" target=\"_blank\">Load in HookTube</a></li>";
var oFormats = JSON.parse(ytplayer.config.args.player_response);
var arFormats = oFormats.streamingData.formats;
for (i = 0; i < arFormats.length; i++) {
oDlListItem = document.createElement("li");
var sFormat = arFormats[i].mimeType.split(';')[0];
if (arFormats[i].mimeType.split(';')[0] == "video/mp4") {
sFormat = "M";
} else if (arFormats[i].mimeType.split(';')[0] == "video/webm") {
sFormat = "W";
}
console.log("YAD: Format " + arFormats[i].quality + " – " + arFormats[i].qualityLabel + " – " + arFormats[i].mimeType.split(';')[0]);
oDlListItem.innerHTML = "<a title=\"" + arFormats[i].mimeType.replace(/\"/g,"") + "\" style=\"color: navy; font-weight: bold; \" target=\"_blank\" href=\"" + arFormats[i].url + "\">" + document.title.replace(" – YouTube", "") + " – " + arFormats[i].qualityLabel + " " + sFormat + "</a>";
oDlList.appendChild(oDlListItem);
}
}
function addCurrentPlayURL() {
var oList = document.getElementById("mvyJsList");
if (oList != null) {
if (document.getElementById("movie_player") != null) {
if (document.getElementById("movie_player").getElementsByTagName("video") != null) {
var oVideo = document.getElementById("movie_player").getElementsByTagName("video")[0];
if (oVideo.src) {
oList.innerHTML += "<li><a id=\"VidLinkUrl\" title=\"" + document.title + "\" download=\"" + document.title.replace(/\s+/ig, "-").replace(/-{2,}/ig, "-") + ".mp4\" style=\"color: navy; font-weight: bold; \" target=\"_blank\" href=\"" + oVideo.src + "\">" + document.title + "</a></li>";
console.log("YAD: Video URL = " + oVideo.src);
oVideo.addEventListener(
"loadeddata",
function() {
console.log("YAD: New video loaded");
document.getElementById("VidLinkUrl").setAttribute("href", document.getElementsByTagName("video")[0].src);
}, false);
} else {
console.log("YAD: Error in player");
}
}
} else {
console.log("YouTube detector: No player");
oList.innerHTML += "<li><a style=\"color: navy; font-weight: bold; \"href=\"" + location.href.replace("www.you", "www.hook") + "\" style=\"color: navy; font-weight: bold; \" target=\"_blank\">Load in HookTube</a></li>";
}
}
}
function addVideoDownloadList() {
console.log("Executing YouTube detector");
var i, n, oDlButtonEl, oVideosList;
oDlDiv = document.createElement("div");
oDlDiv.setAttribute("id", "mvyJsDiv");
oDlDiv.setAttribute("style", "background-color: orange!important; border: 2px dashed firebrick; font-size: 0.34cm!important; font-family: sans-serif!important; line-height: 0.4cm!important; margin: 1em auto; padding: 1em; min-height: 120px; ");
oDlDiv.innerHTML = "Download video from:";
var oTwitterImage = document.querySelector("html head meta[name='twitter:image']");
console.log("YAD: Twitter image" + oTwitterImage.getAttribute("content"));
if (oTwitterImage) {
oDlDiv.innerHTML += "<img src=\"" + oTwitterImage.getAttribute("content") + "\" style=\"max-width: 200px; float: right; margin: 1em auto 1em 1em; \" />\n";
} else if (window.URL) {
var oURL = new URL(location.href);
var sID = oURL.searchParams.get("v");
oDlDiv.innerHTML += "<img src=\"https://i.ytimg.com/vi/&quot; + sID + "/hqdefault.jpg\" style=\"max-width: 200px; float: right; margin: 1em auto 1em 1em; \" />";
}
oDlList = document.createElement("ul");
oDlList.setAttribute("style", "display: block; list-style: disc inside none; margin-left: 1em!important; ");
oDlList.setAttribute("id", "mvyJsList");
oDlDiv.appendChild(oDlList);
if (location.href.indexOf("youtube.com/watch") > -1) {
document.getElementById("watch-headline-title").appendChild(oDlDiv);
addCurrentPlayURL();
parseYTPlayer();
} else if (location.href.indexOf("youtube.com/embed/") > -1) {
// Use the script com.vsubhash.js.embedded-video-catcher
}
}


// ==UserScript==
// @name EmbeddedVideoCatcher
// @namespace com.vsubhash.js.embedded-video-catcher
// @description Adds a link to the video file. Supports Firefox-based browser up to version 36. Newer versions should use a UserAgent (UA) spoofer add-on. YouTube loads a lighter version of the YouTube page for older browsers. This script will require the GreaseMonkey add-on to be executed by the Firefox browser. If the video link is inaccessible by a transparent image or other HTML element, the URL can be obtained from the browser's web console output (Tools -> Web Developers -> Console). The script also automatically pauses the video several times.
// @include http://*
// @include https://*
// @exclude https://www.youtube.com/watch*
// @exclude https://www.dailymotion.com/video*
// @version 2019.06
// @grant none
// ==/UserScript==
var sAdStyle = " { visibility: none!important; display: none!important; }";
document.addEventListener("readystatechange", loadHandler, false);
try {
window.setTimeout(pauseVideos, 2*1000);
window.setTimeout(pauseVideos, 4*1000);
window.setTimeout(pauseVideos, 6*1000);
} catch (e) { console.error("EVC Error: " + e); }
function loadHandler() {
try {
addVideoList();
} catch (e) {
console.error("EVC Error: " + e);
}
}
function updateYouTubeVideoLink() {
console.log("EVC: Loaded video event for YouTube video");
if (document.getElementById("mvyJsList") &&
document.getElementById("player") &&
(document.getElementById("player").getElementsByTagName("video").length > 0)) {
document.getElementById("player").getElementsByTagName("video")[0].pause();
document.getElementById("mvyJsList").innerHTML = "<li style=\"margin-left: 0.2em; padding-left: 0.2em; \"><a id=\"VidLinkUrl\" title=\"" + document.title + "\" download=\"" + document.title.replace(/\s+/ig, "-").replace(/-{2,}/ig, "-") + ".mp4\" style=\"color: navy; font-weight: bold; \" target=\"_blank\" href=\"" + document.getElementById("player").getElementsByTagName("video")[0].src + "\">" + document.title + "</a></li>";
console.log("Video : " + document.title + "\n" + document.getElementById("player").getElementsByTagName("video")[0].src);
} else {
//console.log("EVC: Loaded video event for YouTube video noooh");
}
}
function updateNumberedVideoLink(aoEvent) {
console.log("EVC: Loaded video event for " + aoEvent.target.src);
var oLink = document.getElementById("VidLinkUrl" + aoEvent.target.getAttribute("mvy_id"));
if (oLink) {
oLink.setAttribute("href", aoEvent.target.getAttribute("src"));
oLink.innerHTML = aoEvent.target.getAttribute("src").substr(aoEvent.target.getAttribute("src").lastIndexOf("/")+1);
console.log("EVC: URL : " + document.title + "\n" + aoEvent.target.src);
console.log("EVC: File: " + aoEvent.target.getAttribute("src").substr(aoEvent.target.getAttribute("src").lastIndexOf("/")+1));
}
}
function addVideoList() {
if (document.readyState == "complete") {
console.log("EVC: Executing EmbeddedVideoCatcher");
var i, n, oDlButtonEl, oDlDiv, oVideosList;
if (location.href.indexOf("youtube.com/embed") > -1) {
// Embedded Youtube video page loads twice. On the second time, it will have a video element.
// However, the video element will not have a 'src' attribute. The attribute will be assigned
// a video URL after the play button is clicked. A handler for the "loadeddata" event is added
// obtain this video URL.
console.log("EVC: Found YouTube embedded video player");
if (document.getElementById("mvyJsDiv") == null) {
oDlDiv = document.createElement("div");
oDlDiv.setAttribute("id", "mvyJsDiv");
oDlDiv.setAttribute("style", "position: absolute; top: 0; display: block; background-color: orange!important; border: 2px dashed firebrick; font-size: 0.34cm!important; font-family: sans-serif!important; line-height: 0.4cm!important; margin: 10px 10px 10px 50%; padding: 1em; width: 40%; z-index: 203; ");
}
if (document.getElementById("mvyJsList") == null) {
oDlDiv.innerHTML = "Download video from:";
oDlList = document.createElement("ul");
oDlList.setAttribute("style", "display: block; list-style: disc outside none; margin-left: 0.2em; padding-left: 0.2em; ");
oDlList.setAttribute("id", "mvyJsList");
oDlDiv.appendChild(oDlList);
}
var oVideoDiv = document.getElementById("player");
if (oVideoDiv == null) {
console.log("EVC: Player DIV not found");
} else if (oVideoDiv.getElementsByTagName("video").length < 1) {
console.log("EVC: Video tag not found in player DIV");
} else {
oVideoDiv.appendChild(oDlDiv);
var oVideo = oVideoDiv.getElementsByTagName("video")[0];
oVideo.addEventListener("loadeddata", updateYouTubeVideoLink, false);
if (oVideo.src) {
updateYouTubeVideoLink();
} else {
document.querySelector("button.ytp-large-play-button").click();
window.setTimeout(updateYouTubeVideoLink, 3*1000);
document.getElementById("mvyJsList").innerHTML = "Video not loaded yet";
}
console.log("EVC: Added Youtube video to list");
}
} else {
console.log("EVC: Not youtube");
if (document.getElementsByTagName("video").length > 0) {
console.log("EVC: Number of videos = " + document.getElementsByTagName("video").length);
for (var i = 0; i < document.getElementsByTagName("video").length; i++) {
console.log("EVC: Parsing video " + i);
oDlDiv = document.createElement("div");
oDlDiv.setAttribute("id", ("mvyJsDiv" + i));
oDlDiv.setAttribute("style", "position: absolute; top: 0; display: block; background-color: orange!important; border: 2px dashed firebrick; font-size: 0.34cm!important; font-family: sans-serif!important; line-height: 0.4cm!important; margin: 10px 10px 10px 50%; padding: 0.5em; width: 40%; z-index: " + (203 + (i*10)) + "; ");
oDlDiv.style.top = (i*100) + "px";
oDlDiv.innerHTML = "Download video from:";
oDlList = document.createElement("ul");
oDlList.setAttribute("style", "display: block; list-style: disc outside none; margin-left: 0.2em!important; padding-left: 0.2em!important;");
oDlList.setAttribute("id", ("mvyJsList" + i));
oDlDiv.appendChild(oDlList);
var oVideo = document.getElementsByTagName("video")[i];
oVideo.pause();
oVideo.parentElement.setAttribute("style", "background-color: brown; overflow: scroll!important; ");
oVideo.parentElement.insertBefore(oDlDiv, oVideo);
oVideo.setAttribute("mvy_id", i);
oVideo.addEventListener("loadeddata", updateNumberedVideoLink, false);
//oVideo.onloadeddata = updateNumberedVideoLink;
if (oVideo.getElementsByTagName("source").length > 0) {
oDlList.innerHTML = "<li style=\"margin-left: 0.2em; padding-left: 0.2em; \"><a id=\"VidLinkUrl" + i + "\" title=\"" + document.title + "\" style=\"color: navy; font-weight: bold; \" target=\"_blank\" href=\"" + oVideo.src + "\">Not Available</a></li>";
console.log("EVC: Video " + (i) + " has source tag(s)");
for (var j = 0; j < oVideo.getElementsByTagName("source").length; j++) {
var oSource = oVideo.getElementsByTagName("source")[j];
oDlList.innerHTML = oDlList.innerHTML + "<li style=\"margin-left: 0.2em; padding-left: 0.2em; \"><a id=\"VidLinkUrl" + i + "-" + j + "\" title=\"" + (document.title?document.title:"") + " – Source " + (j+1) + " (" + oSource.type + ")\" download=\"" + document.title.replace(/\s+/ig, "-").replace(/-{2,}/ig, "-") + ".mp4\" style=\"color: navy; font-weight: bold; \" target=\"_blank\" href=\"" + oSource.src + "\">" + (document.title?document.title:"") + " – Source " + (j+1) + (oSource.getAttribute("res")?(" [" + oSource.getAttribute("res") + "]"):"") + (oSource.getAttribute("label")?(" [" + oSource.getAttribute("label") + "]"):"") + "</a></li>";
console.log("EVC: Found source " + (j+1) + " " + oSource.getAttribute("res") + " ~ " + oSource.src);
}
console.log("EVC: Added " + oVideo.getElementsByTagName("source").length + " videos to list");
} else {
console.log("EVC: Video " + (i+1) + " has no source tag");
if (oVideo.src) {
console.log("EVC: Video " + (i+1) + " is at ~ " + oVideo.src);
if (document.title) {
oDlList.innerHTML = "<li style=\"margin-left: 0.2em; padding-left: 0.2em; \"><a id=\"VidLinkUrl" + i + "\" title=\"" + document.title + "\" download=\"" + document.title.replace(/\s+/ig, "-").replace(/-{2,}/ig, "-") + ".mp4\" style=\"color: navy; font-weight: bold; \" target=\"_blank\" href=\"" + oVideo.src + "\">" + document.title + "</a></li>";
} else {
oDlList.innerHTML = "<li style=\"margin-left: 0.2em; padding-left: 0.2em; \"><a id=\"VidLinkUrl" + i + "\" title=\"Video\" style=\"color: navy; font-weight: bold; \" target=\"_blank\" href=\"" + oVideo.src + "\">Video Link</a></li>";
}
} else {
console.log("EVC: Video " + (i+1) + " has no URL");
oDlList.innerHTML = "<li style=\"margin-left: 0.2em; padding-left: 0.2em; \"><a id=\"VidLinkUrl" + i + "\" title=\"Video\" style=\"color: navy; font-weight: bold; \" href=\"javascript:return(false);\">Video Link Not Available</a></li>";
}
}
}
} else {
console.log("EVC: Found no videos");
}
}
} else {
// page not ready
}
}
function pauseVideos() {
console.log("EVC: Pausing videos");
try {
var oVideoEls = document.getElementsByTagName("video");
console.log("EVC: Number of videos " + oVideoEls.length);
for (var i = 0; i < oVideoEls.length; i++) {
oVideoEls[i].pause();
oVideoEls[i].muted = true;
if (oVideoEls[i].src.indexOf("pltype=adhost") > -1) {
console.log("EVC: Video ad found… closing tab");
oVideoEls[i].src = "";
}
console.log("EVC: Pausing video " + (i+1));
if (!oVideoEls[i].paused) {
oVideoEls[i].pause();
}
//oVideoEls[i].volume = 0.6; // custom controls do not update
oVideoEls[i].muted = true;
oVideoEls[i].removeAttribute("autoplay");
oVideoEls[i].removeAttribute("loop");
oVideoEls[i].removeAttribute("controls");
oVideoEls[i].setAttribute("preload", "none");
oVideoEls[i].pause();
}
var oButtons = document.getElementsByTagName("button");
for (var i = 0; i < oButtons.length; i++) {
if (oButtons[i].className) {
if (oButtons[i].className.indexOf("ytp-mute-button") > -1) {
console.log("EVC: Mute button " + oButtons[i].className);
oButtons[i].click();
oButtons[i].click();
}
}
}
} catch (e) {
console.error("EVC: Error – " + e);
}
}

YouTube Ad Blocker and Annoyances Remover GreaseMonkey script updated

Blocks video ads too.

YouTube ad-blocker and annoyances remover script

This script removes ads, disables autoplay, mutes video, adds RSS support and displays all comments.

In this version, the script will

  • disable ads, including video ads. If a video ad is loaded, a new window will be opened until an ad-free video is loaded. You will have to manually close the other tabs. I am not sure how effective it is in blocking text ads, I use a ad-blocking HOSTS file and I don’t see ads most of the time.
  • pause all videos automatically. This is useful if you open multiple videos in different tabs and if they all start playing simultaneously, you will hear the biblical Tower of Babel.
  • turn off autoplay button
  • add an RSS link next to the channel name and in a LINK tag in the HEAD section of the HTML so that the browser can activate its RSS button (if available).
  • delete “recommended for you” videos
  • unhide description
  • display all comments
  • change profile link to videos page
  • change region to US. By default, YouTube pages defaults to India and all the results are tilted in favour of Indian Youtubers. The problems with the Indian Youtubers is that their videos have low-volume voice and high-volume music. By changing to US, the video results are mostly from English-speaking countries. They are not enamoured by the need to pepper their videos with loud interludes of the same copyright-free music.

The script supports Firefox-based browser up to version 36. Newer Firefox versions should use a UserAgent (UA) spoofer add-on. YouTube loads a lighter version of the YouTube page for older browsers. This script will require the GreaseMonkey add-on to be executed by the Firefox browser.

For non-YouTube pages, I have a more generic autoplay video autostopper script. It will also work on YouTube pages if the @exclude line is removed.


// ==UserScript==
// @name YouTubeAnnoyancesRemover
// @namespace com.vsubhash.js.youtube-annoyances-remover
// @description Disables ads, turns off autoload/autoplay, adds RSS link, deletes "recommended for you" videos, unhides description, displays all comments, changes profile link to videos page; changes region to US, displays video thumbnail image, and adds a link to the lighter version on Hooktube if video is not playable for codec reasons. Supports Firefox-based browser up to version 36. Newer versions should use a UserAgent (UA) spoofer add-on. YouTube loads a lighter version of the YouTube page for older browsers. This script will require the GreaseMonkey add-on to be executed by the Firefox browser. For embedded YouTube videos, use the script com.vsubhash.js.embedded-video-catcher.user.js.
// @include https://www.youtube.com/watch*
// @include https://www.youtube.com/channel*
// @include https://www.youtube.com/user*
// @version 2020.01
// @grant none
// ==/UserScript==
var sAdStyle = " { visibility: none!important; display: none!important; }";
var oDlDiv;
document.addEventListener("readystatechange", fixYouTubeAnnoyances, false);
try {
console.log("YAD: Page start");
window.setTimeout(pauseVideos, 2*1000);
window.setTimeout(pauseVideos, 4*1000);
window.setTimeout(pauseVideos, 6*1000);
} catch (e) { }
function fixYouTubeAnnoyances() {
if ((document.readyState == "interactive") || (document.readyState == "complete")) {
console.log("YAD: loaded");
try {
pauseVideos();
window.setTimeout(showDescription, 1*200);
window.setTimeout(closeVideoAds, 2*200);
window.setTimeout(changeRegion, 3*200);
window.setTimeout(addRssButton, 1*1000);
window.setTimeout(changeProfileLink, 2*1000);
window.setTimeout(pauseVideos, 3*1000);
window.setTimeout(removeRecommendedForYouAds, 4*1000);
window.setTimeout(disableAndHideAdContainers, 5*1000);
window.setTimeout(disableAutoPlay, 6*1000);
window.setTimeout(addVideoDownloadList, 7*1000);
window.setTimeout(loadAllComments, 15*1000);
window.setTimeout(removeRecommendedForYouAds, 16*1000);
} catch (e) {
console.error("YAD Error: " + e);
}
}
}
function addRssButton() {
console.log("YAD: addRssButton")
var oLink, oLinkEl, oChannelTag, oRssImg, oRssLink, sChannel, sChannelName, sUserName, sFeedUrl;
// Android 1.6
oLink = document.querySelector("div.tv span.gmb a");
oChannelTag = document.querySelector("div.tv span.gmb a span");
if (oLink == null) {
// Android 3+
oLink = document.querySelector("a.slim-owner-icon-and-title");
oChannelTag = document.querySelector("a.slim-owner-icon-and-title div h3");
}
if (oLink == null) {
// Android 46
oLink = document.querySelector("div.yt-user-info a");
oChannelTag = document.querySelector("div.yt-user-info a");
}
if (oLink == null) {
// Android 60
oLink = document.querySelector("div#owner-container *#owner-name a");
oChannelTag = document.querySelector("div#owner-container *#owner-name a");
}
if ((oLink ==null) || (oChannelTag == null)) { return; } else {
console.log("YAD: Channel name found.");
sChannelName = oChannelTag.textContent;
sChannelName = sChannelName.replace(/^\s+|\s+$/g, '');
console.log("YAD: Channel link found.");
if (oLink.getAttribute("href").indexOf("/channel/") == 0) {
sChannel = oLink.getAttribute("href").substr("/channel/".length);
sFeedUrl = "https://www.youtube.com/feeds/videos.xml?channel_id=&quot; + sChannel;
console.log("YAD: RSS ~ " + sChannelName + " = " + sFeedUrl);
} else if (oLink.getAttribute("href").indexOf("/user/") == 0) {
sUserName = oLink.getAttribute("href").substr("/user/".length);
sFeedUrl = "https://www.youtube.com/feeds/videos.xml?user=&quot; + sUserName;
console.log("YAD: RSS ~ " + sChannelName + " = " + sFeedUrl);
} else { return; }
oLinkEl = document.createElement("link");
oLinkEl.setAttribute("rel", "alternate");
oLinkEl.setAttribute("title", sChannelName);
oLinkEl.setAttribute("type", "application/rss+xml");
oLinkEl.setAttribute("href", sFeedUrl);
document.getElementsByTagName("head")[0].appendChild(oLinkEl);
oRssImg = document.createElement("img");
oRssImg.setAttribute("style", "margin: auto 1em; ");
oRssImg.setAttribute("alt", "RSS");
oRssImg.setAttribute("src", "https://www.google.com/images/rss.png&quot;);
oRssLink = document.createElement("a");
oRssLink.setAttribute("id", "mvytRssFeedLink");
oRssLink.setAttribute("href", sFeedUrl);
oRssLink.setAttribute("title", "RSS feed link for this channel");
oRssLink.setAttribute("style", "text-decoration: none; border-style: none; ");
oRssLink.appendChild(oRssImg);
if (document.getElementById("mvytRssFeedLink") == null) {
oChannelTag.insertAdjacentHTML('afterend', oRssLink.outerHTML);
}
}
}
function pauseVideos() {
console.log("YAD: Pausing videos");
try {
var oVideoEls = document.getElementsByTagName("video");
for (var i = 0; i < oVideoEls.length; i++) {
oVideoEls[i].pause();
oVideoEls[i].muted = true;
if (oVideoEls[i].src.indexOf("pltype=adhost") > -1) {
console.log("YAD: Video ad found… closing tab");
window.open(location.href, '_blank');
window.close();
}
console.log("YAD: Pausing video " + (i+1));
if (!oVideoEls[i].paused) {
oVideoEls[i].pause();
}
//oVideoEls[i].volume = 0.6; // custom controls do not update
oVideoEls[i].muted = true;
oVideoEls[i].removeAttribute("autoplay");
oVideoEls[i].removeAttribute("loop");
oVideoEls[i].removeAttribute("controls");
oVideoEls[i].setAttribute("preload", "none");
oVideoEls[i].pause();
}
var oButtons = document.getElementsByTagName("button");
for (var i = 0; i < oButtons.length; i++) {
if (oButtons[i].className) {
if (oButtons[i].className.indexOf("ytp-mute-button") > -1) {
console.log("YAD: Mute button " + oButtons[i].className);
oButtons[i].click();
oButtons[i].click();
}
}
}
} catch (e) {
console.error("YAD: Error – " + e);
}
}
function showDescription() {
console.log("YAD: Finding description…");
if (document.getElementById("action-panel-details") != null) {
document.getElementById("action-panel-details").className = "action-panel-content yt-uix-expander yt-card yt-card-has-padding";
}
console.log("YAD: Description unhidden.");
}
function closeVideoAds() {
console.log("YAD: Detecting video ads…");
if ((document.getElementsByClassName("videoAdUiTopButtons").length > 0) || (document.getElementsByClassName("videoAdUi").length > 0)) {
console.log("YAD: Video ad found");
window.open(location.href, '_blank');
window.close();
} else {
console.log("YAD: No video ad");
}
}
function disableAutoPlay() {
var oEl = document.getElementById("autoplay-checkbox");
if (oEl == null) {
console.log("YAD: Did not find autoplay button.");
} else if (oEl.hasAttribute("checked")) {
console.log("YAD: Disabling autoplay…");
oEl.click();
} else {
console.log("YAD: Autoplay already disabled.");
}
}
function removeRecommendedForYouAds() {
console.log("YAD: Removing recommended videos");
var oRelatedColumn = document.getElementById("watch-related");
if (oRelatedColumn != null) {
var arRelatedVids = oRelatedColumn.getElementsByTagName("li");
var j = 0;
if (arRelatedVids.length > 0) {
for (var i = arRelatedVids.length-1; i > -1; i–) {
if (arRelatedVids[i].textContent.indexOf("Recommended for you") != -1) {
//console.log("YAD: Removing " + arRelatedVids[i].textContent);
arRelatedVids[i].parentNode.removeChild(arRelatedVids[i]);
++j;
}
}
}
console.log("YAD: Removed " + j + " recommended videos");
}
oRelatedColumn = document.getElementById("watch7-sidebar-modules");
if (oRelatedColumn != null) {
var arRelatedVids = oRelatedColumn.getElementsByClassName("watch-sidebar-section");
var j = 0;
if (arRelatedVids.length > 0) {
for (var i = arRelatedVids.length-1; i > -1; i–) {
if (arRelatedVids[i].textContent.indexOf("Recommended for you") != -1) {
//console.log("YAD: Removing " + arRelatedVids[i].textContent);
arRelatedVids[i].parentNode.removeChild(arRelatedVids[i]);
++j;
}
}
}
console.log("YADN: Removed " + j + " new recommended videos");
}
}
function disableAndHideAdContainers() {
console.log("YAD: Disabling/deleting ad containers…");
var arDivIds = ["AdSense", "watch7-sidebar-ads", "promotion-shelf", "live-chat-iframe", "invideo-overlay:7", ];
var arDivClasses = [ "adDisplay", "annotation", "html5-endscreen", "iv-promo", "video-ads", "videoAdUiBottomBar", "ytp-ad-module", "ytp-endscreen-content", "ytp-cards-button", "ytp-cards-teaser", "ytp-ad-overlay-container", "ytp-ad-overlay-slot", "ytp-ad-text-overlay", "ytp-ad-overlay-ad-info-button-container", "ytp-ad-hover-text-button", "ytp-ad-info-hover-text-button", "ytp-ad-overlay-text-image", "ytp-ad-overlay-text-image", "ytp-ad-image-overlay", "ytp-ad-overlay-close-container", "ytp-ad-overlay-close-button" ];
for (var i = 0; i < arDivIds.length; i++) {
var oDiv = document.getElementById(arDivIds[i]);
if (oDiv != null) {
oDiv.style.visibility = "hidden!important";
oDiv.style.display = "none!important";
oDiv.parentNode.removeChild(oDiv);
console.log("YAD: Removed " + arDivIds[i] + " by ID");
} else {
console.log("YAD: Not found: " + arDivIds[i] + " by ID");
}
sAdStyle = "#" + arDivIds[i] + ((i==0)?" ":" , ") + sAdStyle;
}
for (var i = 0; i < arDivClasses.length; i++) {
var oDivs = document.getElementsByClassName(arDivClasses[i]);
if (oDivs != null) {
for (var j = 0; j < oDivs.length; j++) {
oDivs[j].style.visibility = "hidden!important";
oDivs[j].style.display = "none!important";
oDivs[j].parentNode.removeChild(oDivs[j]);
}
} else {
console.log("YAD: Not found: " + oDivs[j] + " by ID");
}
sAdStyle = "*." + arDivClasses[i] + " , " + sAdStyle;
}
document.getElementsByTagName("head")[0].innerHTML = document.getElementsByTagName("head")[0].innerHTML + "\n<style>" + sAdStyle + "\n</style>";
}
function changeRegion() {
var oLangButton = document.getElementById("yt-picker-country-button");
if (oLangButton != null) {
if (oLangButton.textContent.indexOf("United States") == -1) {
oLangButton.click();
window.setTimeout(
function() {
var arRegions = document.getElementsByClassName("yt-picker-item");
for (var i = 0; i < arRegions.length; i++) {
if (arRegions[i].textContent.indexOf("United States") > -1) {
arRegions[i].click();
break;
}
}
}, 3*1000);
}
}
}
function changeProfileLink() {
console.log("YAD: Changing profile link")
var oDivs = document.getElementsByTagName("div");
if ((oDivs != null) && (oDivs.length > 0)) {
for (var i = 0; i < oDivs.length; i++) { if (oDivs[i].className == "yt-user-info") {
var oAnchors = oDivs[i].getElementsByTagName("a");
if ((oAnchors != null) && (oDivs.length>1)) {
var bFound = false;
for (var j = 0; j < oAnchors.length; j++) {
if (oAnchors[j].href.substring(0, "https://www.youtube.com/channel/&quot;.length) == "https://www.youtube.com/channel/&quot;) {
oAnchors[j].href = oAnchors[j].href + "/videos";
oLatestVideosLink = document.createElement("a");
oLatestVideosLink.setAttribute("style", "background-image: url(https://s.ytimg.com/yts/imgbin/www-hitchhiker-vflYQU35a.png); width: 17px; height: 17px; background-position: -94px -472px; border-style: none; margin: 0; padding: 0; ");
oLatestVideosLink.setAttribute("id", "MvPopularLink");
oLatestVideosLink.setAttribute("href", oAnchors[j].href + "?view=0&sort=p&flow=grid");
oAnchors[j].insertAdjacentHTML("afterend", oLatestVideosLink.outerHTML);
bFound = true;
break;
}
}
if (bFound) { break; }
}
}
}
}
}
var iLoadAllCommentsTimeout = 0;
function loadAllComments() {
if (iLoadAllCommentsTimeout > 0) {
window.clearTimeout(iLoadAllCommentsTimeout);
}
var oDiv = document.getElementById("watch-discussion");
if (oDiv == null) { return; }
var oButtons = oDiv.getElementsByClassName("comment-section-renderer-paginator");
if (oButtons != null) {
console.log("YAD: Comments");
if (oButtons[0] != null) {
oButtons[0].click();
iLoadAllCommentsTimeout = window.setTimeout(loadAllComments, 20*1000);
}
}
}
function parseYTPlayer() {
console.log("YAD: Inside parser" );
console.log("YAD: Title" + ytplayer.config.args.title);
try {
if (document.getElementsByTagName("video")[0] && (document.getElementsByTagName("video")[0].pause)) {
document.getElementsByTagName("video")[0].pause();
}
} catch (e) {
window.alert(e);
}
var arFormatParams, arFormats, i, j, sURL, sQuality, sMimeType, sExtension;
var oDlList, oDlListItem;
oDlList = document.getElementById("mvyJsList");
if (oDlList == null) {
return;
}
oDlList.innerHTML += "<li><a href=\"" + location.href.replace("www.you", "www.hook") + "\" style=\"color: navy; font-weight: bold; \" target=\"_blank\">Load in HookTube</a></li>";
var oFormats = JSON.parse(ytplayer.config.args.player_response);
var arFormats = oFormats.streamingData.formats;
for (i = 0; i < arFormats.length; i++) {
oDlListItem = document.createElement("li");
var sFormat = arFormats[i].mimeType.split(';')[0];
if (arFormats[i].mimeType.split(';')[0] == "video/mp4") {
sFormat = "M";
} else if (arFormats[i].mimeType.split(';')[0] == "video/webm") {
sFormat = "W";
}
console.log("YAD: Format " + arFormats[i].quality + " – " + arFormats[i].qualityLabel + " – " + arFormats[i].mimeType.split(';')[0]);
oDlListItem.innerHTML = "<a title=\"" + arFormats[i].mimeType.replace(/\"/g,"") + "\" style=\"color: navy; font-weight: bold; \" target=\"_blank\" href=\"" + arFormats[i].url + "\">" + document.title.replace(" – YouTube", "") + " – " + arFormats[i].qualityLabel + " " + sFormat + "</a>";
oDlList.appendChild(oDlListItem);
}
}
function addCurrentPlayURL() {
var oList = document.getElementById("mvyJsList");
if (oList != null) {
if (document.getElementById("movie_player") != null) {
if (document.getElementById("movie_player").getElementsByTagName("video") != null) {
var oVideo = document.getElementById("movie_player").getElementsByTagName("video")[0];
if (oVideo.src) {
oList.innerHTML += "<li><a id=\"VidLinkUrl\" title=\"" + document.title + "\" download=\"" + document.title.replace(/\s+/ig, "-").replace(/-{2,}/ig, "-") + ".mp4\" style=\"color: navy; font-weight: bold; \" target=\"_blank\" href=\"" + oVideo.src + "\">" + document.title + "</a></li>";
console.log("YAD: Video URL = " + oVideo.src);
oVideo.addEventListener(
"loadeddata",
function() {
console.log("YAD: New video loaded");
document.getElementById("VidLinkUrl").setAttribute("href", document.getElementsByTagName("video")[0].src);
}, false);
} else {
console.log("YAD: Error in player");
}
}
} else {
console.log("YouTube detector: No player");
oList.innerHTML += "<li><a style=\"color: navy; font-weight: bold; \"href=\"" + location.href.replace("www.you", "www.hook") + "\" style=\"color: navy; font-weight: bold; \" target=\"_blank\">Load in HookTube</a></li>";
}
}
}
function addVideoDownloadList() {
console.log("Executing YouTube detector");
var i, n, oDlButtonEl, oVideosList;
oDlDiv = document.createElement("div");
oDlDiv.setAttribute("id", "mvyJsDiv");
oDlDiv.setAttribute("style", "background-color: orange!important; border: 2px dashed firebrick; font-size: 0.34cm!important; font-family: sans-serif!important; line-height: 0.4cm!important; margin: 1em auto; padding: 1em; min-height: 120px; ");
oDlDiv.innerHTML = "Download video from:";
var oTwitterImage = document.querySelector("html head meta[name='twitter:image']");
console.log("YAD: Twitter image" + oTwitterImage.getAttribute("content"));
if (oTwitterImage) {
oDlDiv.innerHTML += "<img src=\"" + oTwitterImage.getAttribute("content") + "\" style=\"max-width: 200px; float: right; margin: 1em auto 1em 1em; \" />\n";
} else if (window.URL) {
var oURL = new URL(location.href);
var sID = oURL.searchParams.get("v");
oDlDiv.innerHTML += "<img src=\"https://i.ytimg.com/vi/&quot; + sID + "/hqdefault.jpg\" style=\"max-width: 200px; float: right; margin: 1em auto 1em 1em; \" />";
}
oDlList = document.createElement("ul");
oDlList.setAttribute("style", "display: block; list-style: disc inside none; margin-left: 1em!important; ");
oDlList.setAttribute("id", "mvyJsList");
oDlDiv.appendChild(oDlList);
if (location.href.indexOf("youtube.com/watch") > -1) {
document.getElementById("watch-headline-title").appendChild(oDlDiv);
addCurrentPlayURL();
parseYTPlayer();
} else if (location.href.indexOf("youtube.com/embed/") > -1) {
// Use the script com.vsubhash.js.embedded-video-catcher
}
}

This browser user js is also available at
https://openuserjs.org/scripts/zomberi/YouTube_AdBlocker_N_Annoyances_Remover

Greasemonkey script to click the “Load More” button of YouTube video pages

YouTube forces its content creators to create lots of videos than is necessary. I have been watching the drawing videos of an artist. She is now posting videos every day, not about drawing but about her everyday activities. In these videos, she posts links to the real drawing videos or tells about them in advance. It’s awful. She is not alone. There are lots of people who seem to be doing this. There was this one guy whose electronics videos I watched a few times. I decided to check what else he had posted. Yikes! A whole lot of useless nothingness videos! I didn’t see them earlier because I always change the filter to “Most popular”.

If content creators stop making such videos, YouTube lets their earnings fall. This is because only the latest videos of subscribed channels are listed when people launch the YouTube app. If a content creator does not produce at least two or three videos per week, it is easy to get hidden by other channels when he/she does release a new video after a long break.

I use bookmarks and the hidden RSS feeds of YouTube. I don’t login and I don’t watch them live. Because of unexplained lag issues, I download the videos and watch them offline on my WDTV device.

When I check the videos pages, only some video thumbnails are listed there. There is a “Load More” button, which needs to be clicked several times to get the full listing. Sometimes the Net connection breaks during this interval and the expansion of the page stops. I need to then refresh the page and then click the button a few times to get to down to where I was. So, I wrote this Greasemonkey script to that for me. I load the video page and the script automatically clicks the button several times, waiting for sometime between each click to let the videos thumbnails.


// ==UserScript==
// @name YouTube LoadMore Till No More
// @namespace com.vsubhash.js.youtube-load-more-till-no-more
// @description Automatically expands the videoslist
// @include /https://www\.youtube\.com/(channel|user)/(\w+)/videos*/
// @exclude %exclude%
// @version 2018
// @grant none
// ==/UserScript==
var iYLM_Timeout = 0;
var iCounter = 0;
document.addEventListener("DOMContentLoaded", startItDelayed, false);
function startItDelayed() {
iYLM_Timeout = window.setTimeout(loadMore, 10*1000);
}
function loadMore() {
console.log("YLM: We are in");
if (document.getElementsByClassName("load-more-button").length > 0) {
if (document.getElementsByClassName("load-more-button")[0].getElementsByClassName("load-more-text").length > 0) {
document.getElementsByClassName("load-more-button")[0].getElementsByClassName("load-more-text")[0].click();
console.log("YLM: Loading more " + (++iCounter));
startItDelayed();
}
} else if (iYLM_Timeout != 0) {
console.log("YLM: No more found ");
window.clearTimeout(iYLM_Timeout);
}
}

With this script, I open the videos page to let it roll out. Meanwhile, I browse some other page. By the time I come back to the video page, all the thumbnails are listed.

Greasemonkey JavaScript-based YouTube adblocker and annoyances remover

Watching YouTube online is still impossible for me – the Net connection is still flaky and there are disturbances in the electricity supply. Downloading the videos and playing them offline is still the only option for me. Even then, the YouTube comes with a great deal of annoyances – ads (text and video), autoplay, “Recommended for you” video list, lack of RSS feeds, half-hidden description, YouTube-curated (or censored) “Top Comments”.

I have created several Greasemonkey scripts to deal with YouTube. Recently, I added a few more. Here they are:

The last one is new. It does several things – disables video ads, hides text ads, disables autoplay, deletes “recommended for you” ads.

Disabling video ads was tricky. The current implementation opens the same video URL in another tab and closes the current tab. This is repeated until YouTube relents and loads the original video. This can range anywhere from 2 to 10 reloads, probably. The code also finds the mute button and mutes the ad.


// ==UserScript==
// @name YouTube Ads Disabler
// @namespace com.vsubhash.js.youtube-ads-disabler
// @description Disables ads, swithces off autoplay, adds RSS link, deletes "recommended for you" videos, unhides description, displays latest comments
// @include https://www.youtube.com/watch*
// @version 1
// @grant none
// ==/UserScript==
try {
window.setTimeout(
function() {
document.getElementsByTagName('video')[0].pause();
document.getElementsByTagName('video')[1].pause();
},
5*1000);
} catch (e) {
console.error("YAD Error: " + e);
}
document.addEventListener("DOMContentLoaded", fixYouTubeAnnoyances, false);
function fixYouTubeAnnoyances() {
console.log("YAD: Here");
var sAdStyle = " { visibility: none!important; display: none!important; }";
try {
window.setTimeout(closeVideoAds, 1*1000);
window.setTimeout(showDescription, 2*1000);
window.setTimeout(removeRecommendedForYouAds, 3*1000);
window.setTimeout(disableAndHideAdContainers, 4*1000);
window.setTimeout(disableAutoPlay, 5*1000);
} catch (e) {
console.error("YAD Error: " + e);
}
}
function closeVideoAds() {
console.log("YAD: Detecting video ads…");
if ((document.getElementsByClassName("videoAdUiTopButtons").length > 0) || (document.getElementsByClassName("videoAdUi").length > 0)) {
console.log("YAD: Video ad found");
window.open(location.href, '_blank');
//window.open(location, '_self').close();
window.close();
if (document.getElementsByClassName("ytp-mute-button").length > 0) {
console.log("YAD: Video ad mute button found");
if (document.getElementsByClassName("ytp-volume-panel").length > 0) {
if (document.getElementsByClassName("ytp-volume-panel")[0].getAttribute("aria-volumetext") != "100% volume muted") {
document.getElementsByClassName("ytp-mute-button")[0].click();
console.log("YAD: Video ad muted");
}
}
}
} else {
console.log("YAD: No video ad");
}
}
function disableAutoPlay() {
console.log("YAD: Disabling autoplay…");
var arAutoPlayIds = [ "toggleButton", "autoplay-checkbox" ];
for (var i = 0; i < arAutoPlayIds.length; i++) {
console.log("YAD: Checking for autoplay ID " + arAutoPlayIds[i]);
if ((document.getElementById(arAutoPlayIds[i]) != null) && (document.getElementById(arAutoPlayIds[i]).checked)) {
console.log("YAD: Aautoplay ID found " + arAutoPlayIds[i]);
document.getElementById(arAutoPlayIds[i]).click();
console.log("YAD: Autoplay ID disabled – " + arAutoPlayIds[i]);
}
}
}
function showDescription() {
console.log("YAD: Finding description…");
if (document.getElementById("action-panel-details") != null) {
document.getElementById("action-panel-details").className = "action-panel-content yt-uix-expander yt-card yt-card-has-padding";
}
console.log("YAD: Description unhidden.");
}
function removeRecommendedForYouAds() {
console.log("YAD: Removing recommended videos");
var oRelatedColumn = document.getElementById("watch-related");
if (oRelatedColumn != null) {
var arRelatedVids = oRelatedColumn.getElementsByTagName("li");
var j = 0;
if (arRelatedVids.length > 0) {
for (var i = arRelatedVids.length-1; i > -1; i–) {
if (arRelatedVids[i].textContent.indexOf("Recommended for you") != -1) {
//console.log("YAD: Removing " + arRelatedVids[i].textContent);
arRelatedVids[i].parentNode.removeChild(arRelatedVids[i]);
++j;
}
}
}
console.log("YAD: Removed " + j + " recommended videos");
}
}
function disableAndHideAdContainers() {
console.log("YAD: Disabling/deleting ad containers…");
var arDivIds = ["AdSense", "watch7-sidebar-ads", "promotion-shelf", "live-chat-iframe"];
var arDivClasses = [ "adDisplay", "annotation", "html5-endscreen", "iv-promo", "videoAdUiBottomBar", "ytp-endscreen-content", "ytp-cards-button", "ytp-cards-teaser" ];
for (var i = 0; i < arDivIds.length; i++) {
var oDiv = document.getElementById(arDivIds[i]);
if (oDiv != null) {
oDiv.style.visibility = "hidden!important";
oDiv.style.display = "none!important";
oDiv.parentNode.removeChild(oDiv);
console.log("YAD: Removed " + arDivIds[i] + " by ID");
} else {
console.log("YAD: Not found: " + arDivIds[i] + " by ID");
}
sAdStyle = "#" + arDivIds[i] + ((i==0)?" ":" , ") + sAdStyle;
}
for (var i = 0; i < arDivClasses.length; i++) {
var oDivs = document.getElementsByClassName(arDivClasses[i]);
if (oDivs != null) {
for (var j = 0; j < oDivs.length; j++) {
oDivs[j].style.visibility = "hidden!important";
oDivs[j].style.display = "none!important";
oDivs[j].parentNode.removeChild(oDivs[j]);
}
} else {
console.log("YAD: Not found: " + oDivs[j] + " by ID");
}
sAdStyle = "*." + arDivClasses[i] + " , " + sAdStyle;
}
document.getElementsByTagName("head")[0].innerHTML = document.getElementsByTagName("head")[0].innerHTML + "\n<style>" + sAdStyle + "\n</style>";
}

NOTE: I use an old version of Firefox and I spoof a newer but still old version in it. YouTube and other Google sites serve different styles of pages for different browser versions. The above code works with Firefox 42. To make the code work, you can spoof version 42 using the UserAgent Switcher add-on with this UA string.

Mozilla/5.0 (Windows NT 6.2; rv:42) Gecko/20100101 Firefox/42.0

Of course, I will not be publishing the ad-blocking code. YouTube apocalypse is on now. Ad agencies have done to YouTube what they had been doing for decades to newspaper and TV journalism – interfering in content. After CNN decided to launch a crusade against Alex Jones’ YouTube channels, ad agencies are now telling YouTube that their ads should not be playing on “controversial” content. The bottomline now is that videos from big music labels and stars can have all kind of crude/vulgar/unsuitable content but ordinary folk stepping out of the line will have to be immediately “demonetized.” I found one retired nurse, who publishes makeup tutorials, complaining that she never said a bad word or anything controversial but all her videos were demonetized.

Until the said apocalypse, YouTube content creators seem to have been generously paid. When the times were good, YouTube went all over the world asking people to make videos and make tons of money. Now, YouTube’s revenues are down and the first victims are the small and independent content creators who took YouTube’s bait. A million page views earns the creators very little. It is only with off-YouTube marketing deals and paid-promotion that YouTube content creators can make money. I am surprised that that many seemingly intelligent people left their day jobs and became “Youtubers” full time. Even more sad are the legion of retired folks whose savings have been destroyed by Bush and Obama’s zero-interest monetary regime and free-trade policies, and Wall Street’s looting of pension funds and local government funds. There can be no economy without local manufacturing. Selfies and cat videos are not what an advanced economy runs on.

Anyway, I can tolerate text ads. The videos ads are horrible. The “recommended for you” videos are downright creepy. Why are they recommended for me?

Greasemonkey script to display newer comments on YouTube – bypass censorship

Changes comments filter to “Newest first” from “Top comments”

YouTube has been raining on the parade of its content creators with demonetization, censorship and unexplained notifications disablement. Youtube comments are also being censored. The default filter is not “Newest first” or “Oldest first” but “Top comments”. Trolls will eventually game the system. I would rather see unfiltered comments. So, here it is:


// ==UserScript==
// @name Show newer YouTube comments
// @namespace com.vsubhash.js.show-youtube-comments-newer
// @description Automatically changes YouTube comments filter off
// @include https://www.youtube.com/watch*
// @exclude %exclude%
// @version 2018
// @grant none
// ==/UserScript==
document.addEventListener("DOMContentLoaded", startItDelayed, false);
function startItDelayed() {
window.setTimeout(switchCommentsList, 10*1000);
}
function switchCommentsList() {
console.log("Showing newer comments");
var arButtons = document.getElementsByTagName("button");
console.log(arButtons.length);
var bFound = false;
for (var i = 0; i < arButtons.length; i++) {
//console.log(arButtons[i].textContent);
if (arButtons[i].textContent.trim() == "Top comments") {
arButtons[i].click();
bFound = true;
break;
}
}
if (bFound) {
//console.log("Menu found————–");
var arButtons = document.getElementsByTagName("button");
console.log(arButtons.length);
for (var i = 0; i < arButtons.length; i++) {
//console.log(arButtons[i].textContent);
if (arButtons[i].textContent.trim() == "Newest first") {
arButtons[i].click();
bFound = true;
break;
}
}
}
}

A GreaseMonkey script to generate RSS feed links for YouTube channels

Many people use RSS feeds as the primary means to access news and information. RSS is anonymous and does not require you to log in.

Though YouTube generates RSS feeds for its channels, it does not display them (to human visitors) or advertise them (to browser software). If you prefer to subscribe to YouTube videos via RSS, then you have to manually construct the the feed URL for each channel.

I decided to automate the task using this Greasemonkey script. A few seconds after a YouTube video page gets loaded, the Greasemonkey Javascript adds an RSS icon image next to the channel name. The script links the image to the RSS feed of the YouTube channel. (This RSS icon image works seamlessly as it is from Google and is used in its “News” pages.) The Greasemonkey script also adds an RSS link tag to the HTML HEAD section so that browser applications can activate their RSS feed toolbar button.


// ==UserScript==
// @name YouTube RSS feed generator
// @namespace com.vsubhash.js.youtube-rss-feed-generator
// @description Adds a RSS feed button to YouTube channels
// @include https://www.youtube.com/watch*
// @version 2018
// @grant none
// ==/UserScript==
document.addEventListener("DOMContentLoaded", startItDelayed, false);
function startItDelayed() {
if (document.getElementById("YT_RSS_Feed") == null) {
window.setTimeout(addRssButton, 6*1000);
}
}
function addRssButton() {
console.log("Executing YouTube RSS feed generator")
var oDivs = document.getElementsByTagName("div");
if ((oDivs != null) && (oDivs.length > 0)) {
for (var i = 0; i < oDivs.length; i++) { if (oDivs[i].className == "yt-user-info") {
//console.log("YRFG Error: Here");
var oAnchors = oDivs[i].getElementsByTagName("a"); if ((oAnchors != null) && (oDivs.length>1)) {
var bFound = false;
for (var j = 0; j < oAnchors.length; j++) {
//console.log("YRFG Error: " + oAnchors[j].href.substring(0, "https://www.youtube.com/channel/&quot;.length));
if (oAnchors[j].href.substring(0, "https://www.youtube.com/channel/&quot;.length) == "https://www.youtube.com/channel/&quot;) {
var sChannelId = oAnchors[j].href.substring("https://www.youtube.com/channel/&quot;.length);
var oRssElement = document.createElement("a");
oRssElement.id = "YT_RSS_Feed";
oRssElement.href = "https://www.youtube.com/feeds/videos.xml?channel_id=&quot; + sChannelId;
oRssElement.innerHTML = "<img src=\"https://www.google.com/images/rss.png\" style=\"margin: auto 1em; \" />";
oAnchors[j].appendChild(oRssElement);
var oLinkElement = document.createElement("link");
oLinkElement.setAttribute("rel", "alternate");
oLinkElement.setAttribute("title", oAnchors[j].textContent);
oLinkElement.setAttribute("type", "application/rss+xml");
oLinkElement.setAttribute("href", "https://www.youtube.com/feeds/videos.xml?channel_id=&quot; + sChannelId);
document.getElementsByTagName("head")[0].appendChild(oLinkElement);
bFound = true;
break;
}
}
if (bFound) { break; }
}
}
}
}
}

A YouTube channel listing in the Bamboo RSS feed reader (a Firefox add-on or extension).

RSS provides an easier way to check Youtube channels. All that matters to YouTube is that people see their ads. RSS does not block ads and so no problem. Viewers who rely on subscriptions are likely to miss new but not so fresh videos if they don’t log in regularly. (Such videos get folded/wrapped/hidden as newer videos are published.) YouTube RSS feeds can ensure that viewers are more likely to get to know about the existence of a new video.

And, to use this script, you will need the Greasemonkey add-on in the browser. It can be installed from the Firefox/Seamonkey browser add-on search page (Tools – Add-ons from the main menu).

This article has been submitted to .

How to download & play YouTube videos offline using Subhash Browser app for Android

Youtube videos don’t play in any of my Android devices, that is, in the browsers. I think their Javascript tries to launch the YouTube app and remains stuck there (because I delete/disable all Google apps).

Fortunately, my app has a Javasript script which lets me download the videos as a file for offline viewing.

http://www.vsubhash.com/article.asp?id=126&info=Subhash_Browser_ultimate_browser_and_RSS_feed_reader_app_for_Android

Download Any YouTube Video From Anywhere 2016 – User JS for Opera 12.x, Firefox and Android

SCREENSHOT-Subhash-Browser-YouTube-Video-DownloadMy Internet connection does not allow me to play videos live. I need to download them first and then play them. I used to use a FireFox extension called Download YouTube as FLV and MP4 for this. However, my primary browser is Opera 12.x. Today, I decided to write a User JS that would provide the same functionality in Opera 12.x. (The Opera browser company does not provide 12x anymore. They sold out and provide a crappy Chrome imitation.) UPDATE: I adapted this script for my Android browser app and also created a Greasemonkey version for Firefox. On Youtube pages, it displays a drop-down list with download options in various formats. On other pages that have inline videos, it adds a download button. (Check http://softwarerecs.stackexchange.com/questions/817/software-to-download-youtube-videos-to-hard-drive/32132#32132)


// ==UserScript==
// @name YouTube Downloader JavaScript
// @namespace com.vsubhash.js.youtube-downloader
// @description Downloads YouTube videos
// @include https://www.youtube.com/*
// @version 2018
// @grant none
// ==/UserScript==
/*
* Moral Volcano's YouTub DL JavaScript
* Licensed under GPL v3 as provided at
* https://www.gnu.org/licenses/gpl.html
*
*/
document.addEventListener("DOMContentLoaded", addYouTubeDetectingButton, false);
function parseYTPlayer() {
console.error("Inside parser" );
console.error("Title" + ytplayer.config.args.title);
console.error("Format" + unescape(ytplayer.config.args.adaptive_fmts));
try {
if (document.getElementsByTagName("video")[0] && (document.getElementsByTagName("video")[0].pause)) {
document.getElementsByTagName("video")[0].pause();
}
} catch (e) {
window.alert(e);
}
var arFormatParams, arFormats, i, j, sURL, sQuality, sMimeType, sExtension;
var oSelect, oOption;
oSelect = document.getElementById("mvyJsVideoDownloadList");
if (oSelect == null) {
return;
} else {
// Reset download list
oSelect.length = 0;
}
arFormats = ytplayer.config.args.url_encoded_fmt_stream_map.split(",");
for (i = 0; i < arFormats.length; i++) {
//console.error("Format " + i + ". " + arFormats[i]);
arFormatParams = arFormats[i].split("&")
sURL = "";
for (j = 0; j < arFormatParams.length; j++) {
// console.error("\tFormat parameter " + arFormatParams[j]);
if (arFormatParams[j].indexOf("url=") > -1) {
sURL = unescape(arFormatParams[j].substring("url=".length));
} else {
if (arFormatParams[j].indexOf("type=") > -1) {
sMimeType = unescape(arFormatParams[j].substring("type=".length));
}
if (arFormatParams[j].indexOf("quality=") > -1) {
sQuality = arFormatParams[j].substring("quality=".length);
}
}
}
if ((sURL.length > 0) && (sQuality.length > 0) && (sMimeType.length > 0)) {
oOption = document.createElement("option");
oOption.text = sQuality + " – " + sMimeType;
sURL = sURL +
"&ptk=youtube_none&pltype=contentugc" +
"&title=" +
escape(ytplayer.config.args.title);
//console.error("Final URL " + sURL);
oOption.setAttribute("onclick", "(function() { location.href = '" + sURL + "'; })();");
oSelect.add(oOption);
}
}
if (oSelect.length > 0) {
oSelect.style.display = "inline";
} else {
oSelect.style.display = "none";
window.alert("Some error had occurred");
}
}
function handle_DownloadButtonClick() {
if (document.getElementsByTagName("video").length > 0) {
if (document.getElementsByTagName("video")[0].src.length > 10) {
document.getElementById("mvJsLink").setAttribute("href",document.getElementsByTagName("video")[0].src + "&title=" + escape(document.title));
document.getElementById("mvJsLink").innerHTML = document.getElementsByTagName("video")[0].src.substring(0,35) + "…";
document.getElementById("mvJsLink").click();
} else {
window.alert("First play the video a bit and pause. Then, we will get the video link.");
}
} else {
window.alert("No video has loaded yet.");
}
}
function addYouTubeDetectingButton() {
console.log("Executing YouTube detector");
var i, n, oDlButtonEl, oDlDiv, oVideosList;
if ((location.href.indexOf("youtube.com/embed") != -1) ||
(location.href.indexOf("youtube.com/watch") != -1)) {
console.log("Inside YouTube Iframe");
oDlDiv = document.createElement("div");
oDlDiv.setAttribute("id", "mvyJsDiv");
oDlDiv.setAttribute("style", "color: black; padding-left: 1em; background-color: orange!important; width: 100%!important; height: 1.2cm!important; font-size: 0.34cm!important; line-height: 0.4cm!important; font-family: sans-serif!important; ");
if (location.href.indexOf("youtube.com/embed") > -1) {
oDlButtonEl = document.createElement("input");
oDlDiv.setAttribute("id", "mvJsButton");
oDlButtonEl.setAttribute("type", "button");
oDlButtonEl.setAttribute("value", "Grab Video");
oDlButtonEl.addEventListener("click", handle_DownloadButtonClick, false);
oDlButtonEl.setAttribute("style", "color: white!important; border: 1px solid orange; box-shadow: 2px 2px 5px black; background-color: red!important; height: 0.9cm!important; width: 5cm!important; font-size: 0.4cm!important; line-height: 0.5cm!important; ; font-family: sans-serif!important;");
oDlDiv.appendChild(oDlButtonEl);
oVidLink = document.createElement("a");
oVidLink.setAttribute("id", "mvJsLink");
oVidLink.setAttribute("style", "color: darkblue!important; text-decoration: underline!important; font-size: 0.3cm!important; margin: 0.2cm 1cm 0.2cm 1cm!important;");
oVidLink.innerHTML="Video URL";
oVidLink.setAttribute("href","javascript:window.alert('First play the video a bit and pause. Then, we will get the video link.');");
oDlDiv.appendChild(oVidLink);
document.getElementById("player").parentNode.insertBefore(oDlDiv, document.getElementById("player"));
} else {
oDlDiv.innerHTML = "Download video from:";
oVideosList = document.createElement("select");
oVideosList.setAttribute("id", "mvyJsVideoDownloadList");
oVideosList.setAttribute("style", "display: none; font-size: 0.3cm!important; margin: 0.2cm 1cm 0.2cm 1em!important;");
oDlDiv.appendChild(oVideosList);
document.getElementById("player").parentNode.insertBefore(oDlDiv, document.getElementById("player"));
parseYTPlayer();
}
document.getElementById("player").setAttribute("style", document.getElementById("player").getAttribute("style") + "height: 90%!important; ");
document.getElementsByTagName("body")[0].style="background-color: white!important; line-height: 0.5cm;";
document.getElementById("player").parentNode.style="background-color: white!important; ";
}
}