您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
Change the window title on YouTube based on the channel name and video title, and append the website name on Spotify and SoundCloud pages.
// ==UserScript== // @name Audio Tab Title // @description Change the window title on YouTube based on the channel name and video title, and append the website name on Spotify and SoundCloud pages. // @version 0.6.6 // @namespace itsafeature.org // @author Geoffrey De Belie (Smile4ever) // @license Unlicense // @match https://www.youtube.com/watch?v=* // @match https://music.youtube.com/* // @match https://open.spotify.com/* // @match https://soundcloud.com/* // @match https://music.amazon.com/* // @grant none // ==/UserScript== (function() { 'use strict'; // Format GrupoBryndisOficial to Grupo Bryndis function formatChannelName(name) { if (!name.includes(" ")) { name = name.replace(/([a-z])([A-Z])/g, '$1 $2'); // Add spaces if none exist } return name.replace("Oficial", "").trim(); // Remove "Oficial" and trim spaces } // Function to update the title on YouTube function updateYouTubeTitle() { const metadataElementArtist = document.querySelector(".yt-video-attribute-view-model__metadata h4"); // Artist const metadataElementArtistText = metadataElementArtist?.innerText ?? ""; const metadataElementTitle = document.querySelector(".yt-video-attribute-view-model__metadata h1"); // Title const metadataElementTitleText = metadataElementTitle?.innerText ?? ""; const channelElement = document.querySelector('a.yt-simple-endpoint.style-scope.yt-formatted-string'); const channelName = channelElement?.innerText ?? ""; const channelNameClean = formatChannelName(channelName.split(' - ')[0].split('|')[0]); const videoTitleElement = document.querySelector('#above-the-fold #title'); let videoTitle = videoTitleElement?.innerText ?? ""; const spaceIndex = videoTitle.indexOf(' '); const dashIndex = videoTitle.indexOf('-'); const spaceDashIndex = videoTitle.indexOf(' - '); const lastDashIndex = videoTitle.lastIndexOf('-'); // Cleanup videoTitle videoTitle = videoTitle.replace(" - Video Oficial", ""); videoTitle = videoTitle.replace(" - Video", ""); // We need the video title element, if it's not found the page structure must have changed if(videoTitleElement == null) return; if (metadataElementArtist && metadataElementTitle && lastDashIndex != -1){ const contentAfterDash = videoTitle.substring(lastDashIndex + 1).trim(); if (contentAfterDash.toLowerCase().includes(metadataElementArtistText.toLowerCase())) { // If metadata artist appears after the dash in video title, fix the tab title document.title = `${metadataElementArtistText} - ${metadataElementTitleText} - YouTube`; return; } } // Fix dash, for example Marco Antonio Solís — Eran Mentiras if(dashIndex == -1 && videoTitle.indexOf("—") != -1){ document.title = `${videoTitle.replace("—", "-")} - YouTube`; return; } // Fix comma's, for example Marco Antonio Solís, Los Bukis - Será Mejor Que Te Vayas // But don't break Olvídala, Binomio De Oro De América - Video Oficial if(spaceDashIndex != -1 && videoTitle.indexOf(", ") != -1 && metadataElementArtistText.indexOf(", ") != -1){ document.title = `${videoTitle.split(", ")[0]} - ${videoTitle.split(" - ")[1]} - YouTube`; return; } // Use metadata if available, but not if the artist and title are the same if (metadataElementArtist && metadataElementTitle && metadataElementArtistText != metadataElementTitleText && metadataElementArtistText.includes("|") == false) { // Set the window title for YouTube if needed document.title = `${metadataElementArtistText} - ${metadataElementTitleText} - YouTube`; return; } // Sombras, Los Betas - Video if(videoTitle.indexOf("-") == -1 && videoTitle.indexOf(", ") != -1){ document.title = videoTitle.replace(", ", " - ") + " - YouTube"; return; } // Fall back to channel + video title approach if (channelElement && videoTitle.includes('-') == false) { // If there's no space, continue. If the first dash appears before the first space, get out (case A-ha) if (spaceIndex != -1 && dashIndex < spaceIndex) return; // Set the window title for YouTube if needed if(videoTitle.includes(channelNameClean) == false){ document.title = `${channelNameClean} - ${videoTitle} - YouTube`; return; } } } // Function to update the title on YouTube Music function updateYouTubeMusicTitle() { const elements = document.querySelectorAll('.ytmusic-player-bar yt-formatted-string'); if (elements.length < 2) return; const artistElement = elements[1]; const audioTitleElement = elements[0]; if (artistElement && audioTitleElement) { const artistName = artistElement.childNodes[0].innerText; const audioTitle = audioTitleElement.innerText; // Set the window title for YouTube Music document.title = `${artistName} - ${audioTitle} - YouTube Music`; } } // Function to update the title on Spotify function updateSpotifyTitle() { const titleElement = document.querySelector('title'); // Get the <title> element if (titleElement.innerText.includes(" - Spotify") == false) { titleElement.innerText = `${titleElement.innerText} - Spotify`; // Set the title's innerText for Spotify } } function updateSoundCloudTitle() { const titleElement = document.querySelector('title'); // Get the <title> element if (titleElement.innerText.includes(" - SoundCloud") == false) { titleElement.innerText = `${titleElement.innerText} - SoundCloud`; // Set the title's innerText for Spotify } } function updateAmazonMusicTitle(){ const shadowHost = document.querySelector('music-horizontal-item'); const shadowRoot = shadowHost.shadowRoot; const musicLinks = shadowRoot.querySelectorAll('music-link'); if (musicLinks.length >= 2) { const songTitle = musicLinks[0].getAttribute('title'); const artistTitle = musicLinks[1].getAttribute('title'); document.title = `${artistTitle} - ${songTitle} - Amazon Music`; } } // Function to check for the current platform function updateTitle() { if (window.location.hostname == 'music.youtube.com'){ updateYouTubeMusicTitle(); } else if (window.location.hostname.includes('youtube.com')) { updateYouTubeTitle(); } else if (window.location.hostname.includes('spotify.com')) { updateSpotifyTitle(); } else if (window.location.hostname.includes('soundcloud.com')) { updateSoundCloudTitle(); } else if (window.location.hostname.includes('music.amazon.com')) { updateAmazonMusicTitle(); } } // Optionally, observe changes in the page if the title might update after load const observer = new MutationObserver(updateTitle); observer.observe(document.body, { childList: true, subtree: true }); // Wait for the page content to load before running the updateTitle function window.addEventListener('load', updateTitle); // Set an interval to check the title every second on Spotify pages only setInterval(() => { updateTitle(); // Update the title every X seconds (if needed) }, 2000); })();