VUE---爬虫播放器(四)---功能实现--vue3

如果我们找到别的播放器的接口,就可以实现一个播放器,这个接口获取不到就换接口,就是换源

编写api.js文件

不是自己的接口所以没有设置axios请求拦截器

searchMusic搜索音乐

getKey 获取vkey以便于获取音频

getMp获取音乐 可以直接通过拼接vkey来实现 见 寻找接口

getLyric 获取歌词

axiosFun文件(可以忽略) api.js中的axios直接为import {axios} from ‘axios’
在这里插入图片描述

import {axios} from './axiosFun'

export const searchMusic = (p, w) => {
  return axios.get(`api/client_search_cp?p=${p}&n=10&w=${w}`);
};

export const getKey = (id)=>{
  return axios.get(
    `/aki/musicu.fcg?data={"req":{"module":"CDN.SrfCdnDispatchServer","method":"GetCdnDispatch","param":{"guid":"0","calltype":0,"userip":""}},"req_0":{"module":"vkey.GetVkeyServer","method":"CgiGetVkey","param":{"guid":"0","songmid":["${id}"],"songtype":[0],"uin":"0","loginflag":1,"platform":"20"}},"comm":{"uin":0,"format":"json","ct":24,"cv":0}}`
  );
}

export const getMp = (url)=>{
  return axios.get(`/awe/${url}`)
}

export const getLyric = (id)=>{
  return axios.get(`/aqr/fcg_query_lyric_new.fcg?songmid=${id}`)
}


处理获取的数据

接口说明和参数请见 接口获取

存储歌曲信息

我们需要的是下面图中list和totalnum中的数据
当然
在这里插入图片描述在这里插入图片描述

遍历list对每个歌曲信息进行处理 我们只需要
在这里插入图片描述

albumname歌曲名字
albummid用来获取图像
media_mid用来获取歌曲vkey和歌词
singer歌手
用一个新的数组来存储它就行

 let music = JSON.parse(res.data.slice(9, -1)).data.song;
        let musics = music.list;
        this.totalNum = music.totalnum;

解释参数
music对应的是返回的数据中的song
musics代表list中的内容
totalNum就是歌曲总量便于使用vant3的列表懒加载

totalNum是会变化的 一般返回的是150/600但其实数量未必是这个

令命名一个数组来拼接

singers里面未必有一个可以通过他的长度来判断或者用剩余计算符 …来赋值

musics.forEach(item => {
          let singers = "";
          singers = item.singer[0].name;
          let data = [
            {
              name: item.albumname,
              id: item.media_mid,
              albumid: item.albummid,
              singer: singers,
              love: false
            }
          ];
          datas = datas.concat(data);
        });

这样我们就得到了一组数据 默认love为false

获取歌曲vkey

我们需要的数据是
sip和midurlinfo中的purl

sip+purl就是歌曲资源地址

在这里插入图片描述在这里插入图片描述

sip中的两个可以实现切换播放源当sip[0]不可以就切换sip[1]试试看

获取歌曲

我们可以用拼接的形式获
然后生成一个音频对象
在自己的播放器中操作

new Audio(`播放地址`)

处理歌词

歌词接口返回的数据是这样的
在这里插入图片描述
base64加密的数据
base64解码后的数据是歌词加时间戳
在这里插入图片描述
歌词解码

decodeURIComponent(
          escape(atob(JSON.parse(res.data.slice(18, -1)).lyric))
        );

我们把时间戳和歌词拆分开来做处理

		let docs = [];
        let dtc = [];
        str = str.split("\n");
        str.forEach(item => {
          let strs = item.split("]");
          if (strs[1] !== "") {
            let s = strs[0];
            let min = s.slice(1, 6);
            let data = [{ time: min, doc: strs[1] }];
            docs = docs.concat(data);
          }
        });

时间戳可以用来判断歌词是否应该设置当前歌句变大
也可以通过计算两句歌词之间的时间差来设置字的颜色从左到右的变化时间
如果不设置高亮和字体变化也可以歌曲放到哪里就显示哪句歌词

给歌词所在的div设置一个样式
1.jpg是背景图

{
  background-image: url("/1.jpg");
  position: absolute;
  top: 0;
  width: 100%;
  height: 740px;
  overflow: scroll;
  color: white;
}

isP是当前播放时间定时器获取

<div class="transfr" id="gunDoc">
        <p
          v-for="item in docs"
          :key="item"
          style="color: white"
          @click="chanto(item)"
        >
          <span :class="{ gop: item.time === isP }">{
   
   { item.doc }}</span>
        </p>
</div>

动态绑定class 比如高亮变大

处理时间个滚动
因为一开始歌曲歌词不需要滚动 所以我设置300来测试效果
可以通过获取屏幕的高度来设置

let vm = this;
.../处理播放和暂停,暂停清楚定时器  clearInterval(this.timer);
  this.timer = setInterval(function() {
          if (!vm.mp.duration) {
            vm.value = 0;
          } else {
            vm.value = ((vm.mp.currentTime / vm.mp.duration) * 100).toFixed(1);

            if (vm.mp.currentTime !== vm.mp.duration) {
              let doc = document.getElementById("gunDoc");
              let s1 = parseInt(vm.mp.currentTime);
              let min = "0" + parseInt(s1 / 60).toString();
              let m = s1 % 60;
              if (m < 10) {
                m = "0" + m.toString();
              } else {
                m = m.toString();
              }
              let time = min + ":" + m;
              s1 = s1.toString();
              console.log(s1);
              if (docs.search(time) !== -1) {
                console.log("卧槽");
                vm.tansnow += 18;
                console.log(vm.transforms);
                vm.isP = time;
                if (vm.tansnow > 300) {
                  vm.transforms += 18;
                  vm.$nextTick(() => {
                    doc.scrollTop = vm.transforms;
                  });
                }
              }
            } else {
              clearInterval(this.timer);
            }
            // console.log(vm.value);
          }
        }, 500);

使用$nextTic是为了立即刷新DOM,让歌词滚动效果显示出来

获取图像

GET
接口地址:https://y.gtimg.cn/music/photo_new/T002R300x300M000${id}_1.jpg
id为我们之前说的albummid

喜欢或不喜欢歌曲

将歌曲列表中的歌曲添加至喜欢列表存至本地缓存

<van-cell
              v-for="(item, index) in loveLists"
              :key="item"
              :title="item.name"
              size="large"
              :label="item.singer"
              style="text-align: left"
              @click="ready(item)"
            >
              <template #right-icon>
                <!--                <a :href="urls" download="mp3"><van-icon name="down" /></a>-->
                <van-icon
                  :name="isLove(item.love)"
                  color="red"
                  size="32"
                  @click="unlikes(item, index)"
                />
                <!--                <van-icon name="pause-circle-o" />-->
              </template>
            </van-cell>


likes(item, index) {
      if (!this.musicList[index].love) {
        let loveList = localStorage.getItem("loveList");
        if (loveList === null) {
          let loveL = [];
          loveL.unshift(item);
          localStorage.setItem("loveList", JSON.stringify(loveL));
        } else {
          loveList = JSON.parse(loveList);
          loveList.unshift(item);
          localStorage.setItem("loveList", JSON.stringify(loveList));
        }
        this.musicList[index].love = !this.musicList[index].love;
      } else {
        let loveList = localStorage.getItem("loveList");
        loveList = JSON.parse(loveList);
        loveList.forEach((items, indexs) => {
          if (items.name === item.name && items.singer === item.singer) {
            loveList.splice(indexs, 1);
          }
        });
        if (!loveList[0]) {
          this.isEmptys = true;
        }
        localStorage.setItem("loveList", JSON.stringify(loveList));
        this.musicList[index].love = !this.musicList[index].love;
      }
    },

根据这些加上反向代理你就可以做一个爬虫播放器,但是 请勿商用

本文只是讲如何寻找接口,滥用别人接口导致的后果自行负责。







  大家好,我是代码哈士奇,是一名软件学院网络工程的学生,因为我是“狗”,狗走千里吃肉。想把大学期间学的东西和大家分享,和大家一起进步。但由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教!暂时只在csdn这一个平台进行更新,博客主页:https://blog.csdn.net/qq_42027681

未经本人允许,禁止转载

在这里插入图片描述


后续会推出

前端:vue入门 vue开发小程序 等
后端: java入门 springboot入门等
服务器:mysql入门 服务器简单指令 云服务器运行项目
python:推荐不温卜火 一定要看哦
一些插件的使用等

大学之道亦在自身,努力学习,热血青春
如果对编程感兴趣可以加入我们的qq群一起交流:974178910
在这里插入图片描述

有问题可以下方留言,看到了会回复哦

猜你喜欢

转载自blog.csdn.net/qq_42027681/article/details/110979482