【小程序】实现一个定制的音乐播放器

【小程序】实现一个定制的音乐播放器_第1张图片

应用地址:https://spacexcode.com/player

介绍

这是为自己制作的一个在线 Web 版的音乐播放器。众所周知,现在市面上的所有的音乐平台都是会员制。而免费的资源却分散在网络上的各个角落,为此,我收集了自己 喜欢的音乐,放到自己的服务器上,并制作了这样一个专属歌单的简单的音乐播放器。

实现讲解

该播放器虽然简单,但也是五脏俱全,该有的功能一个都没少。比如常见的音乐播放器,我们能想到的功能有:

  • 暂停/开始播放按键

  • 调节播放进度的进度条

  • 调节声音大小的按键

  • 切换下一首/上一首按键

  • 查看歌单的界面

界面

如果不考虑界面, Web 端的音频播放有现成的标签 audio 支持

8e382cf0d9905149be535d735f71b5da.png

这是浏览器渲染的默认样式,各个浏览器可能会有差异。我们要实现一个音乐播放器,当然要所有端的样式统一。这个时候,我们就移除 controls 属性,让 实际的播放组件在页面上什么都不显示。然后我们自己去实现上面的所有控件。

由于这个站点引入的是 Material UI,为了统一视觉,就使用里面现成的组件去实现。

function player () {
  const [paused, setPaused] = React.useState(true);

  return (
    
      
        
           img': {
              width: '100%',
            }
          }}>
            
          
                                                                                       林俊杰               那女孩对我说               心很空 天很大 云很重 我很孤单                                                  00:30
          -04:00
                                                                                                                                                                                                        
       ) } 【小程序】实现一个定制的音乐播放器_第2张图片

至此以上代码,初步实现了基本的播放器界面,然后我们需要对每个功能控件添加事件实现它应该有的功能。

播放按钮

控制播放器的播放,我们可以通过 audio 提供的 play()pause() 接口,首先我们使用 useRef 获取音频组件的实例,然后通过判断 当前的播放状态,调用播放和暂停接口。

function Player () {
  const audioPlayer = useRef();
  const [paused, setPaused] = useState(true);
  const onPlayOrPause = () => {
    paused ? audioPlayer.current.play() : audioPlayer.current.pause();
    setPaused(!paused)
  }
}

下面所有使用的变量 audioPlayer 代表获取的 播放器实例

调节进度

Slider 组件上绑定 onChange 事件,此时 Slider 组件中的最大值即为该音频资源的最大时长。回调中拿到设置的进度值后赋值给 currentTime 属性。

const [position, setPosition] = useState(0); // 表示当前的播放进度值

const onChangeProgress = (val) => {
  setPosition(val);
  audioPlayer.current.currentTime = val;
}

这个音频的资源时长,可以通过监听资源加载完成事件,通过 duration 属性获取。它单位为**毫秒(ms)**。

audioPlayer.current.addEventListener('loadeddata', () => {
  setDuration(audioPlayer.current?.duration)
});

调节音量

音量的调节和进度同样使用的是 Slider 组件,不过它的最大值为 1,步长为 0.01

改变音量时,将获取到的音量值赋给 audioPlayer 实例的 volumn 属性。

const onChangeVolume = (val) => {
  setVolume(val);
  audioPlayer.current.volume = val;
};

切换歌单

切换上一首/下一首,无非就是改变当前播放的音频资源。该音频资源对应到资源列表的索引值,我们通过控制索引值去列表中获取不同的音乐素材。

这里要考虑边界值的情况,当切换的时候碰到最大值和最小值,如果允许循环,那么在索引值等于数组长度时,将它的值重置为 0

// 上一首
const onPreview = () => {
  if (currentIndex > 0) {
    changeCurrentIndex(currentIndex - 1); 
  }
}

// 下一首
const onNext = () => {
  if (currentIndex < songList.length - 1) {
    changeCurrentIndex(currentIndex + 1);
  } else {
    changeCurrentIndex(0);
  }
}

查看歌单

除了所有的功能按钮,右上角还有一个查看歌单的按钮,点击从底部弹出一个 drawer 抽屉组件。里面列出了一个收藏的音乐列表。

function MusicQueue() {
  const songList = [
    {
      artists: '林俊杰',
      name: '那女孩对我说',
      avatar: 'https://spacexcode.oss-cn-hangzhou.aliyuncs.com/1697270523238-8b4b11a5-b5a3-4ac3-b6bd-1e264f526c76.png',
      link: 'https://spacexcode.oss-cn-hangzhou.aliyuncs.com/mp3/那女孩对我说.mp3',
      lyric: '心很空 天很大 云很重 我很孤单'
    },
    {
      artists: '张靓颖',
      name: '终于等到你',
      avatar: 'https://spacexcode.oss-cn-hangzhou.aliyuncs.com/1697503257045-7a262b7d-0df0-4005-a69c-2a645ac24c27.png',
      link: 'https://spacexcode.oss-cn-hangzhou.aliyuncs.com/mp3/终于等到你-张靓颖.mp3',
      lyric: '到了某个年纪你就会知道 一个人的日子真的难熬'
    },
    {
      artists: '张靓颖',
      name: '饿狼传说',
      avatar: 'https://spacexcode.oss-cn-hangzhou.aliyuncs.com/1697503257045-7a262b7d-0df0-4005-a69c-2a645ac24c27.png',
      link: 'https://spacexcode.oss-cn-hangzhou.aliyuncs.com/mp3/饿狼传说-张靓颖.mp3',
      lyric: '她熄掉晚灯 幽幽掩两肩 交织了火花 拘禁在沉淀'
    }
  ];
  return (
    
      
        {songList.map((item, index) => (
          
            
              
                
              
              
                  
                    {item.name}
                  
                  {' -- ' + item.artists}
                
              } />
            
          
        ))}
      
    
  );
}
【小程序】实现一个定制的音乐播放器_第3张图片

至此我们已经实现了界面上所有的控制按钮的功能。最后需要完善下一些边界和初始情况的处理。

当音频在播放的时候,进度条需要随着当前播放时间变化而变化。这里采用定时器,每隔一秒获取播放资源的当前播放时间点,同步给 Slider 组件的 value 属性来定位。

const [timer, setTimer] = useState(null);

audioPlayer.current.addEventListener('play', () => {
  if (timer) {
    clearInterval(timer);
  }
  setTimer(setInterval(() => {
    setPosition(audioPlayer.current?.currentTime)
  }, 1000));
});
audioPlayer.current.addEventListener('pause', () => {
  if (timer) {
    clearInterval(timer);
  }
});

还有歌词的显示,下一步计划加上~

总结

实现一个定制的音乐播放器不复杂,控制功能的实现都有现成的接口:

  • 播放 play()

  • 暂停 pause()

  • 播放进度通过 currentTime 获取

  • 音量控制通过 volumn 的值控制

  • 音频的自动播放通过 autoplay 属性

  • 控制音频播放的时候为静音 muted

  • 当前音频资源循环播放通过属性 loop

我们需要考虑的是如何优化界面,毕竟一款颜值高的播放器和动听的音乐才能给我们带来内心的愉悦。

- END -

你可能感兴趣的:(小程序)