QQ Music MediaSession Helper

Dock metadata to MediaSession API for y.qq.com (Chrome 73+)

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(Tôi đã có Trình quản lý tập lệnh người dùng, hãy cài đặt nó!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         QQ Music MediaSession Helper
// @namespace    https://github.com/nondanee
// @version      0.2.4
// @description  Dock metadata to MediaSession API for y.qq.com (Chrome 73+)
// @author       nondanee
// @match        *://y.qq.com/*
// @grant        none
// @license      ISC
// ==/UserScript==

/* jshint esversion: 6 */

(() => {
    if (!('mediaSession' in navigator)) return

    const updateMetadata = () => {
        try {
            const { src } = document.querySelector('.song_info__pic')
            const { href } = document.querySelector('.player_music__info a:first-of-type')
            const mid = (/songDetail\/(\w+)/.exec(href) || [])[1]

            const tracks = JSON.parse(localStorage.getItem('playSongData')).value.songList
            const song = tracks.find(item => item.mid === mid)

            if (!song) return;

            const meta = {
                title: song.name,
                artist: song.singer.map(artist => artist.name).join(' / '),
                album: song.album.name,
                artwork: [{ src, sizes: '300x300', type: 'image/jpeg' }]
            }

            console.log('updateMetadata', meta)
            navigator.mediaSession.metadata = new MediaMetadata(meta)
        } catch (_) {}
    }

    if (!document.querySelector('.player__ft')) return

    navigator.mediaSession.setActionHandler('previoustrack', () => {
        const button = document.querySelector('.player__ft .btn_big_prev')
        if (button) button.click()
    })

    navigator.mediaSession.setActionHandler('nexttrack', () => {
        const button = document.querySelector('.player__ft .btn_big_next')
        if (button) button.click()
    })

    const bodyObserver = new MutationObserver(() => {
        if (bodyObserver.disconnected) return
        const info = document.querySelector('.player_music__info')
        if (!info) return
        bodyObserver.disconnect()
        bodyObserver.disconnected = true
        updateMetadata()
        new MutationObserver(updateMetadata).observe(info, { childList: true, attributes: true, subtree: true })
    })

    bodyObserver.observe(document.body, { childList: true, attributes: true, subtree: true })
})()