You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从指定音乐流获取歌曲名?解决CORS及代码不更新问题

解决方案

1. 前端直接用fetch能否实现?

不行。这些音乐流服务器几乎都未配置CORS跨域允许头,浏览器的同源策略会直接阻止前端fetch请求,必须通过后端代理获取元数据后再返回给前端。

2. 后端歌曲切换后不更新的问题修复

你的代码能获取初始歌曲名,但歌曲切换时前端无法自动更新,原因有两个:一是前端只有刷新页面或重新请求接口才能拿到最新的name值;二是代码里require语句存在语法错误,'icecast-parser"'应改为'icecast-parser'。以下提供两种修复方案:

方案一:前端定时轮询获取最新歌曲名

修改后端代码,新增单独的歌曲名接口:

const { Parser } = require('icecast-parser');

let currentSong = '';
const radioStation = new Parser({ url: 'http://strm112.1.fm/dubstep_mobile_mp3' });
radioStation.on('metadata', (metadata) => {
  currentSong = metadata.get('StreamTitle') || '未知歌曲';
});

// 主页面接口
app.get("/", (req, res) => {
  res.render("index", { song: currentSong }); 
});

// 单独返回歌曲名的接口
app.get("/current-song", (req, res) => {
  res.json({ song: currentSong });
});

前端页面(index模板)添加定时请求逻辑:

<script>
function updateSong() {
  fetch('/current-song')
    .then(res => res.json())
    .then(data => {
      document.getElementById('current-song').textContent = data.song;
    });
}
// 页面加载时先获取一次,之后每5秒更新
updateSong();
setInterval(updateSong, 5000);
</script>

<div id="current-song"></div>

方案二:用WebSocket实时推送(更高效)

如果希望歌曲切换时立即更新,WebSocket是更优选择,步骤如下:

  1. 安装ws模块:npm install ws
  2. 修改后端代码:
const { Parser } = require('icecast-parser');
const WebSocket = require('ws');

let currentSong = '';
const radioStation = new Parser({ url: 'http://strm112.1.fm/dubstep_mobile_mp3' });
radioStation.on('metadata', (metadata) => {
  currentSong = metadata.get('StreamTitle') || '未知歌曲';
  // 将更新推送给所有连接的客户端
  wss.clients.forEach(client => {
    if (client.readyState === WebSocket.OPEN) {
      client.send(JSON.stringify({ song: currentSong }));
    }
  });
});

app.get("/", (req, res) => {
  res.render("index", { song: currentSong }); 
});

// 启动WebSocket服务
const wss = new WebSocket.Server({ port: 8080 });

前端页面添加WebSocket监听:

<script>
const ws = new WebSocket('ws://localhost:8080');
ws.onmessage = function(event) {
  const data = JSON.parse(event.data);
  document.getElementById('current-song').textContent = data.song;
};
// 渲染初始歌曲名
document.getElementById('current-song').textContent = '<%= song %>';
</script>

<div id="current-song"></div>

3. 支持多个音乐流链接

如果需要处理你列出的所有5个电台,可以修改后端代码,按ID区分不同电台:

const { Parser } = require('icecast-parser');

// 存储每个电台的当前歌曲
const stationSongs = {};
const stations = [
  { id: 'zeno1', url: 'https://stream-27.zeno.fm/0r0xa792kwzuv?zs=of2rNL4EQaKONauS-rWZdQ' },
  { id: 'zeno2', url: 'https://stream-61.zeno.fm/0r0xa792kwzuv?zs=SyKyJJtSQvSmEQObk_ymow' },
  { id: 'dubstep', url: 'http://strm112.1.fm/dubstep_mobile_mp3' },
  { id: 'generations', url: 'http://gene-rgton.ice.infomaniak.ch/generations-rgton.mp3' },
  { id: 'iloveradio', url: 'https://streams.ilovemusic.de/iloveradio21.mp3' }
];

// 初始化每个电台的元数据监听
stations.forEach(station => {
  stationSongs[station.id] = '加载中...';
  const parser = new Parser({ url: station.url });
  parser.on('metadata', (metadata) => {
    stationSongs[station.id] = metadata.get('StreamTitle') || '未知歌曲';
  });
});

// 根据电台ID返回对应歌曲名
app.get("/current-song/:stationId", (req, res) => {
  const { stationId } = req.params;
  res.json({ song: stationSongs[stationId] || '无效电台ID' });
});

前端可通过请求/current-song/dubstep这类接口获取对应电台的歌曲名。

内容的提问来源于stack exchange,提问作者Vεκρός

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 00:47:32