目的功能:

  1. axios 请求获取歌曲的 url 以及 封面照片
  2. 切换歌曲
  3. 歌单的展示

演示:



网易云音乐接口 github地址

https://github.com/Binaryify/NeteaseCloudMusicApi

安装

git clone git@github.com:Binaryify/NeteaseCloudMusicApi.git

在他的目录下

npm install

运行

node app.js

运行后我么可以在

http://localhost:3000/

打开文档

借此我们可以请求歌单和歌曲的 url 地址 , 歌曲照片地址等等,详细功能可以自己查看

以上全部借助别人的 api 接口

这里重点强调一下 获取歌曲 url 的 api

需要传入歌曲的 id 返回 url 地址

template

<template><div class="music-container" ref="music-container"><p v-show="isShowList">歌单: {{ belong }}</p><div class="music-audio"><audio ref="audio" autoplay="autoplay" :src="songsList[currentIndex].url" loop="loop"></audio><img :src="songsList[currentIndex].picUrl" alt="" style="width: 60px; height: 60px;border-radius: 50%;" ref="audio-pic" @click="playMusic()"></div><ul><li @click="showList"><span v-if="isShowList">关闭播放列表</span><span v-else>打开</span></li><li v-for="(item, index) in songsList" @click="playMusic(index)" v-show="isShowList"><span>{{ item.name }}</span> <span>{{ item.ar + "" }}</span></li></ul></div>
</template>

这里需要修改为你自己的信息

<script>
import axios from "axios"
export default {name: 'App',components: {},data: function () {return {// 歌曲名称 歌曲url 照片url 作者名称songsList: [{name: '未知', url: '', picUrl: '', ar: ''}],currentIndex: 0,belong: '',musicTimer: null,musicTime: 0,isShowList: true}},methods: {//showList:function () {this.isShowList = !this.isShowListif (!this.isShowList) {this.$refs["music-container"].style.width = "90px"this.$refs["music-container"].style.height = "120px"this.$refs["music-container"].style.transition = "1s"} else {this.$refs["music-container"].style.width = "270px"this.$refs["music-container"].style.height = ""}},// 控制音乐播放playMusic: function (index) {if (index === undefined) {} else if (this.currentIndex !== index) {this.currentIndex = indexthis.musicTime = 0return true;}if (this.$refs.audio.paused) {this.$refs.audio.play()this.isPlaying = !this.isPlayingthis.musicTimer = setInterval(() => {this.musicTime += 1this.$refs["audio-pic"].style.transform = "rotate(" + this.musicTime + "deg)";},100)return true;}else  {this.$refs.audio.pause()clearInterval(this.musicTimer)this.$refs["audio-pic"].style.transitionDuration = this.musicTime;}},/*** 音乐,网络请求* */// 获取用户的 idgetUserId:function () {// 网易云接口axios.get('http://localhost:3000/login/cellphone?phone=修改为你的电话&password=修改为你的密码').then(res => {this.getList(res.data.account.id)})},// 获取用户的歌单getList:function (id) {axios.get('http://localhost:3000/user/playlist', {params: {uid: id}}).then(res => {// 选择要选择的歌单this.belong = res.data.playlist[1].namethis.getSongsId(res.data.playlist[1].id)})},// 获取歌单中 歌的id, 名字, 照片路径// 一次最多请求十首歌曲getSongsId:function (id) {axios.get('http://localhost:3000/playlist/track/all', {params: {id: id,limit: 10}}).then((res) => {// console.log(res.data.songs)// console.log(res.data.songs[0].name)// console.log(res.data.songs[0].id)// console.log(res.data.songs[0].al.picUrl)this.getSongs(res.data.songs)})},// 获取音乐getSongs:function (res) {for (let i = 0; i < res.length; i++) {// console.log(res[i].name)// console.log(res[i].id)// console.log(res[i].al.picUrl)this.getSong(res[i])}console.log(this.songsList)},getSong:function(items) {axios.get('http://localhost:3000/song/url', {params: {id: items.id}}).then(res => {console.log(res.data.data[0].url)if (this.songsList[0].name === '' || this.songsList[0].name === '未知') {this.songsList[0].name = items.namethis.songsList[0].url = res.data.data[0].urlthis.songsList[0].picUrl = items.al.picUrlthis.songsList[0].ar = items.ar.map(it => {return it.name})} else {this.songsList.push({name: items.name,url: res.data.data[0].url,picUrl: items.al.picUrl,ar: items.ar.map(it => {return it.name})})}})}},mounted() {// 获取音乐this.getUserId()}
}
</script>

样式的话,自己玩去

<style lang="less" scoped>
* {padding: 0;margin: 0;box-sizing: border-box;
}
.music-container {text-align: center;color: #bbbbbb;width: 270px;background-color: transparent;border: 1px solid black;border-radius: 20px;
}.music-audio {width: 100%;display: flex;& > img {margin: 10px;}& > span {margin: auto;}
}button {width: 20px;height: 20px;border-radius: 50%;outline: none;background-color: transparent;border: none;color: #bbbbbb;
}ul {width: 100%;list-style: none;display: flex;flex-direction: column;border-top: 1px solid black;font-size: 8px;color: #bbbbbb;li {padding: 10px 0;border-bottom: 1px solid black;display: flex;justify-content: space-evenly;align-items: center;span {width: 40%;text-align: center;overflow: hidden;white-space: nowrap;text-overflow-ellipsis: ellipsis;}}& > li:last-child {border-bottom: none;}& > li:first-child {border-bottom: none;}
}

目录结构


vue.config.js

// vue.config.js
const path =  require('path');
const IS_PROD = ['production', 'prod'].includes(process.env.NODE_ENV);
const resolve = (dir) => path.join(__dirname, dir);
module.exports = {chainWebpack: config => {config.resolve.symlinks(true); // 修复热更新失效// 如果使用多页面打包,使用vue inspect --plugins查看html是否在结果数组中config.plugin("html").tap(args => {// 修复 Lazy loading routes Errorargs[0].chunksSortMode = "none";return args;});config.resolve.alias // 添加别名.set('@', resolve('src')).set('@assets', resolve('src/assets')).set('@components', resolve('src/components')).set('@views', resolve('src/views')).set('@store', resolve('src/store'));},devServer: {overlay: { // 让浏览器 overlay 同时显示警告和错误warnings: true,errors: true},host: "localhost",port: 8081, // 端口号https: false, // https:{type:Boolean}open: true, //配置自动启动浏览器hotOnly: true, // 热更新// proxy: 'http://localhost:8080'   // 配置跨域处理,只有一个代理proxy: { //配置多个跨域"/api": {target: "http://172.11.11.11:3000",changeOrigin: true,// ws: true,//websocket支持secure: false,pathRewrite: {"^/api": "/"}}}}
}

bable.config,js

module.exports = module.exports = {presets: [ '@vue/cli-plugin-babel/preset' ],"plugins": [["component",{"libraryName": "element-ui","styleLibraryName": "theme-chalk"}]]
}

App.vue

<template><div id="app"><music-container></music-container></div>
</template><script>
import MusicContainer from "./components/MusicContainer";
export default {name: 'App',components: {MusicContainer}
}
</script><style lang="less">
* {padding: 0;margin: 0;box-sizing: border-box
}
body {height: 100vh;width: 100vw;background-image: url("~@/assets/b.jpg");background-repeat: no-repeat;background-size: cover;background-position: center;
}
</style>

and 附加视频播放器的思路

<!DOCTYPE html>
<html>
<head lang="en"><meta charset="UTF-8"><title></title><!-- 引入字体图标的文件--><link rel="stylesheet" href="css/font-awesome.min.css"/><style>*{margin: 0;padding: 0;}/*多媒体标题*/figcaption{text-align: center;line-height: 150px;font-family: "Microsoft Yahei";font-size:24px;}/* 播放器*/.palyer{width: 720px;height: 360px;margin:10px auto;border: 1px solid #000;background: url(images/loading.gif) center no-repeat #000;background-size:auto 100%;position: relative;border-radius: 20px;}.palyer video{height:100%;display: block;margin:0 auto;/*display: none;*/}/* 控制条*/.controls{width: 700px;height:40px;background-color: rgba(255, 255, 0, 0.3);position: absolute;bottom:10px;left:10px;border-radius: 10px;}/*开关*/.switch{position: absolute;width: 20px;height: 20px;left:10px;top:10px;text-align: center;line-height: 20px;color:yellow;}/*进度条*/.progress{width: 432px;height: 10px;position: absolute;background-color: rgba(255,255,255,0.4);left:40px;top:15px;border-radius: 4px;overflow: hidden;}/* 当前进度*/.curr-progress{width: 50%;height: 10px;background-color: #fff;}/* 时间模块*/.time{width: 120px;height: 20px;text-align: center;line-height: 20px;color:#fff;position: absolute;left:510px;top:10px;font-size:12px;}/*全屏*/.extend{position: absolute;width: 20px;height: 20px;right:20px;top:10px;text-align: center;line-height: 20px;color:yellow;}</style>
</head>
<body><!-- 多媒体--><figure><!--  多媒体标题--><figcaption>视频案例</figcaption><div class="palyer"><video src="video/fun.mp4"></video><!-- 控制条--><div class="controls"><!-- 播放暂停--><a href="#" class="switch  icon-play"></a><div class="progress"><!-- 当前进度--><div class="curr-progress"></div></div><!-- 时间--><div class="time"><span class="curr-time">00:00:00</span>/<span class="total-time">00:00:00</span></div><!-- 全屏--><a href="#" class="extend  icon-resize-full"></a></div></div></figure><script>// 思路:/** 1、点击按钮 实现播放暂停并且切换图标* 2、算出视频的总时显示出出来* 3、当视频播放的时候,进度条同步,当前时间同步* 4、点击实现全屏*///        获取需要的标签var  video=document.querySelector('video');
//          播放按钮var  playBtn=document.querySelector('.switch');
//          当前进度条var  currProgress=document.querySelector('.curr-progress');
//          当前时间var  currTime=document.querySelector('.curr-time');
//          总时间var  totalTime=document.querySelector('.total-time');
//          全屏var extend=document.querySelector('.extend');var tTime=0;//         1、点击按钮 实现播放暂停并且切换图标playBtn.onclick=function(){//               如果视频播放 就暂停,如果暂停 就播放if(video.paused){//                   播放video.play();//切换图标this.classList.remove('icon-play');this.classList.add('icon-pause');}else{//                   暂停video.pause();
//                   切换图标this.classList.remove('icon-pause');this.classList.add('icon-play');}}//        2、算出视频的总时显示出出来
//        当时加载完成后的事件,视频能播放的时候video.oncanplay=function(){//             获取视频总时长tTime=video.duration;console.log(tTime);//          将总秒数 转换成 时分秒的格式:00:00:00
//            小时var h=Math.floor(tTime/3600);
//            分钟var m=Math.floor(tTime%3600/60);
//            秒var s=Math.floor(tTime%60);//            console.log(h);
//            console.log(m);
//            console.log(s);//            把数据格式转成 00:00:00h=h>=10?h:"0"+h;m=m>=10?m:"0"+m;s=s>=10?s:"0"+s;console.log(h);console.log(m);console.log(s);
//            显示出来totalTime.innerHTML=h+":"+m+":"+s;}
//   * 3、当视频播放的时候,进度条同步,当前时间同步
//         当时当前时间更新的时候触发video.ontimeupdate=function(){//            获取视频当前播放的时间
//           console.log(video.currentTime);
//            当前播放时间var cTime=video.currentTime;
//           把格式转成00:00:00var h=Math.floor(cTime/3600);
//            分钟var m=Math.floor(cTime%3600/60);
//            秒var s=Math.floor(cTime%60);//            把数据格式转成 00:00:00h=h>=10?h:"0"+h;m=m>=10?m:"0"+m;s=s>=10?s:"0"+s;//            显示出当前时间currTime.innerHTML=h+":"+m+":"+s;//            改变进度条的宽度: 当前时间/总时间var value=cTime/tTime;currProgress.style.width=value*100+"%";}//        全屏extend.onclick=function(){//            全屏的h5代码video.webkitRequestFullScreen();}</script>
</body>
</html>

处理兼容性问题

为了做到多浏览器支持,可以采取以下兼容性写法:

<!--推荐的兼容写法:-->
<audio controls loop><source src="music/yinyue.mp3"/><source src="music/yinyue.ogg"/><source src="music/yinyue.wav"/>抱歉,你的浏览器暂不支持此音频格式
</audio>

代码解释:如果识别不出音频格式,就弹出那句“抱歉”。

补充视频兼容问题

HTML5通过<video>标签来解决视频播放的问题。

使用举例:

 <video src="video/movie.mp4" controls autoplay></video>

我们可以通过附加属性,来更友好地控制视频的播放,如:

  • autoplay 自动播放。写成autoplay 或者 autoplay = "",都可以。

  • controls 控制条。(建议把这个选项写上,不然都看不到控件在哪里)

  • loop 循环播放。

  • preload 预加载 同时设置 autoplay 时,此属性将失效。

  • width:设置播放窗口宽度。

  • height:设置播放窗口的高度。

由于版权等原因,不同的浏览器可支持播放的格式是不一样的:

兼容性写法:

    <!--<video src="video/movie.mp4" controls  autoplay ></video>--><!--  行内块 display:inline-block --><video controls autoplay><source src="video/movie.mp4"/><source src="video/movie.ogg"/><source src="video/movie.webm"/>抱歉,不支持此视频</video>

音乐 组件 (音频, 视频)相关推荐

  1. 音频视频解决方案:GStreamer/ffmpeg/ffdshow/directshow/vfw

    音频视频编程相关:GStreamer/ffmpeg/directshow/vfw linux和window下几种流行的音频视频编程框架作一个总结,防止自己迷惘,免于晕头转向. 一.GStreamer ...

  2. 音频视频解决方案:GStreamer-ffmpeg-ffdshow-directshow-vfw

    Linux和window下几种流行的音频视频编程框架作一个总结,防止自己迷惘,免于晕头转向. 一.GStreamer GStreamer is a library that allows the co ...

  3. 各种音频视频编码方法

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...

  4. HTML5媒体(音频/视频)

    摘要: 在HTML5出现之前,web媒体大部分通过Flash来实现.这种方式造成了文件大加载慢,影响网站性能,开发难度高,维护麻烦,不易扩展等.这就导致HTML5自己开始支持媒体功能.HTML5 DO ...

  5. iOS 音频视频图像合成那点事

    代码地址如下: http://www.demodashi.com/demo/13420.html 人而无信不知其可 前言 很久很久没有写点什么了,只因为最近事情太多了,这几天终于闲下来了,趁此机会,记 ...

  6. 从入门到入土:Python实现爬取某站视频|根据视频编号|支持通过视频名称和创作者名称寻找编号|以及python moviepy合并音频视频

    写在前面: 此博客仅用于记录个人学习进度,学识浅薄,若有错误观点欢迎评论区指出.欢迎各位前来交流.(部分材料来源网络,若有侵权,立即删除) Python实现爬取某站视频|根据视频编号|支持通过视频名称 ...

  7. android 获取蓝牙设备id_安卓蓝牙系统中如何获取蓝牙音乐的音频跟踪会话ID

    原标题:安卓蓝牙系统中如何获取蓝牙音乐的音频跟踪会话ID 蓝牙音乐AudioTrack Session ID的获取 当今这个音视频无处不在的时代,音频跟踪会话ID(AudioTrack Session ...

  8. 音频/视频标签的使用

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 音视频的发展史 早期: 中期: 现在: 一.视频标签 定义 属性 写法 HTML 与 XHTML 之间的区别: 二.音 ...

  9. android声音编辑器,音频视频编辑器app下载-Audio Video Editorv1.1.0 安卓版-腾牛安卓网...

    Audio Video Editor,一款功能强大的音频视频编辑器软件,拥有音频切割.音频合并.视频切割.视频合并.音频与视频合并等功能,不仅可以编辑手机铃声,还能够制作出优质视频. 软件介绍: MP ...

  10. 使用ffmpeg合并音频视频并实现背景音乐循环播放

    这两天遇到一个问题,使用PowerPoint 2013创建的PPT文件 将该PPT复制到另一台电脑的时候,背景音乐不能播放 生成Mp4视频提示音频不能添加,因此生成的Mp4也不能播放背景音乐 原因是M ...

最新文章

  1. 【数理知识】《矩阵论》方保镕老师-第1章-矩阵的几何理论
  2. 脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手
  3. Javafx 报错Exception in Application start method java.lang.reflect.InvocationTargetException
  4. bootstrap - 弹出层
  5. linux环境c语言编程 蔡晋,Linux环境C语言编程
  6. Atitit 快速开发体系建设路线图
  7. CF991E Bus Number
  8. 植物大战僵尸实训记录
  9. 【原生JS小实例】加减乘除取余计算器
  10. android 2k屏分辨率是多少,手机2k屏幕是什么意思 2k屏幕几大问题
  11. java mpeg ps转mpeg-4_MPEG4格式转换器下载_枫叶MPEG4格式转换器(MPEG转换器) 9.0.5.0 共享版_极速下载站...
  12. 生成随机数字字母组合参数
  13. Windows NT
  14. 条码打印软件制作数字+字母的流水号二维码
  15. 一夜撸700万,羊毛党不光薅羊毛,还吃羊肉吸羊血。
  16. AXI总线信号含义说明
  17. 诺基亚夏令营游学经历
  18. Switch case小知识点
  19. opencv读取realsense
  20. 新一代硬件安全-自序

热门文章

  1. ncre计算机职业英语,NCRE计算机职业英语一级考试样卷.doc
  2. 斜杠 反斜杠  双斜杠 双反斜杠
  3. 单片机c语言的按键程序设计,单片机C语言程序设计:按键发音
  4. JAVA房屋租赁管理系统计算机毕业设计Mybatis+系统+数据库+调试部署
  5. 2021中国大学生程序设计竞赛(CCPC)- 网络选拔赛(重赛) Jumping Monkey(并查集,逆向考虑)
  6. 黑苹果简单的手动开启显示器HiDPI教程
  7. linux系统弹出鼠标,Ubuntu14.04及以上操作系统鼠标闪烁问题
  8. 屏幕不光只看尺寸 各材质屏幕实战解析
  9. QQ互联第三方登录多应用用户登录打通
  10. php属于哪种语言,php是哪种类型的语言