用Vue实现音乐播放器案例_vue内调起系统的喇叭-程序员宅基地

技术标签: css  html5  前端  vue.js  

需求

  1. 歌曲搜索
  2. 歌曲播放
  3. 歌曲封面
  4. 歌曲评论
  5. 播放动画
  6. mv播放

接口

歌曲搜索接口

  1. 请求地址

https://autumnfish.cn/search

  1. 请求方法 get
  2. 请求参数:keywords(查询的关键字)
  3. 响应内容(歌曲的搜索结果)

歌曲播放地址

  1. 请求地址

https://autumnfish.cn/song/url

  1. 请求方法:get
  2. 请求参数:id
  3. 相应内容:歌曲的url地址

歌曲详情获取

  1. 请求地址

https://autumnfish.cn/song/detail

  1. 请求方法:get
  2. 请求参数:ids
  3. 相应内容:歌曲详情,包含封面信息

歌曲评论

  1. 请求地址

https://autumnfish.cn/comment/hot

  1. 请求方法:get
  2. 请求参数:id
  3. 响应内容:歌曲的热门评论

mv地址获取

  1. 请求地址

https://autumnfish.cn/mv/url

  1. 请求方法:get
  2. 请求参数:id
  3. 响应内容:mv的地址

全部代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>网抑云音乐</title>
    <link rel="shortcut icon" href="images/音乐.png">
</head>
<style>
    a{
      
        text-decoration: none;
    }
    *{
      
        margin: 0;
        padding: 0;
    }
    @font-face {
      
        font-family: 'iconfont';
        src: url('font4/iconfont.eot');
        src: url('font4/iconfont.eot?#iefix') format('embedded-opentype'),
            url('font4/iconfont.woff2') format('woff2'),
            url('font4/iconfont.woff') format('woff'),
            url('font4/iconfont.ttf') format('truetype'),
            url('font4/iconfont.svg#iconfont') format('svg');
    }
    @font-face {
      
        font-family: 'iconfont';
        src: url('font3/iconfont.eot');
        src: url('font3/iconfont.eot?#iefix') format('embedded-opentype'),
            url('font3/iconfont.woff2') format('woff2'),
            url('font3/iconfont.woff') format('woff'),
            url('font3/iconfont.ttf') format('truetype'),
            url('font3/iconfont.svg#iconfont') format('svg');
    }
    @font-face {
      
    font-family: 'iconfont';
    src: url('font5/iconfont.eot');
    src: url('font5/iconfont.eot?#iefix') format('embedded-opentype'),
        url('font5/iconfont.woff2') format('woff2'),
        url('font5/iconfont.woff') format('woff'),
        url('font5/iconfont.ttf') format('truetype'),
        url('font5/iconfont.svg#iconfont') format('svg');
}
    .iconfont {
      
        font-family: "iconfont" !important;
        font-size: 22px;
        font-style: normal;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        position: absolute;
        top: 12px;
        right: 20px;
        color: #fff;
    }
    .iconfont1 {
      
        font-family: "iconfont" !important;
        font-size: 16px;
        font-style: normal;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        font-size: 20px;
        margin-left: 10px;
        color: blue;
        margin-right: 5px;
    }
    .iconfont2 {
      
    font-family: "iconfont" !important;
    font-size: 22px;
    font-style: normal;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    margin-left: 14px;
    }
    .iconfont1:hover,
    .iconfont2:hover{
      
        color:rgb(36, 131, 255);
    }
    body{
      
        background: url(images/W4.jpg);
        background-size: cover;
    }
    ul{
      
        list-style: none;
        height: 500px;
        overflow-y: scroll;
    }
    #music{
      
        width: 1000px;
        height: 626px;
        /* color="#323635" */
        /* background-color: rgb(104, 104, 104); */
        margin: 130px auto;
        border-radius: 4px;
        /* border:1px solid #fff; */
        box-shadow: 1px 1px 40px, -1px -1px 40px rgba(0,0,0,0.1);
    }
    .title{
      
        margin: 20px 30px;
        display: inline-block;
        font-size: 25px;
        color: #fff;
        
    }
    header{
      
        background-color:#858585;
        border-radius: 4px 4px 0 0;
    }
    .search{
      
        display: inline-block;
        width: 400px;
        height: 50px;
        background-color: #323635;
        float: right;
        margin-right: 40px;
        margin-top: 10px;
        border-radius: 30px;
        position: relative;
    }
    .box{
      
        width: 350px;
        margin: 10px 20px;
        height: 30px;
        font-size: 20px;
        background-color: #323635;
        color: #fff;
        font-weight: 100;
        outline: none;
        border: none;
    }
    .banner{
      
        height: 500px;
        background-color: rgba(255, 255, 255, 0.5);
        z-index: -1;
    }
    footer{
      
        height: 50px;
        background-color: rgb(68, 68, 68);
        border-radius: 0 0 4px 4px;
        z-index: 1;
    }
    .left{
      
        display: inline-block;
        width: 240px;
        height: 500px;
        float: left;
    }
    .center{
      
        width: 500px;
        display: inline-block;
        height: 500px;
        /* background-color: blue; */
        float: left;
        position: relative;
    }
    .right{
      
        float: right;
        /* background-color: green; */
        height: 500px;
        width: 258px;
    }
    .disc{
      
        width: 255px;
        height: 255px;
        background: url(images/disc.png);
        display: inline-block;
        position: absolute;
        top: 80px;
        left: 130px;
        position: relative;
    }
    /* 播放杆 */
    .player{
      
        background: url(images/player_bar.png) -2px -10px;
        width: 150px;
        height: 150px;
        display: inline-block;
        background-repeat: no-repeat;
        float: right;
        margin-right: 100px;
        position: absolute;
        left: 230px;
        transform: rotate(-25deg);
        transform-origin: 12px 12px;
        transition: 1s;
    }
    /* 播放杆转回去 */
    .player1{
      
        transform: rotate(0);
    }
    .line1{
      
        float: left;
    }
    .left ul li{
      
        color: rgb(27, 27, 27);
        width: 230px;
        line-height: 50px;
        /* border:1px solid pink; */
        /* color: white; */
    }
    .left ul li:nth-child(odd){
      
        background-color: rgba(255,255,255,0.3);
    }
    h2{
      
        margin-top: 10px;
        margin-left: 10px;
        font-size: 20px;
    }
    .sub{
      
        display: inline-block;
        width: 50px;
        height: 50px;
        border-radius: 50%;
        background-color: #fff;
        margin: 5px 0 0 10px;
    }
    .t1{
      
        width: 100%;
        height: 100%;
        overflow: hidden;
        border-radius: 50%;
        display: inline-block;
    }
    .webname{
      
        position: absolute;
        top: 4px;
        font-size: 15px;
        left: 70px;
    }
    .right li{
      
        position: relative;
        margin-bottom: 10px;
        height: 100px;
        width: 258px;
        overflow: scroll;
    }
    .com{
      
        position: absolute;
        top: 30px;
        left: 70px;
        color: #333;
    }
    .center1{
      
        width: 145px;
        height: 145px;
        position: absolute;
        top: 55px;
        left: 58px;
        border-radius: 50%;
    }
    .voice{
      
        /* width: 1000px;
        height: 50px;
        outline: none;
        background-color: rgb(68, 68, 68); */
        width: 1000px;
        height: 50px;
        outline: none;
        background-color: #f1f3f4;
        border-radius: 0 0 4px 4px;
        z-index: 1;
    }
    .cover{
      
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        float: left;
        background-color: rgba(0, 0, 0, 0.7);
    }
    .cover video{
      
        position: fixed;
        margin-top: 100px;
        width: 800px;
        height: 546px;
        left: 300px;
    }
            /* @keyframes Rotate {
        from {
            transform: rotateZ(0);
        }
        to {
            transform: rotateZ(360deg);
        }
        }
        /* 旋转的类名 */
        /* .autoRotate {
        animation-name: Rotate;
        animation-iteration-count: infinite;
        animation-play-state: paused;
        animation-timing-function: linear;
        animation-duration: 5s;
        } */
        /* 是否正在播放 */
        /* .player_con.playing .disc,
        .player_con.playing .cover {
        animation-play-state: running;
        } */ 
        /* 黑胶的转动 */
            @keyframes go{
      
            from{
      
                transform:rotateZ(0)
            }
            to{
      
                transform:rotateZ(360deg)
            }
        }
        .autoGo{
      
            animation: go 5s linear 0s infinite;
        }
        /* 黑胶暂停 */
        .disc1{
      
            animation-play-state: running;
        }

</style>
<body>
    <div id="music">
        <header>
            <span class="title">网抑云音乐</span>
            <div class="search">
                <input type="text" placeholder="搜索" class="box" @keyup.enter="insearch" v-model="query">
                <a href="javascript:;" class="iconfont" @click="insearch">&#xe501;</a>
            </div>
        </header>
        <div class="banner">
            <div class="left">
                <ul>
                    <li v-for="item in musiclist">
                        <a href="javascript:;" class="iconfont1" @click="pl(item.id)">&#xe601;</a>
                        {
   {item.name}}
                        <a href="javascript:;" class="iconfont2" v-if="item.mvid!=0" @click="mvPlay(item.mvid)">&#xe6af;</a>
                    </li>
                </ul>
            </div>
            <img src="images/line.png" alt="" class="line1">
            <img src="images/line.png" alt="" class="line2">
            <div class="center">
                <span class="disc" :class="{autoGo:isPlay}">
                    <img src="images/C1.JPG" class="center1">
                    <img src="" class="center1" :src="picSrc" v-if="picSrc">
                </span>
                <span class="player" :class="{player1:isPlay}"></span>
            </div>
            <div class="right">
                <h2>热门留言</h2>
                <ul>
                    <li v-for="item in hotComments">
                        <span class="sub">
                            <img src="" :src="item.user.avatarUrl" alt="" class="t1">
                        </span>
                        <span class="webname">{
   {item.user.nickname}}</span>
                        <span class="com">{
   {item.content}}</span>
                    </li>
                </ul>
            </div>
        </div>
        <footer>
            <!-- <audio ref="audio" src="" controls="" autoplay="" loop="" class="myaudio"></audio> -->
            <audio  src="" controls autoplay="" loop="" ref="audio" class="voice" :src="musicSrc"@play="play" @pause="pause"></audio>
        </footer>
        <div class="cover" v-if="cover" @click="close">
            <video ref='video' src="" controls :src="mvUrl" autoplay="" ></video>
        </div>
    </div>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var music=new Vue({
      
            el:"#music",
            data:{
      
                query:"",
                musiclist:[],
                musicSrc:"",
                picSrc:"",
                hotComments:[],
                mvUrl:"",
                cover:false,
                isPlay:false
            },
            methods:{
      
                insearch:function(){
      
                    var that=this;
                    axios.get("https://autumnfish.cn/search?keywords="+this.query).then(function(response){
      
                        console.log(response);
                        
                        that.musiclist=response.data.result.songs;
                    },function(err){
      
                        console.log(err);
                        
                    })
                    that.query=""
                },
                pl:function(musicid){
      
                    var that=this;
                    that.isPlay=true;
                    axios.get("https://autumnfish.cn/song/url?id="+musicid).then(function(response){
      
                        that.musicSrc=response.data.data[0].url;
                        console.log(that.musicSrc);
                    });

                    axios.get("https://autumnfish.cn/song/detail?ids="+musicid).then(function(response){
      
                        console.log(response.data.songs[0].al.picUrl);
                        that.picSrc=response.data.songs[0].al.picUrl;
                    })
                    axios.get("https://autumnfish.cn/comment/hot?type=0&id="+musicid).then(function(response){
      
                        console.log(response.data.hotComments);
                        that.hotComments=response.data.hotComments;
                        console.log(that.hotComments.content);
                        
                    })
                },
                mvPlay:function(mvid){
      
                    this.cover=true;
                    var that=this;
                    axios.get("https://autumnfish.cn/mv/url?id="+mvid).then(function(response){
      
                        console.log(response);
                        that.mvUrl=response.data.data.url;
                    })
                    this.$refs.audio.pause();
                },
                close:function(){
      
                    this.cover=false;
                    this.$refs.video.pause();
                },
                pause:function(){
      
                   this.isPlay=false;
                    
                },
                play:function(){
      
                    console.log(000);
                    this.isPlay=true;
                    
                }
            }
        })
    </script>
</body>
</html>

成果展示

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_34306228/article/details/124052212

智能推荐

我的程序员开始定义_程序员如何定义自己的程序段-程序员宅基地

文章浏览阅读1.1k次。要想学的好,就应该不断地去尝试,当我们_程序员如何定义自己的程序段

CompletableFuture学习_completablefuture 学习-程序员宅基地

文章浏览阅读209次。学习地址:https://colobu.com/2016/02/29/Java-CompletableFuture/CompletableFuture类实现了CompletionStage和Future接口:创建方法:public static CompletableFuture<Void> runAsync(Runnable runnable)public stati..._completablefuture 学习

SSM框架整合(以黑马程序员2022最新SSM框架教程P59为例)_spring整合mybatis源码 黑马程序员ssm框架教程-程序员宅基地

文章浏览阅读2.7k次。SSM框架快速整合3. 编写配置类 JdbcConfig类MyBatisConfig类SpringMvcCo_spring整合mybatis源码 黑马程序员ssm框架教程

《Vim实用技巧(第2版)》学习笔记:技巧112-认识Vim的关键字自动补全_vim 自动补全快捷键有多个选项时怎么选中需要的-程序员宅基地

文章浏览阅读212次。《Vim实用技巧(第2版)》学习笔记:技巧112-认识Vim的关键字自动补全1. 自动补全Vim的自动补全可以再插入模式下触发。ignorecase选项别启用后,自动补全时也会忽略大小写。可以用infercase 修正。2. 触发自动补全<C-p>与<C-n> 可以再补全列表中反向或正向选择。触发Vim 自动补全的方法总结命令补全类型..._vim 自动补全快捷键有多个选项时怎么选中需要的

经济学人The Economist学习(笔记词汇)Day2_经济学人the spoils of war-程序员宅基地

文章浏览阅读715次。材料均来自于微信公众号“每日双语经济学人&quot;重难点词汇:outstandingly['aut’stændiŋli] adv. 醒目地backdrop ['bæk’drɑp] n. 背景;背景幕;交流声aplomb [ə’plɑm] n. 自信,沉着,泰然自若bundle ['bʌndl] n.束;捆 vt. 捆 vi. 匆忙离开双语原文:经济学人 | 马云即将卸任 从阿里巴巴看中国的科..._经济学人the spoils of war

浅谈人工智能:现状、任务、构架与统一 | 正本清源(看完有新认知)_真目人工智能-程序员宅基地

文章浏览阅读3w次,点赞36次,收藏113次。浅谈人工智能:现状、任务、构架与统一原创 2017-11-02 朱松纯目录引言第一节 现状:正视现实第二节 未来:一只乌鸦给我们的启示第三节 历史:从“春秋五霸”到“战国六雄”第四节 统一:“小数据、大任务”范式与认知构架第五节 学科一:计算视觉 — 从“深”到“暗”第六节 学科二:认知推理 — 走进内心世界第七节 学科三:语言通讯 — 沟通的认知基础第..._真目人工智能

随便推点

外部SD卡无法写入_sd 卡无法写入 媒体 文件-程序员宅基地

文章浏览阅读1.2k次。外部SD卡无法写入_sd 卡无法写入 媒体 文件

jQuery选择器完全总结_jquery $("#input_commonnodesubtypeid option")得到的是什-程序员宅基地

文章浏览阅读802次。jQuery 选择器允许您对 HTML 元素组或单个元素进行操作。jQuery 选择器基于元素的 id、类、类型、属性、属性值等"查找"(或选择)HTML 元素。 它基于已经存在的 CSS 选择器,除此之外,它还有一些自定义的选择器。jQuery 中所有选择器都以美元符号开头:$()。 本文对jQuery选择器作一个总结。1、说明 通用语法:$('具体_jquery $("#input_commonnodesubtypeid option")得到的是什么

c语言变长(动态)数组 ArrayList_c语言list实现变长数组-程序员宅基地

文章浏览阅读2.5k次,点赞6次,收藏15次。关于变长(动态)数组 ArrayList缘起在c语言的程序设计中,想要实现对一个数组的长度的动态变化其实是比较困难的,并且也是低效且不尽实用的。但是看到别人在做arraylist时,我决定将网课上所学习的变长数组放上来。另一方面,正是由于变长数组的缺点使得我们可以引入链表的学习。java实现arraylist代码h文件中的代码样例#ifndef __ARRAY_H__#define ..._c语言list实现变长数组

opencv--imgproc模块·Hough 检测圆_imgproc.houghcircles-程序员宅基地

文章浏览阅读1k次。官网:http://www.opencv.org.cn/opencvdoc/2.3.2/html/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.html#hough-circle前言Hough变换也是在图像处理、计算机视觉领域应用很广泛的技术。经常是用Hough来检测直线,今天想学习下Hough检测圆。用官网的代码..._imgproc.houghcircles

uniapp ## 错误七 <map>:marker id should be a number-程序员宅基地

文章浏览阅读9k次,点赞8次,收藏5次。错误七 :marker id should be a number微信小程序报错:marker id should be a number1.首先看官方文档https://developers.weixin.qq.com/miniprogram/dev/component/map.html发现不是必填,但是随便填一个数字型number就可以解决问题以后,没解决一个bug,总结一个uniapp的知识点1.uniapp的应用生命周期2.页面生命周期..._marker id should be a number

Android Studio系列教程(一)_android studio系列(一)-程序员宅基地

文章浏览阅读837次。背景相信大家对Android Studio已经不陌生了,Android Studio是Google于2013 I/O大会针对Android开发推出的新的开发工具,目前很多开源项目都已经在采用,Google的更新速度也很快,明显能感觉到这是Android开发的未来,那么我们还有什么理由不去拥抱未来呢?虽然推出了很久,但是国内貌似普及的程度并不高,鉴于很多朋友求studio的详细教程,那么今天我就手把手_android studio系列(一)

推荐文章

热门文章

相关标签