资源来源网络,如果需要授权,请大家更换源码,模块仅供学习,下载后请2小时内删除,如需商用请购买正版授权
html代码
<!-- app root container --> <div class="app-wrap" id="app" v-cloak> <!-- app player container --> <main class="player-wrap fx fx-fade-in" ref="playerWrap" style="opacity: 0"> <!-- bg absolute elements --> <figure class="player-bg" ref="playerBg"></figure> <canvas class="player-canvas" ref="playerCanvas"></canvas> <!-- main player layout --> <section class="player-layout"> <!-- player top header --> <header class="player-header flex-row flex-middle flex-stretch"> <h2 class="text-clip flex-1"><i class="fa fa-headphones"></i> <span>Soma FM Player</span></h2> <button class="text-nowrap common-btn" @click="toggleSidebar( true )"><i class="fa fa-bars"></i></button> </header> <!-- player middle content area --> <main class="player-content flex-row"> <!-- default greet message --> <section class="player-greet" v-if="!hasChannel && !hasErrors"> <div class="fx fx-slide-left push-bottom"><h1>Pick a Station</h1></div> <div class="fx fx-slide-left fx-delay-1 push-bottom">This is a music streaming player for the channels provided by SomaFM.com. Just pick a station from the sidebar to the right to start listening.</div> <div class="fx fx-slide-up fx-delay-2 pad-top"><button class="cta-btn" @click="toggleSidebar( true )"><i class="fa fa-headphones"> </i> View Stations</button></div> </section> <!-- show selected channel info if possible --> <section class="player-channel flex-1" v-if="hasChannel && !hasErrors" :key="channel.id"> <div class="flex-autorow flex-middle flex-stretch"> <!-- station details --> <div class="flex-item flex-1"> <!-- station --> <div class="push-bottom pad-bottom border-bottom"> <div class="flex-row flex-middle"> <img class="img-round fx fx-drop-in fx-delay-1" :src="channel.largeimage" width="80" height="80" :alt="channel.title" /> <div class="pad-left fx fx-slide-left fx-delay-2"> <div class="text-clip text-uppercase">{{ channel.genre | toSpaces }}</div> <h2 class="text-clip">{{ channel.title }}</h2> </div> </div> </div> <!-- description --> <div class="push-bottom pad-bottom border-bottom fx fx-slide-up fx-delay-3"> {{ channel.description }} </div> <!-- current track --> <div class="push-bottom pad-bottom border-bottom fx fx-slide-up fx-delay-4" :key="track.date"> <div><span class="text-faded">DJ:</span> <span class="text-default">{{ channel.dj | toText( 'N/A' ) }}</span></div> <div><span class="text-faded">Playing:</span> <span class="text-secondary">{{ track.title | toText( 'N/A' ) }}</span></div> <div><span class="text-faded">From:</span> <span class="text-bright">{{ track.album | toText( 'N/A' ) }}</span></div> <div><span class="text-faded">By:</span> <span class="text-default">{{ track.artist | toText( 'N/A' ) }}</span></div> </div> <!-- buttons --> <div class="push-bottom"> <a class="cta-btn text-nowrap fx fx-slide-up fx-delay-5" :href="channel.twitter" title="Open link" target="_blank"> <i class="fa fa-twitter"></i> Twitter </a> <a class="cta-btn text-nowrap fx fx-slide-up fx-delay-6" :href="channel.infourl" title="Channel page" target="_blank"> <span class="fx fx-notx fx-ibk fx-drop-in fx-delay-1" :key="channel.listeners"><i class="fa fa-headphones"></i> {{ channel.listeners | toCommas( 0 ) }}</span> </a> <a class="cta-btn text-nowrap fx fx-slide-up fx-delay-7" :href="channel.plsfile" title="Download PLS" target="_blank"> <i class="fa fa-download"></i> </a> </div> </div> <!-- songs list --> <div class="flex-item flex-1"> <div class="push-bottom"> <h5 class="fx fx-slide-left fx-delay-1">Recent Tracks</h5> </div> <div class="card push-bottom" v-if="!hasSongs"> There are no songs loaded yet for this station. </div> <ul class="player-tracklist push-bottom" v-if="hasSongs"> <li v-for="( s, i ) of songsList" :key="s.date" class="card fx" :class="'fx-slide-left fx-delay-' + ( i + 2 )"> <div><span class="text-secondary">{{ s.title | toText( 'N/A' ) }}</span></div> <div><span class="text-faded">From:</span> <span class="text-bright">{{ s.album | toText( 'N/A' ) }}</span></div> <div><span class="text-faded">By:</span> <span class="text-default">{{ s.artist | toText( 'N/A' ) }}</span></div> </li> </ul> </div> </div> </section> <!-- show tracks for selected channel if possible --> <section class="player-errors flex-1 text-center" v-if="hasErrors" key="errors"> <div class="push-bottom fx fx-drop-in fx-delay-1"> <i class="fa fa-plug text-huge text-faded"></i> </div> <div class="push-bottom fx fx-slide-up fx-delay-2"> <h3>Oops, there's a problem!</h3> </div> <hr /> <div class="text-primary push-bottom fx fx-slide-up fx-delay-3" v-if="errors.init" v-text="errors.init"></div> <div class="text-primary push-bottom fx fx-slide-up fx-delay-4" v-if="errors.stream" v-text="errors.stream"></div> <hr /> <button class="cta-btn text-nowrap fx fx-slide-up fx-delay-5" @click="tryAgain"> <i class="fa fa-refresh"></i> Try again </button> </section> </main> <!-- player footer with controls --> <footer class="player-footer flex-row flex-middle flex-space"> <!-- player controls --> <section class="player-controls flex-row flex-middle push-right" :class="{ 'disabled': !canPlay }"> <button class="common-btn" @click="togglePlay()"> <i v-if="playing" class="fa fa-stop fx fx-drop-in" key="stop"></i> <i v-else class="fa fa-play fx fx-drop-in" key="play"></i> </button> <div class="form-slider push-left"> <i class="fa fa-volume-down"></i> <input class="common-slider" type="range" min="0.0" max="1.0" step="0.1" value="0.5" v-model="volume" /> <i class="fa fa-volume-up"></i> </div> <div class="text-clip push-left"> <span>{{ timeDisplay }}</span> <span class="fx fx-fade-in fx-delay-1" v-if="hasChannel" :key="channel.id"> | {{ channel.title }}</span> </div> </section> <!-- player links --> <section class="player-links text-nowrap"> <a class="common-btn text-faded" href="https://github.com/rainner/soma-fm-player" title="View on Github" target="_blank"> <i class="fa fa-github"></i> </a> <a class="common-btn text-faded" href="https://codepen.io/rainner" title="Codepen Projects" target="_blank"> <i class="fa fa-codepen"></i> </a> </section> </footer> </section> <!-- layout wrapper --> <!-- player stations overlay + sidebar --> <section class="player-stations" :class="{ 'visible': sidebar }" @click="toggleSidebar( false )"> <aside class="player-stations-sidebar" @click.stop> <!-- sidebar search --> <header class="player-stations-header flex-row flex-middle flex-stretch"> <div class="form-input push-right"> <i class="fa fa-search"></i> <input type="text" placeholder="Search station..." v-model="searchText" /> </div> <button class="common-btn" @click="toggleSidebar( false )"><i class="fa fa-times-circle"></i></button> </header> <!-- sidebar stations list --> <ul class="player-stations-list"> <li class="player-stations-list-item flex-row flex-top flex-stretch" v-for="c of channelsList" :key="c.id" @click="selectChannel( c )" :class="{ 'active': c.active }"> <figure class="push-right if-small"> <img class="img-round" width="70" height="70" :src="c.largeimage" :alt="c.title" /> </figure> <aside class="flex-1"> <div class="flex-row flex-middle flex-space"> <h6 class="text-bright text-clip">{{ c.title }}</h6> <div class="text-secondary"><i class="fa fa-headphones"></i> {{ c.listeners | toCommas( 0 ) }}</div> </div> <div class="text-small"> <span class="text-faded text-uppercase text-small">{{ c.genre | toSpaces }}</span> <br /> {{ c.description }} </div> </aside> </li> </ul> <!-- sidebar sort options --> <footer class="player-stations-footer flex-row flex-middle flex-stretch"> <div class="flex-1 push-right"> <span @click="toggleSortOrder()" class="fa clickable" :class="{ 'fa-sort-amount-desc': sortOrder === 'desc', 'fa-sort-amount-asc': sortOrder === 'asc' }"> </span> <span class="text-faded">Sort: </span> <span class="text-secondary popover"> <span class="clickable">{{ sortLabel }}</span> <span class="popover-box popover-top"> <button @click="sortBy( 'title', 'asc' )">Station Name</button> <button @click="sortBy( 'listeners', 'desc' )">Listeners Count</button> <button @click="sortBy( 'genre', 'asc' )">Music Genre</button> </span> </span> </div> <div> </div> </footer> </aside> </section> </main> <!-- player --> </div> <!-- wrapper -->