Apple Music Enhanced

增强Apple Music页面功能,提供ID复制和地区切换

当前为 2025-04-21 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name Apple Music Enhanced
// @name:zh-CN Apple Music 增强
// @name:en Apple Music Enhanced
// @name:ja Apple Music 拡張
// @name:ko Apple Music 향상
// @name:zh-TW Apple Music 增強
// @namespace https://github.com/hu3rror/my-userscript
// @version 2.2.1
// @description 增强Apple Music页面功能,提供ID复制和地区切换
// @description:zh-CN 增强Apple Music页面功能,提供ID复制和地区切换
// @description:en Enhance Apple Music page functionality, providing ID copy and region switch
// @description:ja Apple Musicページの機能を強化し、IDコピーと地域切り替えを提供
// @description:ko Apple Music 페이지 기능을 향상시켜 ID 복사 및 지역 전환을 제공합니다.
// @description:zh-TW 增強Apple Music頁面功能,提供ID複製和地區切換
// @match https://music.apple.com/*
// @grant GM_setClipboard
// @grant GM_addStyle
// @license MIT
// @homepageURL   https://github.com/hu3rror/my-userscript
// @supportURL   https://github.com/hu3rror/my-userscript/issues
// ==/UserScript==

(function () {
    'use strict';

    // 定义可用地区
    const regions = [
        { name: '🇭🇰', code: 'hk', fullName: 'Hongkong' },
        { name: '🇯🇵', code: 'jp', fullName: 'Japan' },
        { name: '🇺🇸', code: 'us', fullName: 'US' },
        { name: '🇨🇳', code: 'cn', fullName: 'China' }
    ];

    // 添加样式
    GM_addStyle(`
        .region-switcher {
            background-color: #1c1c1e;
            border: 1px solid #3c3c3e;
            color: white;
            font-size: 14px;
            font-family: inherit;
            padding: 8px 16px;
            border-radius: 16px;
            cursor: pointer;
            display: flex;
            align-items: center;
            transition: background-color 0.3s;
            margin-right: 10px;
        }
        .region-switcher:hover {
            background-color: #2c2c2e;
        }
        .region-switcher:before {
            content: '🌍';
            margin-right: 5px;
        }
        .region-switcher:focus {
            outline: none;
            box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.3);
        }
        .region-switcher option {
            background-color: #1c1c1e;
            color: white;
            padding: 8px;
        }
        .custom-button {
            background-color: #1d1d1f;
            border: 1px solid #3c3c3e;
            color: #fff;
            font-size: 14px;
            font-weight: bold;
            padding: 8px 16px;
            border-radius: 16px;
            cursor: pointer;
            margin-right: 10px;
            transition: background-color 0.3s, transform 0.1s;
        }
        .custom-button:hover {
            background-color: #2c2c2e;
        }
        .custom-button:active {
            transform: scale(0.95);
        }
        .feedback-message {
            position: fixed;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 10px 20px;
            border-radius: 5px;
            z-index: 9999;
            transition: opacity 0.3s;
            opacity: 1;
        }
        #buttons-container {
            display: flex;
            align-items: center;
            margin-top: 10px;
            flex-wrap: wrap;
        }
    `);

    // 创建通用按钮
    function createButton(text, onClick, title) {
        const button = document.createElement('button');
        button.textContent = text;
        button.className = 'custom-button';
        button.addEventListener('click', onClick);
        if (title) button.title = title;
        return button;
    }

    // 显示反馈消息
    function showFeedback(message) {
        const existingFeedback = document.querySelector('.feedback-message');
        if (existingFeedback) {
            existingFeedback.remove();
        }

        const feedback = document.createElement('div');
        feedback.textContent = message;
        feedback.className = 'feedback-message';
        document.body.appendChild(feedback);

        setTimeout(() => {
            feedback.style.opacity = '0';
            setTimeout(() => feedback.remove(), 300);
        }, 2000);
    }

    // 获取专辑ID
    function getAlbumId(url) {
        const match = url.match(/\/album\/.*?\/(\d+)(?:\?i=\d+)?$/);
        return match ? match[1] : null;
    }

    // 添加按钮到页面
    function addButtons() {
        // 检查按钮容器是否已存在
        const existingContainer = document.querySelector('#buttons-container');
        if (existingContainer) return;

        // 查找插入点
        const previewButton = document.querySelector('button[data-testid="click-action"]');
        if (!previewButton) return;

        // 创建按钮容器
        const container = document.createElement('div');
        container.id = 'buttons-container';

        // 添加复制ID按钮
        const copyIdButton = createButton('复制ID', function () {
            const albumId = getAlbumId(window.location.href);
            if (albumId) {
                GM_setClipboard(albumId);
                showFeedback('ID已复制');
            } else {
                showFeedback('未找到ID');
            }
        }, '复制专辑ID');
        container.appendChild(copyIdButton);

        // 创建地区选择器
        const regionSwitcher = document.createElement('select');
        regionSwitcher.className = 'region-switcher';

        // 添加默认选项
        const defaultOption = document.createElement('option');
        defaultOption.textContent = '切换地区';
        defaultOption.value = '';
        defaultOption.disabled = true;
        defaultOption.selected = true;
        regionSwitcher.appendChild(defaultOption);

        // 添加地区选项
        regions.forEach(region => {
            const option = document.createElement('option');
            option.value = region.code;
            option.textContent = `${region.name} ${region.fullName}`;
            regionSwitcher.appendChild(option);
        });

        // 添加地区切换事件
        regionSwitcher.addEventListener('change', function() {
            if (this.value) {
                const currentUrl = window.location.href;
                const newUrl = currentUrl.replace(
                    /\/\/music\.apple\.com\/[a-z]{2}/,
                    `//music.apple.com/${this.value}`
                );
                window.location.href = newUrl;
            }
        });

        container.appendChild(regionSwitcher);

        // 添加区域复制按钮
        regions.forEach(region => {
            const regionCopyButton = createButton(region.name, function () {
                const currentUrl = window.location.href.split('?')[0];
                const newUrl = currentUrl.replace(
                    /\/\/music\.apple\.com\/[a-z]{2}/,
                    `//music.apple.com/${region.code}`
                );
                GM_setClipboard(newUrl);
                showFeedback(`${region.fullName} 链接已复制`);
            }, `复制 ${region.fullName} 链接`);
            container.appendChild(regionCopyButton);
        });

        // 将按钮容器添加到页面
        previewButton.parentNode.insertAdjacentElement('afterend', container);
    }

    // 持续检查并添加按钮
    function persistentlyAddButtons() {
        addButtons();
        setTimeout(persistentlyAddButtons, 1000);
    }

    // 初始化
    persistentlyAddButtons();

    // 监听URL变化
    let lastUrl = location.href;
    new MutationObserver(() => {
        const url = location.href;
        if (url !== lastUrl) {
            lastUrl = url;
            setTimeout(addButtons, 1000);
        }
    }).observe(document, { subtree: true, childList: true });
})();