vue-- a page to achieve music player


Please ignore the following paragraph
year is approaching, the addition of a little time at any rate. But dare not excessive pastime. Years have not spared me, I also do not want to bypass the years. And stuffed it expands, so this year seems to add more fulfilling.
I did not expect a more romantic love, grinding the ink OK song of the people, but to start a farm yard in this trade. Although the code to do farming, but can not break habits, every day will be songs. But since Recently, the company restrict access high-traffic network. Shrimp, cloud Netease, QQ and even cool dog, escaped.
Without a song, become like a hammer cattle suffer the same weakness into a pool of mud.
Fortunately, also with the use listen 1, but this insipid but people listen 1. And no song too, think this interface is substandard appetite. Being a front-end, also stained appearance seized four pick three problems.
Then a flash, he wanted to make a come out.


image description

Project Address: HTTPS: //github.com/ermu592275 ...
Demo: HTTPS: //ermu592275254.github .... (because referer restrictions, can not search for a song)

Pre-conceived development

interface

Do music player, the interface must be cool. The songs did not feel too low. For use itself is at work, then made a similar YORK cloud music interface, the right size. Not compatible with the mobile phone side.

Icons do with css

With this simple and practical needs to consider, icon available SVG, url or css. Relative to the url, SVG and css better. For practice, the final choice of css. Make good use after and before, can reduce a lot of nested dom.

 .next {
    position: relative;
    display: inline-block;
    height: 36px;
    width: 36px;
    border: 2px solid #fff;
    border-radius: 20px;
    -webkit-border-radius: 20px;
    -moz-border-radius: 20px;
}
        
.next:before {
    content: '';
    height: 0;
    width: 0;
    display: block;
    border: 10px transparent solid;
    border-right-width: 0;
    border-left-color: #fff;
    position: absolute;
    top: 8px;
    left: 10px;
}

.next:after {
    content: '';
    height: 20px;
    width: 4px;
    display: block;
    background: #fff;
    position: absolute;
    top: 8px;
    left: 22px;
}

Draw a record

NetEase cloud record looks good, I have to get a record!
Good use Box-Shadow , one element can be made good look at the record results.

.disc {
    position: relative;
    margin-top: 10%;
    margin-left: 10%;
    width: 300px;
    height: 300px;
    border-radius: 300px;
    transform: rotate(45deg);
    background-image: radial-gradient(5em 30em ellipse, #fff, #000);
    border: 2px solid #131313;
    box-shadow: 0 0 0 10px #343935;
    opacity: 0.7;
}

Do progress bar with range

Style audio itself is ugly and different browsers presentation of the results are not the same. Of course, you can modify the audio style, the traditional approach is to hide the audio controls through the property, and then be replaced with div. Now is the era of html5, of course, use more in line with the new elements of the scene ---- range.

 input[type=range] {
    -webkit-appearance: none;
    width: 80%;
    height: 8px;
    border-radius: 10px;
    background-color: #fff;
}
input[type=range]::-webkit-slider-thumb{
    -webkit-appearance: none;
} 
input[type=range]::-webkit-slider-runnable-track {
    height: 8px;
    border-radius: 20px;
}
input[type=range]:focus {
    outline: none;
}

input[type=range]::-webkit-slider-thumb {
    -webkit-appearance: none;
    margin-top: -3px;
    height: 14px;
    width: 14px;
    background: #eb7470;
    border-radius: 50%;
    border: solid 3px #fff;
    box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.5);
}

Background blur filter

Set a picture as the background of a great feeling, it can be said color values ​​of the entire player which provides the background half. Settings are also very simple, uses css3 filters.

.bg-blur {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    height: 100%;
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
    filter: blur(20px);
    z-index: -1;
}

Background image control by js.

 <div class="bg-blur" :style="`background-image:url(${currentSong.album_logo})`"></div>

Songs resources

Climb down Interface

Shrimp directly to the official website open network, which will copy the url to the postman do requests. It found that by modifying the headers will check Referer. That allowed only shrimp domain can access this interface.
http: //api.xiami.com/web v = 2 ....?

To solve cross-domain problems

Because the interface supports jsonp. At first try to chrome browser settings across domains, and then do a jsonp request by $ .ajax. It can be accessed normally.
Then suddenly die, is not the shrimp have been restricted?
Then switch to start a service node, to forge referer initiated the request, and then forwards the request to the page. Inadvertently wrote a proxy.

...
case '/song':
    let songOptions = {
        url: 'http://api.xiami.com/web?'+ urlArr[1],
        headers: {
            'Referer': 'http://m.xiami.com/'
        }
    };
    function callback1(error, response, body) {
        if (!error && response.statusCode == 200) {
            res.end(body);
        }
    }
    request(songOptions, callback1);
    break;
...

Scroll lyrics

As a relatively high force grid player, the lyrics scroll is a must.

principle

Each word will be saved as an object with corresponding time. When the length greater than or equal to the lyrics of the current song playing when the time is less than this time in the lyrics of the lyrics, then scroll the lyrics to this viewing area. And change the font color.

Format lyrics

Interface returned lyrics look ignorant force, a closer look and found that there is a pattern.

[ti:aLIEz]
[ar:SawanoHiroyuki[nZk]:mizuki]
[al:o1]
[ly:澤野弘之]
[mu:澤野弘之]
[ma:]
[pu:]
[by:ttpod]
[total:268512]
[offset:0]
[00:00.000]<195>aLIEz <199>- <451>SawanoHiroyuki[nZk]:mizuki
[x-trans]彻头彻尾的谎言 - SawanoHiroyuki[nZk]:mizuki
[00:01.095]<201>作<250>詞<200>:<201>澤<200>野<199>弘<300>之
[x-trans]
[00:02.846]<200>作<150>曲<150>:<200>澤<200>野<351>弘<349>之
[x-trans]
[00:20.828]<200>決<250>め<200>つ<201>け<149>ば<201>か<349>り
[x-trans]一直独断专权
[00:23.279]<200>自<200>惚<200>れ<200>を<200>着<400>た
[x-trans]总是自负逞强
[00:24.979]<200>チ<200>ー<200>プ<450>な<550>hokori<350>で
[x-trans]明明只是一文不值的骄傲
......
   refactoringLyrics(lyric){
    let text = lyric.split('[offset:0]')[1];
    let textArr = text.split('\n');
    let lyricsArr = [], translate = [];
    textArr.forEach((item, index) => {
        let time = 0, text = '';
        if (item.indexOf('[x-trans]') > -1) {
            translate.push(item.split('[x-trans]')[1])
        } else if (item.trim() != '') {
            time = item.slice(1, 6).split(':');
            time = parseInt(time[0]) * 60 + parseInt(time[1]);
            text = item.slice(11);
            let arr = text.split('>');
            let str = arr.reduce((a, b) => {
                return a.split('<')[0] + b.split('<')[0]
            });
            let obj = {
                time: time,
                text: str
            };
            lyricsArr.push(obj);
        }
    });
    for (let i in translate) {
        lyricsArr[i].text = lyricsArr[i].text + '\n' + translate[i];
    }
    this.currentLyrics = lyricsArr;
},

Search bar to achieve

Mount assembly erupted in the same file

In order to follow the development of modular, we decided to write a subcomponent of the search bar. Write subassemblies in the same page, subassemblies mounted to have to pay attention to the corresponding template. This template can not be mounted component contains the element's parent, or because the data can not be rendered sub-assemblies and report undefined when the parent component rendering.

<div id="app" class="main">
...
</div>
<template id="search-box">
...
</template>

var searchBox = {
        template: '#search-box',
        props: {
            isShow: Boolean,
            openFun: Function
        },
        data(){
            return {
                resultList: [],
                searchValue: '',
            }
        },
        methods: {
        }
    };
 new Vue({
    el: '#app',
    components: {
        'com-tip': tip,
        'search-box': searchBox
    },
    ...
})

eventBus solve the data transmission

By jsonp to request data, we need to set a callback function, the callback written as a global function, if you do not write, but by
the form of searchBox.methods.callback, this point will be methods. The data can not be directly assigned to searchBox.
Thus processed by eventBus, so easier to maintain.

var EventBus = new Vue();
var callBack = function(result) {
    console.log(result);
    EventBus.$emit('callBack', result);
};
...
mounted(){
    let self = this;
    EventBus.$on('callBack', function(res) {
        if (res && res.data) {
            self.resultList = res.data.songs;
        }
    })
}
...

localStrong store song information

Next time you turn, should playlist once the data should be retained on, this can be achieved directly localstrong

Technical supplements

Blur filter HTTP: //www.zhangxinxu.com/wor ...
CSS icon HTTP: //www.uiplayground.in/cs ...
Flex is compatible with the wording: https://www.cnblogs.com/irisz .. .
Flex layout tutorial http: //www.ruanyifeng.com/blo ...
slider style custom http: //blog.csdn.net/u0133472 ...
hide scrollbars compatible https://segmentfault.com/q / 10 ...
Audio properties https: //developer.mozilla.org ...
Audio event https: //developer.mozilla.org ...

Stepped pit

Data transfer prop

Use cdn, vue of prop supports only the center line format, the format does not take effect hump
ps: hump with webpack packaged items can be used in the packaging process, will do the processing.

// 正确写法
<search-box :is-show="showSearch" :open-fun="openSearch" @push-song="pushNewSong"
                @play-song="playSong"></search-box>
// 错误写法
<search-box :isShow="showSearch" :openFun="openSearch" @pushSong="pushNewSong"
                @playSong="playSong"></search-box>

To be optimized

Manually modify the schedule, occasionally not take effect.
Search does not support pagination
does not support the construction of a single song
background color and the color of the progress bar similar need to modify the color of the progress bar
does not support the playback mode selection - Single cycle - Shuffle

Guess you like

Origin www.cnblogs.com/baimeishaoxia/p/12050650.html