diff --git a/extension/content.js b/extension/content.js index 852dd82..269a380 100644 --- a/extension/content.js +++ b/extension/content.js @@ -236,6 +236,8 @@ const current = video.currentTime; if (!Number.isFinite(current)) return; + const mediaTitle = (navigator.mediaSession && navigator.mediaSession.metadata) ? navigator.mediaSession.metadata.title : null; + const eventState = action === EVENTS.PLAY ? 'playing' : (action === EVENTS.PAUSE ? 'paused' : (action === EVENTS.SEEK ? 'seek' : null)); if (eventState && lastTargetState === eventState) { @@ -249,6 +251,7 @@ payload: { currentTime: current, targetTime: current, + mediaTitle: mediaTitle, timestamp: Date.now() } }); @@ -307,11 +310,13 @@ const heartbeatInterval = setInterval(() => { const video = findVideo(); if (video) { + const mediaTitle = (navigator.mediaSession && navigator.mediaSession.metadata) ? navigator.mediaSession.metadata.title : null; chrome.runtime.sendMessage({ type: 'HEARTBEAT', payload: { playbackState: video.paused ? 'paused' : 'playing', - currentTime: video.currentTime + currentTime: video.currentTime, + mediaTitle: mediaTitle } }).catch(err => { if (err.message.includes('Extension context invalidated')) { diff --git a/extension/popup.js b/extension/popup.js index 0d649ad..8c4df0b 100644 --- a/extension/popup.js +++ b/extension/popup.js @@ -241,10 +241,17 @@ function updatePeerList(peers) { peerItem.appendChild(header); + if (p.mediaTitle) { + const mediaDiv = document.createElement('div'); + mediaDiv.style.cssText = 'font-size:11px; color:var(--star); font-weight: 600; margin-top: 2px;'; + mediaDiv.textContent = `🎬 ${p.mediaTitle}`; + peerItem.appendChild(mediaDiv); + } + if (pTabTitle) { const titleDiv = document.createElement('div'); - titleDiv.style.cssText = 'font-size:10px; color:var(--text-muted);'; - titleDiv.textContent = pTabTitle; + titleDiv.style.cssText = 'font-size:10px; color:var(--text-muted); opacity: 0.8;'; + titleDiv.textContent = p.mediaTitle ? `via ${pTabTitle}` : pTabTitle; peerItem.appendChild(titleDiv); } diff --git a/server/index.js b/server/index.js index c87cee0..fe1dee8 100644 --- a/server/index.js +++ b/server/index.js @@ -155,7 +155,7 @@ io.on('connection', (socket) => { return; } if (!payload || typeof payload.roomId !== 'string') return; - const { roomId, password, peerId, username, tabTitle, protocolVersion } = payload; + const { roomId, password, peerId, username, tabTitle, mediaTitle, protocolVersion } = payload; try { // Protocol check if (protocolVersion !== '1.0.0') { @@ -244,12 +244,13 @@ io.on('connection', (socket) => { peerId, username: username || null, tabTitle: tabTitle || null, + mediaTitle: mediaTitle || null, lastSeen: Date.now() }); socketToRoom.set(socket.id, { roomId, peerId }); peerToSocket.set(peerId, socket.id); - socket.to(roomId).emit(EVENTS.PEER_STATUS, { peerId, username: username || null, tabTitle: tabTitle || null, status: 'joined' }); + socket.to(roomId).emit(EVENTS.PEER_STATUS, { peerId, username: username || null, tabTitle: tabTitle || null, mediaTitle: mediaTitle || null, status: 'joined' }); socket.emit(EVENTS.ROOM_DATA, { roomId, peers: Array.from(room.peers).map(sid => room.peerData.get(sid)) @@ -288,8 +289,9 @@ io.on('connection', (socket) => { const existing = room.peerData.get(socket.id) || { peerId: mapping.peerId }; room.peerData.set(socket.id, { ...existing, - username: data.username || existing.username, - tabTitle: data.tabTitle || existing.tabTitle, + username: data.username !== undefined ? data.username : existing.username, + tabTitle: data.tabTitle !== undefined ? data.tabTitle : existing.tabTitle, + mediaTitle: data.mediaTitle !== undefined ? data.mediaTitle : existing.mediaTitle, lastSeen: Date.now() });