1 Star 0 Fork 5

AMI/tv

forked from 火昱/tv 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
192.168.12.224.html 146.28 KB
一键复制 编辑 原始数据 按行查看 历史
火昱 提交于 2023-06-03 12:51 . update 192.168.12.224.html.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157
<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width,initial-scale=1,user-scalable=0,maximum-scale=1,viewport-fit=cover">
<title>R1 Control</title>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/vue@2.6.14/dist/vue.min.js"></script>
<script src="https://unpkg.com/element-ui@2.15.6/lib/index.js"></script>
<script src="https://unpkg.com/axios@0.26.0/dist/axios.min.js"></script>
<style>
:root {
--color-body-bg: #fff;
--color-text: #000;
--color-title: #ff9347;
--color-primary: #335eea;
--color-primary-bg: #eaeffd;
--color-secondary: #7a7a7b;
--color-secondary-bg: #f5f5f7;
--color-navbar-bg: hsla(0, 0%, 100%, 0.86);
--color-primary-bg-for-transparent: rgba(189, 207, 255, 0.28);
--color-secondary-bg-for-transparent: rgba(209, 209, 214, 0.28);
--html-overflow-y: overlay;
}
[data-theme=dark] {
--color-body-bg: #222;
--color-text: #fff;
--color-primary-bg: #bbcdff;
--color-secondary: #7a7a7b;
--color-secondary-bg: #323232;
--color-navbar-bg: rgba(34, 34, 34, 0.86);
--color-primary-bg-for-transparent: hsla(0, 0%, 100%, 0.12);
--color-secondary-bg-for-transparent: hsla(0, 0%, 100%, 0.08);
}
body {
margin: 0;
padding: 0;
outline: none;
}
.el-slider__button-wrapper {
z-index: 90 !important;
}
#app {
position: relative;
left: 0;
top: 0;
right: 0;
bottom: 0;
overflow: hidden;
background-color: var(--color-body-bg);
}
#app .menu {
position: fixed;
right: 0;
top: 0;
z-index: 2001;
}
#app .menu .icon {
position: absolute;
right: -20px;
font-size: 40px;
color: var(--color-text);
cursor: pointer;
transition: 0.5s;
}
#app .menu .icon:hover {
right: 0;
}
#app .drawer-mark {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
opacity: 0.5;
display: none;
background: #000;
z-index: 2000;
}
#app .drawer-ltr {
position: absolute;
top: 0;
right: -64px;
width: 64px;
transition: 0.5s;
}
#app .drawer-ltr.active {
right: -5px;
}
#app .drawer-ltr .el-menu-item i {
line-height: 56px !important;
}
#app .main {
position: fixed;
top: 0px;
left: 0px;
right: 0px;
overflow-x: hidden;
overflow-y: auto;
padding-top: 40px;
height: calc(100vh - 40px);
color: var(--color-text);
background-color: var(--color-body-bg);
}
#app .main::-webkit-scrollbar {
display: none;
}
#app .main.hasfooter {
height: calc(100vh - 104px);
}
#app .main .title {
font-size: 20px;
margin-left: 10px;
color: var(--color-title);
}
#app .main .item-title {
margin: 5px 10px 5px 15px;
font-size: 20px;
}
#app .button-icon.disabled {
cursor: default;
opacity: 0.38;
}
#app .button-icon.disabled:hover {
background: none;
}
#app .button-icon.disabled:active {
transform: unset;
}
#app .button-icon {
display: flex;
justify-content: center;
align-items: center;
padding: 8px;
background: transparent;
margin: 4px;
border-radius: 25%;
transition: 0.2s;
background: none;
border: none;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
font-family: inherit;
}
#app .button-icon:hover {
background: rgba(209, 209, 214, 0.5);
}
#app .button-icon .svg-icon {
color: var(--color-text);
height: 16px;
width: 16px;
}
#app .player {
position: fixed;
bottom: 0;
right: 0;
left: 0;
display: flex;
flex-direction: column;
justify-content: space-around;
height: 64px;
backdrop-filter: saturate(180%) blur(30px);
background-color: var(--color-navbar-bg);
z-index: 100;
}
#app .progress-bar {
margin-top: -6px;
margin-bottom: -6px;
width: 100%;
}
#app .player>.controls {
display: grid;
grid-template-columns: repeat(3, 1fr);
height: 100%;
padding-left: 10vw;
padding-right: 10vw;
}
#app .blank {
flex-grow: 1;
}
#app .controls .playing {
display: flex;
}
#app .controls .playing .container {
display: flex;
align-items: center;
}
#app .controls .playing .container img {
height: 46px;
border-radius: 5px;
box-shadow: 0 6px 8px -2px rgba(0, 0, 0, 0.16);
cursor: pointer;
user-select: none;
}
#app .controls .playing .container .track-info {
height: 46px;
margin-left: 12px;
display: flex;
flex-direction: column;
justify-content: center;
}
#app .controls .playing .container .track-info .name {
font-weight: 600;
font-size: 16px;
opacity: 0.88;
color: var(--color-text);
margin-bottom: 4px;
cursor: pointer;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
word-break: break-all;
}
#app .controls .playing .container .track-info .name:hover {
text-decoration: underline;
}
#app .controls .playing .container .track-info .artist {
font-size: 12px;
opacity: 0.58;
color: var(--color-text);
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
word-break: break-all;
}
#app .controls .playing .container .track-info .artist span.ar {
cursor: pointer;
}
#app .controls .playing .container .track-info .artist span.ar:hover {
text-decoration: underline;
}
#app .middle-control-buttons {
display: flex;
}
#app .middle-control-buttons .container {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
padding: 0 8px;
}
#app .middle-control-buttons .container .button-icon {
margin: 0 8px;
}
#app .middle-control-buttons .container .play {
height: 42px;
width: 42px;
}
#app .middle-control-buttons .container .play .svg-icon {
width: 24px;
height: 24px;
}
#app .right-control-buttons {
display: flex;
}
#app .right-control-buttons .container {
display: flex;
justify-content: flex-end;
align-items: center;
}
#app .right-control-buttons .container .volume-control {
margin-left: 4px;
display: flex;
align-items: center;
}
#app .right-control-buttons .container .volume-control .volume-bar {
width: 84px;
}
#app .right-control-buttons .container .active .svg-icon {
color: var(--color-primary);
}
#app .like-button {
margin-left: 16px;
}
#app .next-tracks {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
overflow: auto;
padding: 10px 10vw 70px 10vw;
box-sizing: border-box;
z-index: 99;
background-color: var(--color-navbar-bg);
}
#app .track-list::-webkit-scrollbar {
display: none;
}
#app .next-tracks h1 {
margin-top: 10px;
margin-bottom: 18px;
cursor: default;
color: var(--color-text);
display: flex;
justify-content: space-between;
}
#app .track .button-icon {
display: flex;
justify-content: center;
align-items: center;
padding: 8px;
background: transparent;
border-radius: 25%;
transition: transform 0.2s;
}
#app .track .button-icon .svg-icon {
height: 16px;
width: 16px;
color: #335eea;
}
#app .track .button-icon:hover {
transform: scale(1.12);
}
#app .track .button-icon:active {
transform: scale(0.96);
}
#app .track {
display: flex;
align-items: center;
padding: 8px;
border-radius: 12px;
user-select: none;
}
#app .track .explicit-symbol {
opacity: 0.28;
color: #335eea;
}
#app .track .explicit-symbol .svg-icon {
margin-bottom: -3px;
}
#app .track .explicit-symbol.before-artist {
margin-right: 2px;
}
#app .track .explicit-symbol.before-artist .svg-icon {
margin-bottom: -3px;
}
#app .track .title-and-artist {
flex: 1;
display: flex;
}
#app .track .title-and-artist .container {
display: flex;
flex-direction: column;
}
#app .track .title-and-artist .title {
font-size: 18px;
font-weight: 600;
color: var(--color-text);
cursor: default;
padding-right: 16px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
word-break: break-all;
}
#app .track .title-and-artist .title .featured {
margin-right: 2px;
font-weight: 500;
font-size: 14px;
opacity: 0.72;
}
#app .track .title-and-artist .artist {
margin-top: 2px;
font-size: 13px;
opacity: 0.68;
color: var(--color-text);
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
}
#app .track .album {
flex: 1;
display: flex;
font-size: 16px;
opacity: 0.88;
color: var(--color-text);
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
#app .track .time {
font-size: 16px;
width: 50px;
cursor: default;
display: flex;
justify-content: flex-end;
margin-right: 10px;
font-variant-numeric: tabular-nums;
opacity: 0.88;
color: var(--color-text);
}
#app .track:hover {
transition: all 0.3s;
background: var(--color-secondary-bg);
}
#app .track.disable img {
filter: grayscale(1) opacity(0.6);
}
#app .track.disable .title,
#app .track.disable .artist,
#app .track.disable .album,
#app .track.disable .time,
#app .track.disable .no,
#app .track.disable .featured {
opacity: 0.28 !important;
}
#app .track.disable:hover {
background: none;
}
#app .track.tracklist img {
height: 36px;
width: 36px;
border-radius: 6px;
margin-right: 14px;
cursor: pointer;
}
#app .track.tracklist .title {
font-size: 16px;
}
#app .track.tracklist .artist {
font-size: 12px;
}
#app .track.album {
height: 32px;
}
#app .actions {
width: 80px;
display: flex;
justify-content: flex-end;
visibility: hidden;
}
#app .track:hover .actions {
visibility: visible;
}
#app .track.playing {
background: var(--color-primary-bg);
color: var(--color-primary);
height: 48px;
}
#app .track.playing .title,
#app .track.playing .album,
#app .track.playing .time {
color: var(--color-primary);
}
#app .track.playing .title .featured,
#app .track.playing .artist,
#app .track.playing .explicit-symbol {
color: var(--color-primary);
opacity: 0.88;
}
#app .dynamic-background>div {
animation: rotate 150s linear infinite;
}
@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
#app .left-side {
flex: 1;
display: flex;
justify-content: flex-end;
/* margin-right: 32px;*/
margin-top: 24px;
align-items: center;
transition: all 0.5s;
z-index: 1;
}
#app .left-side .controls {
max-width: 54vh;
margin-top: 24px;
color: var(--color-text);
}
#app .left-side .controls .title {
margin-top: 8px;
font-size: 1.4rem;
font-weight: 600;
opacity: 0.88;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
}
#app .left-side .controls .subtitle {
margin-top: 4px;
font-size: 1rem;
opacity: 0.58;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
overflow: hidden;
}
#app .left-side .controls .top-part {
display: flex;
justify-content: space-between;
}
#app .left-side .controls .top-part .buttons {
display: flex;
align-items: center;
}
#app .left-side .controls .top-part .buttons button {
margin: 0 0 0 4px;
}
#app .left-side .controls .top-part .buttons .svg-icon {
height: 18px;
width: 18px;
}
#app .left-side .controls .progress-bar {
margin-top: 22px;
display: flex;
align-items: center;
justify-content: space-between;
}
#app .left-side .controls .progress-bar .slider {
width: 100%;
flex-grow: grow;
padding: 0 10px;
}
#app .left-side .controls .progress-bar span {
font-size: 15px;
opacity: 0.58;
min-width: 28px;
}
#app .left-side .controls .media-controls {
display: flex;
justify-content: center;
margin-top: 18px;
align-items: center;
}
#app .left-side .controls .media-controls button {
margin: 0;
}
#app .left-side .controls .media-controls .svg-icon {
opacity: 0.38;
height: 14px;
width: 14px;
}
#app .left-side .controls .media-controls .active .svg-icon {
opacity: 0.88;
}
#app .left-side .controls .media-controls .middle {
padding: 0 16px;
display: flex;
align-items: center;
}
#app .left-side .controls .media-controls .middle button {
margin: 0 8px;
}
#app .left-side .controls .media-controls .middle button#play .svg-icon {
height: 28px;
width: 28px;
padding: 2px;
}
#app .left-side .controls .media-controls .middle .svg-icon {
opacity: 0.88;
height: 22px;
width: 22px;
}
#app .box-menu {
padding-left: 10vw;
padding-right: 10vw;
}
#app .box-menu+.box-menu {
margin-top: 44px;
}
#app .box-menu>.title {
display: flex;
justify-content: space-between;
align-items: flex-end;
margin-bottom: 20px;
font-size: 28px;
font-weight: 700;
color: var(--color-text);
}
#app .box-menu .cover-row {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 44px 24px;
}
#app .box-menu .item {
color: var(--color-text);
}
#app .box-menu .item .cover {
position: relative;
transition: transform .3s;
}
#app .box-menu .item .cover:hover .play-button {
display: flex;
}
#app .box-menu .item .cover-hover:hover {
cursor: pointer;
}
#app .box-menu .item .play-button,
#app .box-menu .item .shade {
display: flex;
justify-content: center;
align-items: center;
}
#app .box-menu .cover .cover-container {
position: relative;
overflow: hidden;
border-radius: .75em;
aspect-ratio: 1/1;
}
#app .box-menu .item .shade {
position: absolute;
top: 0;
height: calc(100% - 3px);
width: 100%;
background: transparent;
z-index: 1;
}
#app .box-menu .item .play-button {
color: #fff;
-webkit-backdrop-filter: blur(8px);
backdrop-filter: blur(8px);
background: hsla(0, 0%, 100%, .14);
border: 1px solid hsla(0, 0%, 100%, .08);
height: 22%;
width: 22%;
border-radius: 50%;
cursor: default;
transition: .2s;
width: 22%;
height: 22%;
display: none;
cursor: pointer;
}
#app .box-menu .item .play-button:hover {
background: hsla(0, 0%, 100%, .28);
}
#app .box-menu .item .play-button .svg-icon {
height: 44%;
margin-left: 4px;
}
#app .box-menu .item .cover-container img {
border-radius: .75em;
width: 100%;
height: auto;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
aspect-ratio: 1/1;
transition: all .3s ease-in-out;
}
#app .box-menu .item .cover-container:hover img {
transform: scale(1.3);
}
#app .box-menu .item .text {
margin-top: 10px;
}
#app .box-menu .item .text .title {
font-size: 18px;
font-weight: 600;
line-height: 20px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
word-break: break-all;
color: var(--color-text);
margin-left: 0;
}
#app .box-menu .item .text .info {
font-size: 14px;
opacity: 0.68;
line-height: 18px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
word-break: break-word;
color: var(--color-text);
}
#app .box-menu .svg-icon {
height: 12px;
width: 12px;
}
#app .main .play-music-navmenu {
position: absolute;
left: 50%;
top: 0px;
transform: translateX(-50%);
border-radius: 0px 0px 10px 10px;
overflow: hidden;
}
#app .main .loading-mark {
position: absolute;
width: 100%;
top: 0;
bottom: 0;
z-index: 10;
}
#app .main .uid {
position: absolute;
left: 10px;
top: 10px;
cursor: pointer;
}
#app .main .uid>span {
color: #ff5722;
}
#app .progress-bar .el-slider__button-wrapper.hover,
#app .progress-bar .el-slider__button-wrapper:hover,
#app .progress-bar .el-slider__button.hover,
#app .progress-bar .el-slider__button:hover {
cursor: pointer;
}
#app .progress-bar .el-slider {
height: 2px;
padding: 6px 0px;
width: auto;
}
#app .progress-bar .el-slider__runway {
height: 100%;
margin: 0;
background-color: hsla(0, 0%, 50.2%, .18);
}
#app .progress-bar .el-slider__bar {
height: 2px;
}
#app .progress-bar .el-slider__button-wrapper {
height: 12px;
width: 12px;
}
#app .volume-control .el-slider__button-wrapper {
top: -13px;
}
#app .progress-bar .el-slider__button {
height: 12px;
width: 12px;
border: none;
background-color: var(--color-text);
visibility: hidden;
}
#app .progress-bar .el-slider:hover .el-slider__button {
visibility: visible;
}
#app .left-side .progress-bar .el-slider {
width: 100%;
padding: 0 10px;
}
#app .left-side .progress-bar .el-slider {
height: 4px;
}
#app .left-side .progress-bar .el-slider__bar {
height: 4px;
background-color: #fff;
}
#app .volume-control .progress-bar {
width: 84px;
}
#app .volume-control .el-slider {
height: 4px;
}
#app .volume-control .el-slider__runway {
border-radius: 15px;
}
#app .volume-control .el-slider__bar {
height: 4px;
background-color: var(--color-text);
}
#app .volume-control .el-slider:hover .el-slider__bar {
background-color: var(--color-primary);
}
@media (max-aspect-ratio: 1.1111111111) {
#app .left-side {
display: none;
}
#app .right-side {
margin-right: 0;
}
}
@media (max-width: 1336px) {
#app .player>.controls {
padding: 0 5vw;
}
#app .next-tracks {
padding: 10px 5vw 70px 5vw;
}
#app .box-menu {
padding-left: 5vw !important;
padding-right: 5vw !important;
}
}
@media (max-aspect-ratio: 10 / 9) {
#app .left-side {
display: none;
}
#app .right-side {
margin-right: 0;
}
}
@media (max-width: 834px) {
#app .box-menu .item .text .title {
font-size: 14px;
}
}
@media (max-width: 768px) {
#app .next-tracks h1 {
font-size: 30px;
}
#app .box-menu .cover-row {
grid-template-columns: repeat(4, 1fr);
}
#app .track-list .track .album {
flex: 0;
}
#app .player>.controls {
padding: 0;
grid-template-columns: repeat(2, 1fr);
}
#app .player>.controls .playing {
display: none;
}
#app .container>span[title="歌词"] {
margin-left: 4px !important;
}
#app .play-music-navmenu .el-menu--horizontal>.el-menu-item {
height: 40px;
line-height: 40px;
}
#app .play-music-navmenu .el-menu-item {
padding: 0px 8px;
}
}
@media (max-width: 500px) {
#app .next-tracks h1,
#app .box-menu>.title {
font-size: 22px;
}
#app .box-menu .cover-row {
grid-template-columns: repeat(3, 1fr);
gap: 30px 14px;
}
#app .box-menu .item .text .info {
font-size: 12px;
}
#app .track-list .track .time,
#app .track-list .track .actions {
display: none;
}
#app .volume-bar {
display: none;
}
#app .middle-control-buttons .container .button-icon {
margin: 0;
}
#app .main .uid {
font-size: 12px;
left: 0;
}
}
@media (max-width: 360px) {
#app .middle-control-buttons .container {
padding: 0;
}
#app .volume-control .progress-bar {
width: 78px;
}
#app .right-control-buttons .container .volume-control {
margin-left: 0;
}
}
</style>
</head>
<body>
<div id="app" :data-theme="theme">
<div class="menu" @click="drawer = true">
<i class="el-icon-s-fold icon"></i>
<div class="drawer-ltr" :class="{active: drawer}" @click.stop>
<el-menu :collapse="true" @select="handleChangeMenu">
<el-menu-item index="0">
<i class="el-icon-service"></i>
<span slot="title">点歌列表</span>
</el-menu-item>
<el-menu-item index="1">
<i class="el-icon-monitor"></i>
<span slot="title">屏幕控制</span>
</el-menu-item>
<el-menu-item index="2">
<i class="el-icon-s-operation"></i>
<span slot="title">音效控制</span>
</el-menu-item>
<el-menu-item index="3">
<i class="el-icon-s-tools"></i>
<span slot="title">音箱控制</span>
</el-menu-item>
<el-menu-item index="100">
<i class="el-icon-moon-night"></i>
<span slot="title">切换主题</span>
</el-menu-item>
</el-menu>
</div>
</div>
<div class="drawer-mark" @click="drawer = false" :style="{display: drawer ? 'block' : 'none'}"></div>
<div class="main" :class="{hasfooter: deviceInfo.music_info}" v-show="!nextTracksPage">
<!-- 点歌列表 -->
<template>
<div v-show="activeMenu == 0">
<div class="play-music-navmenu">
<el-menu default-active="1001" @select="handleChangeList" mode="horizontal"
background-color="var(--color-text)" text-color="var(--color-body-bg)"
active-text-color="#ffd04b">
<el-menu-item index="1001">
<span slot="title">网易</span>
</el-menu-item>
<el-menu-item index="1002" v-if="(netEaseUid - 0 > 0)">
<span slot="title">My</span>
</el-menu-item>
<el-menu-item index="1003">
<span slot="title">收藏</span>
</el-menu-item>
<el-menu-item index="1004">
<span slot="title">随机</span>
</el-menu-item>
<el-menu-item index="1005">
<span slot="title">搜索</span>
</el-menu-item>
</el-menu>
</div>
<div class="loading-mark" v-show="isLoading.playMusicNavmenu">
<div v-loading="isLoading.playMusicNavmenu" element-loading-text="拼命加载中..."
element-loading-spinner="el-icon-loading" element-loading-background="rgba(0,0,0,.7)"
style="height: 100%;"></div>
</div>
<div v-show="activeList == 1001">
<div class="box-menu" v-for="(item, index) of netEaseBangMenu" :key="'netEasebang-' + index">
<div class="title">{{item.name}}</div>
<div class="cover-row">
<div class="item" v-for="(ite, ind) of item.list" :key="'netEaselist-' + ind">
<div class="cover cover-hover">
<div class="cover-container">
<div class="shade">
<span class="play-button" @click="goToPlayList(ite.id)">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 448 512"
class="svg-icon">
<path fill="currentColor"
d="M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z" />
</svg>
</span>
</div>
<img :src="ite.pic" alt="">
</div>
</div>
<div class="text">
<div class="title">{{ite.name}}-{{ite.pub}}</div>
<div class="info" :title="ite.intro">
<span>{{ite.intro}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div v-show="activeList == 1002">
<span class="uid">
Uid:
<span>{{netEaseUid}}</span>
</span>
<div class="box-menu" v-for="(item, index) of myMusicMenu" :key="'myMusic-' + index">
<div class="title">{{item.name}} <span
style="font-size: 16px; color: #e91e63;cursor: pointer;" @click="refreshMyMenu"
title="用于打开此页面后,更新网易云歌单,而这里没有更新">刷新歌单</span> </div>
<div class="cover-row">
<div class="item" v-for="(ite, ind) of item.list" :key="'myMusiclist-' + ind">
<div class="cover cover-hover">
<div class="cover-container">
<div class="shade">
<span class="play-button" @click="goToPlayList(ite.id)">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 448 512"
class="svg-icon">
<path fill="currentColor"
d="M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z" />
</svg>
</span>
</div>
<img :src="ite.pic" alt="">
</div>
</div>
<div class="text">
<div class="title">{{ite.name}}-{{ite.pub}}</div>
<div class="info" :title="ite.intro">
<span>{{ite.intro}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div v-show="activeList == 1003">
<div class="box-menu">
<el-input placeholder="网易云歌单ID" style="width: 200px;margin-bottom: 20px;"
v-model="netEaseLId" clearable>
</el-input>
<br>
<el-button type="primary" @click="goToPlayList(netEaseLId)">播放</el-button>
<el-button type="warning" @click="collectMusicList" title="仅记录在这个浏览器上">收藏</el-button>
<el-switch v-model="delCollectListMode"
v-show="collectList[0].list && collectList[0].list.length > 0" active-text="删除"
inactive-text="默认" active-color="#ffeb3b" inactive-color="#cccccc">
</el-switch>
</div>
<div class="box-menu" v-for="(item, index) of collectList" :key="'collect-' + index">
<div class="title" v-show="item.list.length > 0">{{item.name}}</div>
<div class="cover-row">
<div class="item" v-for="(ite, ind) of item.list" :key="'collectList-' + ind">
<div class="cover cover-hover">
<div class="cover-container">
<div class="shade">
<span class="play-button" @click="goToPlayList(ite.id)"
v-show="!delCollectListMode">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 448 512"
class="svg-icon">
<path fill="currentColor"
d="M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z" />
</svg>
</span>
<span class="play-button" @click="delCollectMusicList(ite.id)"
v-show="delCollectListMode">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 352 512"
class="svg-icon" style="color: red;">
<path fill="currentColor"
d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z">
</path>
</svg>
</span>
</div>
<img :src="ite.pic" alt="">
</div>
</div>
<div class="text">
<div class="title">{{ite.name}}-{{ite.pub}}</div>
<div class="info" :title="ite.intro">
<span>{{ite.intro}}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<!-- 屏幕控制 -->
<template>
<div v-show="activeMenu == 1">
<div v-show="screencap.length > 1"
style="margin:5px 15px;display: flex;justify-content: center;align-items: center;">
<img id="screen" :src="screencap" width="100%" alt="屏幕"
style="max-width: 1024px;user-select: none;-webkit-user-drag: none;" />
</div>
<div style="height: 110px;width: 100%;position: relative;">
<span id="arrow_keys"
style="width: 120px;height: 100%;display: inline-block;position: absolute;left: calc(50% - 130px);">
<el-button type="info" icon="el-icon-caret-top"
style="position: absolute;top: 0;left: calc(50% - 20px);margin: 0;" circle
@click="sendKeyevent(19)"></el-button>
<el-button type="info" icon="el-icon-caret-right"
style="position: absolute;top: calc(50% - 20px);right: 0;margin: 0;" circle
@click="sendKeyevent(22)"></el-button>
<el-button type="info" icon="el-icon-caret-bottom"
style="position: absolute;bottom: 0;left: calc(50% - 20px);margin: 0;" circle
@click="sendKeyevent(20)"></el-button>
<el-button type="info" icon="el-icon-caret-left"
style="position: absolute;top: calc(50% - 20px);left: 0;margin: 0;" circle
@click="sendKeyevent(21)"></el-button>
</span>
<span id="function_keys"
style="width: 150px;height: 100%;display: inline-block;position: absolute;right: calc(50% - 160px);">
<el-button icon="el-icon-back" round
style="position: absolute;top: calc(50% - 20px);left: 0;margin: 0;"
@click="sendKeyevent(4)" title="返回"></el-button>
<el-button type="primary" icon="el-icon-thumb" round
style="position: absolute;top: calc(50% - 20px);right: 0;margin: 0;"
@click="sendKeyevent(23)" title="确认"></el-button>
</span>
</div>
</div>
</template>
<!-- 音效控制 -->
<template>
<div v-show="activeMenu == 2">
<div id="volume" class="item-title">
<span>
音量 : <span>{{deviceInfo.vol}}</span> / 15
</span>
<el-slider v-model="deviceInfo.vol" :max="15" :show-tooltip="false" @change="setVolume">
</el-slider>
</div>
<div id="loudness" class="item-title">
<span>
响度 : <span>{{soundEffect.loudness.Current_Gain / 100}}</span> dB
</span>
<span style="float: right;">
<el-switch :value="soundEffect.loudness.sound_effects_loudness_enable"
active-color="#13ce66" inactive-color="#ff4949" active-text="开" inactive-text="关"
@change="btnLoudness">
</el-switch>
</span>
<el-slider v-model="soundEffect.loudness.Current_Gain" :step="100" :min="-3000" :max="3000"
:show-tooltip="false" :disabled="!soundEffect.loudness.Loudness_Enable"
@change="setLoudness"></el-slider>
</div>
<div id="bass" class="item-title">
<span>
低音增强 : <span>{{soundEffect.bass.Current_Strength / 10}}</span> %
</span>
<span style="float: right;">
<el-switch :value="soundEffect.bass.sound_effects_bass_enable" active-color="#13ce66"
inactive-color="#ff4949" active-text="开" inactive-text="关" @change="btnBass">
</el-switch>
</span>
<el-slider v-model="soundEffect.bass.Current_Strength" :step="100" :max="1000"
:show-tooltip="false" :disabled="!soundEffect.bass.Bass_Enable" @change="setBass">
</el-slider>
</div>
<div v-for="(item, index) in soundEffect.eq.Bands.list" :key="'eq' + index" :id="'eq' + index"
class="item-title">
<span>
<el-tooltip placement="top-start">
<div slot="content">频率 : {{item.Frequency}}</div>
<span>
{{ eqBandListName[index] }} : </span>
</el-tooltip>
<span>{{item.BandLevel / 100}}</span> dB
</span>
<span style="float: right;" v-if="index == 0">
<el-switch :value="soundEffect.eq.sound_effects_eq_enable" active-color="#13ce66"
inactive-color="#ff4949" active-text="开" inactive-text="关" @change="btnEq">
</el-switch>
</span>
<el-slider v-model="item.BandLevel" :step="100" :min="-1500" :max="1500" :show-tooltip="false"
:disabled="!soundEffect.eq.Eq_Enable" @change="setEq(index)"></el-slider>
</div>
<el-row class="item-title">
<el-button type="danger" style="margin:5px;" v-for="(item, index) in soundEffect.eq.Preset_list"
:key="'Preset_list' + index " @click="setEqMode(index)">
{{eqPresetListName[item.Name]}}
</el-button>
<el-button v-for="(item, index) in myEqMode" :key="'myEqMode' + index" type="danger"
style="margin:5px;" @click="setMyEqMode(index)">
{{item.Name}}
</el-button>
<el-button v-for="(item, index) in myEqMode2" v-show="!isDelEqMode" :key="'myEqMode2' + index"
type="danger" style="margin:5px;" @click="setMyEqMode2(index)">
{{item.Name}}
</el-button>
<el-popconfirm v-for="(item, index) in myEqMode2" v-show="isDelEqMode"
:key="'myEqMode2b' + index" :title="'确定删除 : '+ item.Name + ' ?'" :hide-icon="true"
@confirm="delEqMode(item)">
<el-button slot="reference" type="warning" style="margin:5px;">
{{item.Name}}
</el-button>
</el-popconfirm>
</el-row>
<el-row class="item-title">
<el-button type="primary" style="margin:5px;" @click="dialogVisible = true">
保存设置
</el-button>
<el-switch :value="!isDelEqMode" v-show="myEqMode2.length > 0" active-color="#13ce66"
inactive-color="#ff4949" active-text="默认模式" inactive-text="删除模式"
@change="isDelEqMode = !isDelEqMode">
</el-switch>
<el-dialog :visible.sync="dialogVisible" width="250px" center :modal="false">
<el-input v-model="eqModeName" placeholder="给当前设置的音频一个名字"></el-input>
<span slot="footer">
<el-button @click="dialogVisible = false">取 消</el-button>
<el-button type="primary" @click="addEqMode">确 定</el-button>
</span>
</el-dialog>
</el-row>
</div>
</template>
<!-- 音箱控制 -->
<template>
<div v-show="activeMenu == 3">
<div class="item-title">
<span>
蓝牙 :
</span>
<el-switch :value="Bluetooth" active-color="#13ce66" inactive-color="#ff4949" active-text="开"
inactive-text="关" @change="BluetoothControl">
</el-switch>
</div>
<div class="item-title">
<span>
氛围灯 :
</span>
<el-switch :value="deviceInfo.music_light_enable" active-color="#13ce66"
inactive-color="#ff4949" active-text="开" inactive-text="关" @change="musicLightControl">
</el-switch>
</div>
<div class="item-title">
<span>
氛围灯亮度 : <span>{{deviceInfo.music_light_luma}}</span>
</span>
<el-slider v-model="deviceInfo.music_light_luma" :min="1" :max="200" :show-tooltip="false"
@change="musciLightLuma"></el-slider>
</div>
<div class="item-title">
<span>
氛围灯颜色渐变速度 : <span>{{deviceInfo.music_light_chroma}}</span>
</span>
<el-slider v-model="deviceInfo.music_light_chroma" :min="1" :max="100" :show-tooltip="false"
@change="musicLightChroma"></el-slider>
</div>
<div class="item-title">
<span>
氛围效果 :
</span>
<el-radio-group v-model="deviceInfo.music_light_mode" @change="musicLightMode"
style="display: block;margin:5px;">
<el-radio-button :label="0">官方氛围</el-radio-button>
<el-radio-button :label="2">七彩氛围</el-radio-button>
</el-radio-group>
</div>
<div class="item-title" v-if="false">
<span>
网络配置 :
</span>
<div>
<el-popconfirm title="确定要打开配网模式吗?打开后网页控制将断开!" :hide-icon="true" @confirm="netConfig()">
<el-button slot="reference" type="primary" style="margin:5px;">
打开网络配置
</el-button>
</el-popconfirm>
</div>
</div>
<div class="item-title">
<span>
shell命令 :
</span>
<div>
<el-popconfirm title="是否确认重启app" :hide-icon="true"
@confirm="restartApp('com.phicomm.speaker.device')">
<el-button slot="reference" type="danger" style="margin:5px;">
重启小讯
</el-button>
</el-popconfirm>
<el-popconfirm title="是否确认重启音箱" :hide-icon="true" @confirm="reboot">
<el-button slot="reference" type="danger" style="margin:5px;">
重启音箱
</el-button>
</el-popconfirm>
<el-button type="danger" style="margin:5px;"
@click="restartdialogVisible = true, getListPackages()">
开关软件
</el-button>
<el-dialog :title="listPackagesIndex == null ? '重启软件' : listPackagesIndex"
:visible.sync="restartdialogVisible" width="375px" center :modal="false">
<el-radio-group v-model="listPackagesIndex"
style="height: 400px;width: 100%;overflow-y: scroll;overflow-x: hidden;">
<el-radio v-for="(item ,index) of listPackages" :key="'listPackages-' + index"
:label="item">
{{item}}
</el-radio>
</el-radio-group>
<span slot="footer" class="dialog-footer">
<el-button type="info" @click="restartdialogVisible = false, stopApp()">
</el-button>
<el-button type="success" @click="restartdialogVisible = false, startApp()">
</el-button>
<el-button @click="restartdialogVisible = false">取 消</el-button>
</span>
</el-dialog>
<br>
<el-button type="primary" @click="light(true)" style="margin:5px 0 5px 5px;">
开灯
</el-button>
<el-button type="primary" @click="light()" style="margin:5px 5px 5px 0;">
关灯
</el-button>
<el-popconfirm title="清除所有闹钟,同时重启半岛app" :hide-icon="true" @confirm="clear()">
<el-button slot="reference" type="danger" style="margin:5px;">
清除闹钟
</el-button>
</el-popconfirm>
<el-popover placement="top" width="160" v-model="shellVisible">
<textarea v-model="shellStr" cols="30" rows="3" style="width: 100%;"></textarea>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="shellVisible = false">取消</el-button>
<el-button type="primary" size="mini" @click="shellVisible = false, executeShell()">
执行</el-button>
</div>
<el-button slot="reference" title="F12 console 有输出结果">输入shell</el-button>
</el-popover>
</div>
</div>
<div class="item-title">
<span>
固件版本 : {{systemInfo.incremental}}
</span>
</div>
<div class="item-title">
<span>
可用运存 : {{parseInt((systemInfo.MemFree + systemInfo.Cached) / 1024)}} Mb/
{{parseInt(systemInfo.MemTotal / 1024)}} Mb
</span>
</div>
<div class="item-title">
<span>
系统启动时间 : {{new Date(systemInfo.btime).Format('yyyy-MM-dd hh:mm:ss')}}
</span>
</div>
<div class="item-title">
<span>
系统已运行 : {{new Date(new Date().getTime() - systemInfo.btime).totalDay('dd天hh:mm:ss')}}
</span>
</div>
</div>
</template>
</div>
<template v-if="deviceInfo.music_info">
<div class="player">
<div class="progress-bar">
<el-slider :value="Math.round(deviceInfo.music_info.position)" :min="0"
:max="Math.round(deviceInfo.music_info.duration)" :format-tooltip="typeMmss"></el-slider>
</div>
<div class="controls">
<div class="playing">
<div class="container" @click.stop>
<img width="46" height="46" :src="songInfo.pic" />
<div class="track-info">
<div class="name" :title="songInfo.name">
{{songInfo.name}}
</div>
<div class="artist">
<span>{{songInfo.artist}}</span>
</div>
</div>
<div class="like-button button-icon" v-show="showLike">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 30 30" class="svg-icon"
style="display:none;">
<path
d="M15,26c-0.21,0-0.42-0.066-0.597-0.198C13.938,25.456,3,17.243,3,11c0-3.859,3.141-7,7-7c2.358,0,4.062,1.272,5,2.212 C15.938,5.272,17.642,4,20,4c3.859,0,7,3.14,7,7c0,6.243-10.938,14.456-11.403,14.803C15.42,25.934,15.21,26,15,26z"
fill="currentColor" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 30 30" class="svg-icon">
<path
d="M 9.5449219 3 C 5.3895807 3 2 6.3895806 2 10.544922 C 2 14.283156 4.9005496 18.084723 7.6601562 21.119141 C 10.419763 24.153558 13.171875 26.369141 13.171875 26.369141 A 1.0001 1.0001 0 0 0 13.197266 26.388672 C 13.517448 26.630481 13.956962 26.684854 14.369141 26.785156 A 1.0001 1.0001 0 0 0 15 27 A 1.0001 1.0001 0 0 0 15.630859 26.785156 C 16.043038 26.684854 16.482552 26.630481 16.802734 26.388672 A 1.0001 1.0001 0 0 0 16.828125 26.369141 C 16.828125 26.369141 19.580237 24.153558 22.339844 21.119141 C 25.099451 18.084722 28 14.283156 28 10.544922 C 28 6.3895806 24.610419 3 20.455078 3 C 17.450232 3 15.833405 4.5910542 15 5.5664062 C 14.166595 4.5910543 12.549768 3 9.5449219 3 z M 9.5449219 5 C 12.372924 5 14.069642 7.4290597 14.126953 7.5117188 A 1.0001 1.0001 0 0 0 14.910156 8.0078125 A 1.0001 1.0001 0 0 0 15.003906 8.0117188 A 1.0001 1.0001 0 0 0 15.019531 8.0117188 A 1.0001 1.0001 0 0 0 15.042969 8.0097656 A 1.0001 1.0001 0 0 0 15.119141 8.0039062 A 1.0001 1.0001 0 0 0 15.871094 7.5136719 C 15.925786 7.4347249 17.624838 5 20.455078 5 C 23.529737 5 26 7.4702629 26 10.544922 C 26 13.147688 23.499768 16.870104 20.859375 19.773438 C 18.227966 22.666891 15.607768 24.780451 15.589844 24.794922 C 15.414236 24.925626 15.219097 25 15 25 C 14.780903 25 14.585764 24.925626 14.410156 24.794922 C 14.392232 24.780451 11.772034 22.66689 9.140625 19.773438 C 6.5002316 16.870105 4 13.147688 4 10.544922 C 4 7.4702629 6.470263 5 9.5449219 5 z"
fill="currentColor" />
</svg>
</div>
</div>
<div class="blank"></div>
</div>
<div class="middle-control-buttons">
<div class="blank"></div>
<div class="container" @click.stop>
<span class="button-icon" title="上一首" @click="prev()">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 448 512" class="svg-icon">
<path fill="currentColor"
d="M64 468V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12v176.4l195.5-181C352.1 22.3 384 36.6 384 64v384c0 27.4-31.9 41.7-52.5 24.6L136 292.7V468c0 6.6-5.4 12-12 12H76c-6.6 0-12-5.4-12-12z" />
</svg>
</span>
<span class="button-icon play" :title="isPlay ? '暂停' : '播放'"
@click="isPlay ? pause() : play()">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 448 512" class="svg-icon"
v-show="!isPlay">
<path fill="currentColor"
d="M424.4 214.7L72.4 6.6C43.8-10.3 0 6.1 0 47.9V464c0 37.5 40.7 60.1 72.4 41.3l352-208c31.4-18.5 31.5-64.1 0-82.6z" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 448 512" class="svg-icon"
v-show="isPlay">
<path fill="currentColor"
d="M144 479H48c-26.5 0-48-21.5-48-48V79c0-26.5 21.5-48 48-48h96c26.5 0 48 21.5 48 48v352c0 26.5-21.5 48-48 48zm304-48V79c0-26.5-21.5-48-48-48h-96c-26.5 0-48 21.5-48 48v352c0 26.5 21.5 48 48 48h96c26.5 0 48-21.5 48-48z" />
</svg>
</span>
<span class="button-icon" title="下一首" @click="next()">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 448 512" class="svg-icon">
<path fill="currentColor"
d="M384 44v424c0 6.6-5.4 12-12 12h-48c-6.6 0-12-5.4-12-12V291.6l-195.5 181C95.9 489.7 64 475.4 64 448V64c0-27.4 31.9-41.7 52.5-24.6L312 219.3V44c0-6.6 5.4-12 12-12h48c6.6 0 12 5.4 12 12z" />
</svg>
</span>
</div>
<div class="blank"></div>
</div>
<div class="right-control-buttons">
<div class="blank"></div>
<div class="container" @click.stop>
<span class="button-icon" title="播放列表" @click="nextTracksPage = !nextTracksPage"
:class="{'active': nextTracksPage}">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 512 512" class="svg-icon">
<path fill="currentColor"
d="M16 256h256a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16zm0-128h256a16 16 0 0 0 16-16V80a16 16 0 0 0-16-16H16A16 16 0 0 0 0 80v32a16 16 0 0 0 16 16zm128 192H16a16 16 0 0 0-16 16v32a16 16 0 0 0 16 16h128a16 16 0 0 0 16-16v-32a16 16 0 0 0-16-16zM470.94 1.33l-96.53 28.51A32 32 0 0 0 352 60.34V360a148.76 148.76 0 0 0-48-8c-61.86 0-112 35.82-112 80s50.14 80 112 80 112-35.82 112-80V148.15l73-21.39a32 32 0 0 0 23-30.71V32a32 32 0 0 0-41.06-30.67z" />
</svg>
</span>
<!-- 1: 随机;2: 顺序;3: 单曲 -->
<span class="button-icon active" @click="setPlayMode()"
:title="playModes[deviceInfo.play_mode - 1]">
<!-- 随机播放 -->
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 512 512" class="svg-icon"
v-show="deviceInfo.play_mode == 1">
<path fill="currentColor"
d="M504.971 359.029c9.373 9.373 9.373 24.569 0 33.941l-80 79.984c-15.01 15.01-40.971 4.49-40.971-16.971V416h-58.785a12.004 12.004 0 0 1-8.773-3.812l-70.556-75.596 53.333-57.143L352 336h32v-39.981c0-21.438 25.943-31.998 40.971-16.971l80 79.981zM12 176h84l52.781 56.551 53.333-57.143-70.556-75.596A11.999 11.999 0 0 0 122.785 96H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12zm372 0v39.984c0 21.46 25.961 31.98 40.971 16.971l80-79.984c9.373-9.373 9.373-24.569 0-33.941l-80-79.981C409.943 24.021 384 34.582 384 56.019V96h-58.785a12.004 12.004 0 0 0-8.773 3.812L96 336H12c-6.627 0-12 5.373-12 12v56c0 6.627 5.373 12 12 12h110.785c3.326 0 6.503-1.381 8.773-3.812L352 176h32z" />
</svg>
<!-- repeat 顺序播放-->
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 512 512" class="svg-icon"
v-show="deviceInfo.play_mode == 2">
<path fill="currentColor"
d="M512 256c0 88.224-71.775 160-160 160H170.067l34.512 32.419c9.875 9.276 10.119 24.883.539 34.464l-10.775 10.775c-9.373 9.372-24.568 9.372-33.941 0l-92.686-92.686c-9.373-9.373-9.373-24.568 0-33.941l92.686-92.686c9.373-9.373 24.568-9.373 33.941 0l10.775 10.775c9.581 9.581 9.337 25.187-.539 34.464L170.067 352H352c52.935 0 96-43.065 96-96 0-13.958-2.996-27.228-8.376-39.204-4.061-9.039-2.284-19.626 4.723-26.633l12.183-12.183c11.499-11.499 30.965-8.526 38.312 5.982C505.814 205.624 512 230.103 512 256zM72.376 295.204C66.996 283.228 64 269.958 64 256c0-52.935 43.065-96 96-96h181.933l-34.512 32.419c-9.875 9.276-10.119 24.883-.539 34.464l10.775 10.775c9.373 9.372 24.568 9.372 33.941 0l92.686-92.686c9.373-9.373 9.373-24.568 0-33.941l-92.686-92.686c-9.373-9.373-24.568-9.373-33.941 0L306.882 29.12c-9.581 9.581-9.337 25.187.539 34.464L341.933 96H160C71.775 96 0 167.776 0 256c0 25.897 6.186 50.376 17.157 72.039 7.347 14.508 26.813 17.481 38.312 5.982l12.183-12.183c7.008-7.008 8.786-17.595 4.724-26.634z" />
</svg>
<!-- repeat1 单曲循环-->
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 512 512" class="svg-icon"
v-show="deviceInfo.play_mode == 3">
<path fill="currentColor"
d="M512 256c0 88.224-71.775 160-160 160H170.067l34.512 32.419c9.875 9.276 10.119 24.883.539 34.464l-10.775 10.775c-9.373 9.372-24.568 9.372-33.941 0l-92.686-92.686c-9.373-9.373-9.373-24.568 0-33.941l80.269-80.27c9.373-9.373 24.568-9.373 33.941 0l10.775 10.775c9.581 9.581 9.337 25.187-.539 34.464l-22.095 20H352c52.935 0 96-43.065 96-96 0-13.958-2.996-27.228-8.376-39.204-4.061-9.039-2.284-19.626 4.723-26.633l12.183-12.183c11.499-11.499 30.965-8.526 38.312 5.982C505.814 205.624 512 230.103 512 256zM72.376 295.204C66.996 283.228 64 269.958 64 256c0-52.935 43.065-96 96-96h181.933l-22.095 20.002c-9.875 9.276-10.119 24.883-.539 34.464l10.775 10.775c9.373 9.372 24.568 9.372 33.941 0l80.269-80.27c9.373-9.373 9.373-24.568 0-33.941l-92.686-92.686c-9.373-9.373-24.568-9.373-33.941 0l-10.775 10.775c-9.581 9.581-9.337 25.187.539 34.464L341.933 96H160C71.775 96 0 167.776 0 256c0 25.897 6.186 50.376 17.157 72.039 7.347 14.508 26.813 17.481 38.312 5.982l12.183-12.183c7.008-7.008 8.786-17.595 4.724-26.634zm154.887 4.323c0-7.477 3.917-11.572 11.573-11.572h15.131v-39.878c0-5.163.534-10.503.534-10.503h-.356s-1.779 2.67-2.848 3.738c-4.451 4.273-10.504 4.451-15.666-1.068l-5.518-6.231c-5.342-5.341-4.984-11.216.534-16.379l21.72-19.939c4.449-4.095 8.366-5.697 14.42-5.697h12.105c7.656 0 11.749 3.916 11.749 11.572v84.384h15.488c7.655 0 11.572 4.094 11.572 11.572v8.901c0 7.477-3.917 11.572-11.572 11.572h-67.293c-7.656 0-11.573-4.095-11.573-11.572v-8.9z" />
</svg>
</span>
<div class="volume-control">
<span class="button-icon" title="静音" @click="mute">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 480 512" class="svg-icon"
v-if="volume >= 8">
<path fill="currentColor"
d="M215.03 71.05L126.06 160H24c-13.26 0-24 10.74-24 24v144c0 13.25 10.74 24 24 24h102.06l88.97 88.95c15.03 15.03 40.97 4.47 40.97-16.97V88.02c0-21.46-25.96-31.98-40.97-16.97zM480 256c0-63.53-32.06-121.94-85.77-156.24-11.19-7.14-26.03-3.82-33.12 7.46s-3.78 26.21 7.41 33.36C408.27 165.97 432 209.11 432 256s-23.73 90.03-63.48 115.42c-11.19 7.14-14.5 22.07-7.41 33.36 6.51 10.36 21.12 15.14 33.12 7.46C447.94 377.94 480 319.53 480 256zm-141.77-76.87c-11.58-6.33-26.19-2.16-32.61 9.45-6.39 11.61-2.16 26.2 9.45 32.61C327.98 228.28 336 241.63 336 256c0 14.38-8.02 27.72-20.92 34.81-11.61 6.41-15.84 21-9.45 32.61 6.43 11.66 21.05 15.8 32.61 9.45 28.23-15.55 45.77-45 45.77-76.88s-17.54-61.32-45.78-76.86z" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 512 512" class="svg-icon"
v-else-if="volume == 0">
<path fill="currentColor"
d="M215.03 71.05L126.06 160H24c-13.26 0-24 10.74-24 24v144c0 13.25 10.74 24 24 24h102.06l88.97 88.95c15.03 15.03 40.97 4.47 40.97-16.97V88.02c0-21.46-25.96-31.98-40.97-16.97zM461.64 256l45.64-45.64c6.3-6.3 6.3-16.52 0-22.82l-22.82-22.82c-6.3-6.3-16.52-6.3-22.82 0L416 210.36l-45.64-45.64c-6.3-6.3-16.52-6.3-22.82 0l-22.82 22.82c-6.3 6.3-6.3 16.52 0 22.82L370.36 256l-45.63 45.63c-6.3 6.3-6.3 16.52 0 22.82l22.82 22.82c6.3 6.3 16.52 6.3 22.82 0L416 301.64l45.64 45.64c6.3 6.3 16.52 6.3 22.82 0l22.82-22.82c6.3-6.3 6.3-16.52 0-22.82L461.64 256z" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 384 512" class="svg-icon"
v-else>
<path fill="currentColor"
d="M215.03 72.04L126.06 161H24c-13.26 0-24 10.74-24 24v144c0 13.25 10.74 24 24 24h102.06l88.97 88.95c15.03 15.03 40.97 4.47 40.97-16.97V89.02c0-21.47-25.96-31.98-40.97-16.98zm123.2 108.08c-11.58-6.33-26.19-2.16-32.61 9.45-6.39 11.61-2.16 26.2 9.45 32.61C327.98 229.28 336 242.62 336 257c0 14.38-8.02 27.72-20.92 34.81-11.61 6.41-15.84 21-9.45 32.61 6.43 11.66 21.05 15.8 32.61 9.45 28.23-15.55 45.77-45 45.77-76.88s-17.54-61.32-45.78-76.87z" />
</svg>
</span>
<div class="progress-bar">
<el-slider v-model="deviceInfo.vol" :min="0" :max="15" @change="setVolume">
</el-slider>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="next-tracks" v-if="nextTracksPage">
<h1>播放列表</h1>
<div class="track-list" style="overflow-y: scroll; height: calc(100vh - 160px);"
@dblclick="playMusic($event)">
<div class="track playlist" :class="{'playing': list.playIndex == index}"
v-for="(item, index) of list.playList" :key="index" :data-index="index"
:ref="'playList' + index">
<div class="title-and-artist">
<div class="container">
<div class="title">{{index + 1}} : {{item.title}} </div>
<div class="artist">
<span class="artist-in-line">
{{item.artist}}
</span>
</div>
</div>
</div>
<div class="album">
专辑 - {{item.album}}
</div>
<div class="actions" v-show="showLike">
<span class="button-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 30 30" class="svg-icon"
style="display:none;">
<path
d="M15,26c-0.21,0-0.42-0.066-0.597-0.198C13.938,25.456,3,17.243,3,11c0-3.859,3.141-7,7-7c2.358,0,4.062,1.272,5,2.212 C15.938,5.272,17.642,4,20,4c3.859,0,7,3.14,7,7c0,6.243-10.938,14.456-11.403,14.803C15.42,25.934,15.21,26,15,26z"
fill="currentColor" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 30 30" class="svg-icon">
<path
d="M 9.5449219 3 C 5.3895807 3 2 6.3895806 2 10.544922 C 2 14.283156 4.9005496 18.084723 7.6601562 21.119141 C 10.419763 24.153558 13.171875 26.369141 13.171875 26.369141 A 1.0001 1.0001 0 0 0 13.197266 26.388672 C 13.517448 26.630481 13.956962 26.684854 14.369141 26.785156 A 1.0001 1.0001 0 0 0 15 27 A 1.0001 1.0001 0 0 0 15.630859 26.785156 C 16.043038 26.684854 16.482552 26.630481 16.802734 26.388672 A 1.0001 1.0001 0 0 0 16.828125 26.369141 C 16.828125 26.369141 19.580237 24.153558 22.339844 21.119141 C 25.099451 18.084722 28 14.283156 28 10.544922 C 28 6.3895806 24.610419 3 20.455078 3 C 17.450232 3 15.833405 4.5910542 15 5.5664062 C 14.166595 4.5910543 12.549768 3 9.5449219 3 z M 9.5449219 5 C 12.372924 5 14.069642 7.4290597 14.126953 7.5117188 A 1.0001 1.0001 0 0 0 14.910156 8.0078125 A 1.0001 1.0001 0 0 0 15.003906 8.0117188 A 1.0001 1.0001 0 0 0 15.019531 8.0117188 A 1.0001 1.0001 0 0 0 15.042969 8.0097656 A 1.0001 1.0001 0 0 0 15.119141 8.0039062 A 1.0001 1.0001 0 0 0 15.871094 7.5136719 C 15.925786 7.4347249 17.624838 5 20.455078 5 C 23.529737 5 26 7.4702629 26 10.544922 C 26 13.147688 23.499768 16.870104 20.859375 19.773438 C 18.227966 22.666891 15.607768 24.780451 15.589844 24.794922 C 15.414236 24.925626 15.219097 25 15 25 C 14.780903 25 14.585764 24.925626 14.410156 24.794922 C 14.392232 24.780451 11.772034 22.66689 9.140625 19.773438 C 6.5002316 16.870105 4 13.147688 4 10.544922 C 4 7.4702629 6.470263 5 9.5449219 5 z"
fill="currentColor" />
</svg>
</span>
</div>
<div class="time" title="时长">{{ typeMmss(new Date(item.dt - 0)) }}</div>
</div>
</div>
</div>
<!-- 查看歌单详细列表 -->
<div class="next-tracks" v-if="playlistCurrentPage">
<h1>歌单详情: </h1>
<div class="track-list" style="overflow-y: scroll; height: calc(100vh - 160px);"
@dblclick="playMusic($event)">
<div class="track playlist" :class="{'playing': list.playIndex == index}"
v-for="(item, index) of list.playlistCurrent" :key="index" :data-index="index"
:ref="'playlistCurrent' + index">
<div class="title-and-artist">
<div class="container">
<div class="title">{{index + 1}} : {{item.title}} </div>
<div class="artist">
<span class="artist-in-line">
{{item.artist}}
</span>
</div>
</div>
</div>
<div class="album">
专辑 - {{item.album}}
</div>
<div class="actions" v-show="showLike">
<span class="button-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 30 30" class="svg-icon"
style="display:none;">
<path
d="M15,26c-0.21,0-0.42-0.066-0.597-0.198C13.938,25.456,3,17.243,3,11c0-3.859,3.141-7,7-7c2.358,0,4.062,1.272,5,2.212 C15.938,5.272,17.642,4,20,4c3.859,0,7,3.14,7,7c0,6.243-10.938,14.456-11.403,14.803C15.42,25.934,15.21,26,15,26z"
fill="currentColor" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 30 30" class="svg-icon">
<path
d="M 9.5449219 3 C 5.3895807 3 2 6.3895806 2 10.544922 C 2 14.283156 4.9005496 18.084723 7.6601562 21.119141 C 10.419763 24.153558 13.171875 26.369141 13.171875 26.369141 A 1.0001 1.0001 0 0 0 13.197266 26.388672 C 13.517448 26.630481 13.956962 26.684854 14.369141 26.785156 A 1.0001 1.0001 0 0 0 15 27 A 1.0001 1.0001 0 0 0 15.630859 26.785156 C 16.043038 26.684854 16.482552 26.630481 16.802734 26.388672 A 1.0001 1.0001 0 0 0 16.828125 26.369141 C 16.828125 26.369141 19.580237 24.153558 22.339844 21.119141 C 25.099451 18.084722 28 14.283156 28 10.544922 C 28 6.3895806 24.610419 3 20.455078 3 C 17.450232 3 15.833405 4.5910542 15 5.5664062 C 14.166595 4.5910543 12.549768 3 9.5449219 3 z M 9.5449219 5 C 12.372924 5 14.069642 7.4290597 14.126953 7.5117188 A 1.0001 1.0001 0 0 0 14.910156 8.0078125 A 1.0001 1.0001 0 0 0 15.003906 8.0117188 A 1.0001 1.0001 0 0 0 15.019531 8.0117188 A 1.0001 1.0001 0 0 0 15.042969 8.0097656 A 1.0001 1.0001 0 0 0 15.119141 8.0039062 A 1.0001 1.0001 0 0 0 15.871094 7.5136719 C 15.925786 7.4347249 17.624838 5 20.455078 5 C 23.529737 5 26 7.4702629 26 10.544922 C 26 13.147688 23.499768 16.870104 20.859375 19.773438 C 18.227966 22.666891 15.607768 24.780451 15.589844 24.794922 C 15.414236 24.925626 15.219097 25 15 25 C 14.780903 25 14.585764 24.925626 14.410156 24.794922 C 14.392232 24.780451 11.772034 22.66689 9.140625 19.773438 C 6.5002316 16.870105 4 13.147688 4 10.544922 C 4 7.4702629 6.470263 5 9.5449219 5 z"
fill="currentColor" />
</svg>
</span>
</div>
<div class="time" title="时长">{{ typeMmss(new Date(item.dt - 0)) }}</div>
</div>
</div>
</div>
</template>
</div>
</body>
<script>
// 打开的网页ip
let hostname = '192.168.12.224';
// 打开的webSocket通讯端口
let port = 8080
// 网易云用户uid
let netEaseUid = 31097058
// 默认标题
let defaultTitle = 'R1音箱控制'
// axios请求的baseurl
let baseURL = 'https://music-api.heheda.top'
function apis (a, b, c, d) {
return {
//获取音箱状态
info: { type: 'get_info' },
//打开响度开关
loudnessEnable: { type: 'set_loudness_enable', enable: a },
//打开低音开关
bassEnable: { type: 'set_bass_enable', enable: a },
//打开EQ开关
eqEnable: { type: 'set_eq_enable', enable: a },
//获取音效数据
eqConfig: { type: 'get_eq_config' },
//设置音量
vol: { type: 'set_vol', vol: a },
//设置响度
loudnessGain: { type: 'set_loudness_gain', gain: a },
//设置低音
bassStrength: { type: 'set_bass_strength', strength: a },
//设置音效
eqBandlevel: { type: 'set_eq_bandlevel', band: a, level: b },
//选择音效模式
eqPreset: { type: 'set_eq_preset', preset: a },
//蓝牙控制; 打开: ('打开蓝牙', 1) ; 关闭:('关闭蓝牙', 2)
bluetooth: { type: 'send_message', type_id: a, what: 64, arg1: b, arg2: -1 },
//氛围灯; 打开:('打开氛围灯', 1);关闭:('关闭氛围灯', 0);
musicLight: { type: 'send_message', type_id: a, what: 4, arg1: 64, arg2: b },
//设置氛围灯亮度
musciLightLuma: { type: 'send_message', type_id: '设置氛围灯亮度', what: 4, arg1: 65, arg2: a },
//设置颜色渐变速度
musicLightChroma: { type: 'send_message', type_id: '设置颜色渐变速度', what: 4, arg1: 66, arg2: a },
//氛围效果
musicLightMode: { type: 'send_message', type_id: a, what: 4, arg1: 68, arg2: b },
//截图 开始: 'start_screencap' ;停止: 'stop_screencap'
screen: { type: a },
//发送按键事件/屏幕滑动/屏幕点击
keyEvent: { type: 'input', input: a },
//执行shell命令
shell: { type_id: a, type: 'shell', shell: b },
//打开网络连接
netConfig: { type: 'send_message', what: 262144, arg1: 1 },
//播放
play: { type: 'send_message', what: 4, arg1: 3, arg2: -1, obj: true },
//暂停
pause: { type: 'send_message', what: 4, arg1: 2, arg2: -1, obj: true },
//上一首
prev: { type: 'prev' },
//下一首
next: { type: 'next' },
//设置播放模式
setPlayMode: { type: 'set_play_mode', mode: a },
//获取播放列表
list: { type: 'list' },
//播放指定歌曲
playMusic: { type: 'play', type_id: '播放指定歌曲', index: a },
}
}
function bandaoApis (a, b, c, d) {
return {
//收藏
collect: { type: 'send_message', what: 65536, arg1: 0, arg2: 6 },
//取消收藏
cancelCollect: { type: 'send_message', what: 65536, arg1: 0, arg2: 7 },
// 播放
playMenu: { type: 'sendMsg', what: 4, arg1: 1, arg2: -1, dataType: 'String', data: a },
}
}
// css
let myStyle = `
`
function getEl (str) {
return document.querySelectorAll(str);
}
function DelEl (el) {
el.parentNode.removeChild(el);
}
// 加载ui文件
function loadCss (url) {
let link = document.createElement('link');
link.rel = 'stylesheet';
link.href = url;
document.getElementsByTagName('head')[0].appendChild(link);
}
function addCss (style) {
let styleNode = document.createElement('style');
styleNode.type = "text/css";
styleNode.innerHTML = style;
document.getElementsByTagName('head')[0].appendChild(styleNode);
}
function addMeta () {
let M = document.createElement('meta');
M.content = 'width=device-width,initial-scale=1,user-scalable=0,maximum-scale=1,viewport-fit=cover';
M.name = 'viewport';
document.getElementsByTagName('head')[0].appendChild(M);
}
// 拓展date
Date.prototype.Format = function (fmt) {
let o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
}
if (/(y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length))
}
for (let k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)))
}
}
return fmt
}
Date.prototype.totalDay = function (fmt) { //把时间戳转为距离今天的时间
let d = 24 * 60 * 60 * 1000; // 一天毫秒数 24 * 60 * 60 * 1000
let h = 60 * 60 * 1000; // 一小时毫秒数 60 * 60 * 1000
let m = 60 * 1000; // 一分钟毫秒数 60 * 1000
let t = this.getTime()
let o = {
"d+": parseInt(t / d), //日
"h+": parseInt(t % d / h), //小时
"m+": parseInt(t % h / m), //分
"s+": parseInt(t % m / 1000), //秒
}
for (let k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length <= 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)))
}
}
return fmt
}
function disableScrolling () {
document.documentElement.style.setProperty('--html-overflow-y', 'hidden');
}
function enableScrolling () {
document.documentElement.style.setProperty('--html-overflow-y', 'overlay');
}
//`````````````````jsonp`````````````````````````````
var count = 0;
function noop () { }
function jsonp (url, opts, fn) {
if ('function' == typeof opts) {
fn = opts;
opts = {};
}
if (!opts) opts = {};
var prefix = opts.prefix || '__jp';
// use the callback name that was passed if one was provided.
// otherwise generate a unique name by incrementing our counter.
var id = opts.name || (prefix + (count++));
var param = opts.param || 'callback';
var timeout = null != opts.timeout ? opts.timeout : 60000;
var enc = encodeURIComponent;
var target = document.getElementsByTagName('script')[0] || document.head;
var script;
var timer;
if (timeout) {
timer = setTimeout(function () {
cleanup();
if (fn) fn(new Error('Timeout'));
}, timeout);
}
function cleanup () {
if (script.parentNode) script.parentNode.removeChild(script);
window[id] = noop;
if (timer) clearTimeout(timer);
}
function cancel () {
if (window[id]) {
cleanup();
}
}
window[id] = function (data) {
cleanup();
if (fn) fn(null, data);
};
// add qs component
url += (~url.indexOf('?') ? '&' : '?') + param + '=' + enc(id);
url = url.replace('?&', '?');
// create script
script = document.createElement('script');
script.src = url;
target.parentNode.insertBefore(script, target);
return cancel;
}
//``````````````````````````````````````````````
function vueBox () {
let string = `
<div id="app">
</div>
`
let vueBox = document.createElement('div');
vueBox.innerHTML = string
// getEl('body')[0].appendChild(vueBox);
newVue()
}
function newVue () {
new Vue({
el: '#app',
data: function () {
return {
Socket: null,
drawer: false,
activeMenu: -1,
activeList: 1001,
setIntervalWesocketPush: null,
getSocketData: null,
deviceInfo: { //设置信息
device_state: 0, // 蓝牙打开:3,
device_udid: "",
music_light_chroma: 0,
music_light_enable: false,
music_light_luma: 0,
music_light_mode: 0,
music_source: "kuwo",
music_info: null
/* {
artist: "",
duration: 0,
id: "",
itemtype: 0,
position: 0,
state: 0,
timestamp: "",
title: "",
}
*/
,
play_mode: 1,
play_state: false,
play_type: 0,
ttsModelType: "SWEET",
u_ver: 1000,
ver: 1822,
vol: 2,
},
soundEffect: { // 音效
loudness: { //响度
Current_Gain: 0,
Loudness_Enable: false,
sound_effects_loudness_enable: false
},
bass: { //低音增强
Current_Strength: 0,
Bass_Enable: false,
sound_effects_bass_enable: false
},
eq: { //音效调节
Current_Preset: 0,
Eq_Enable: false,
sound_effects_eq_enable: false,
Bands: {
list: [
{ Band: 0, BandLevel: 300, Frequency: 60000 },
{ Band: 1, BandLevel: 0, Frequency: 230000 },
{ Band: 2, BandLevel: 0, Frequency: 910000 },
{ Band: 3, BandLevel: 0, Frequency: 3600000 },
{ Band: 4, BandLevel: 300, Frequency: 14000000 }
],
maxBandLevel: 1500,
minBandLevel: -1500
},
Preset_list: [
{ Preset: 0, Name: "Normal" },
{ Preset: 1, Name: "Classical" },
{ Preset: 2, Name: "Dance" },
{ Preset: 3, Name: "Flat" },
{ Preset: 4, Name: "Folk" },
{ Preset: 5, Name: "Heavy Metal" },
{ Preset: 6, Name: "Hip Hop" },
{ Preset: 7, Name: "Jazz" },
{ Preset: 8, Name: "Pop" },
{ Preset: 9, Name: "Rock" }
]
}
},
eqBandListName: ["低频", "中低", "中频", "中高", "高频"],
eqPresetListName: {
"Normal": "普通",
"Classical": "古典",
"Dance": "舞曲",
"Flat": "原声",
"Folk": "民谣",
"Heavy Metal": "重金属",
"Hip Hop": "嘻哈",
"Jazz": "爵士",
"Pop": "流行",
"Rock": "摇滚"
},
myEqMode: [{
Name: '电音',
BandList: [
{ Band: 0, BandLevel: 900 },
{ Band: 1, BandLevel: 1300 },
{ Band: 2, BandLevel: 1100 },
{ Band: 3, BandLevel: 900 },
{ Band: 4, BandLevel: 1400 }
]
}],
myEqMode2: [],
eqModeName: '',
//氛围效果
musicLightModes: ['切换官方氛围效果', '切换七彩旋转效果', '切换七彩氛围效果', '切换七彩旋转效果1'],
screen: null,
screencap: '',
reader: null,
img: null,
startx: -1,
starty: -1,
dialogVisible: false,
restartdialogVisible: false, //重启软件界面是否显示
listPackages: [],
listPackagesIndex: 'com.phicomm.speaker.device',
shellVisible: false,
shellStr: '',
isDelEqMode: false, //是否为删除音效模式状态
systemInfo: {
MemTotal: 0,
MemFree: 0,
Buffers: 0,
Cached: 0,
SwapCached: 0,
Active: 0,
Inactive: 0,
"Active(anon)": 0,
"Inactive(anon)": 0,
"Active(file)": 0,
"Inactive(file)": 0,
Unevictable: 0,
Mlocked: 0,
HighTotal: 0,
HighFree: 0,
LowTotal: 0,
LowFree: 0,
SwapTotal: 0,
SwapFree: 0,
Dirty: 0,
Writeback: 0,
AnonPages: 0,
Mapped: 0,
Shmem: 0,
Slab: 0,
SReclaimable: 0,
SUnreclaim: 0,
KernelStack: 0,
PageTables: 0,
NFS_Unstable: 0,
Bounce: 0,
WritebackTmp: 0,
CommitLimit: 0,
Committed_AS: 0,
VmallocTotal: 0,
VmallocUsed: 0,
VmallocChunk: 0,
intr: '',
ctxt: '',
btime: '',
processes: '',
procs_running: '',
procs_blocked: '',
softirq: '',
incremental: 0,
},
timerSystemInfo: null,// 更新系统信息定时器
playModes: ['随机播放', '顺序播放', '单曲循环'],
list: {
playIndex: 0,
playMode: 0,
playState: 0,
playList: [
/*
{
album: "", 专辑
artist: "", 歌手
itemId: "",
itemType: 0,
title: "", 歌名
url: "", 歌曲mp3地址
dt: "", 歌曲时长(毫秒)
}
*/
]
},
songInfo: {
/*
artist: "郑鱼"
id: "MUSIC_180216407"
link: "http://www.kuwo.cn/yinyue/180216407"
lrc: "[00:02.29]怎叹 - 郑鱼\r\n[00:04.58]词:Listen Dream\r\n[00:06.87]"
name: "怎叹"
*/
},
nextTracksPage: false,
// 现在查看歌单里的歌曲
playlistCurrent: [],
playlistCurrentPage: false,
isMouseWheel: false,
isMouseWheelTimer: null,
showLike: false,
theme: 'light',
netEaseBangMenu: [],
myMusicMenu: [],
netEaseLId: null, // 网易云点播的歌单id
currentMusicProgress: 0, //进度条变化记录
cmp: 0, // 音乐进度条拖动/点击到的进度位置
collectList: [{ // 收藏的网易云歌单
name: '本地收藏歌单',
list: []
}],
delCollectListMode: false, //删除收藏模式
isLoading: { // 是否正在加载
playMusicNavmenu: false,
}
}
},
mounted () {
this.initSocket();
this.screenInit()
this.updateEqMode()
this.setPageTitle(defaultTitle)
this.theme = localStorage.getItem('theme') || 'light'
this.collectList = JSON.parse(localStorage.getItem('collectList')) || this.collectList
//设置默认启动页面
this.handleChangeMenu(0)
},
destroyed () {
//移除监听器
window.removeEventListener('onmessageWS', this.getSocketData);
},
methods: {
handleChangeMenu (index) {
this.drawer = false
if (index == 100) {
this.toggleTheme()
return
}
this.nextTracksPage = false
this.activeMenu = index
this.stopScreen()
clearInterval(this.timerSystemInfo)
if (index == 0) {
this.handleChangeList(this.activeList)
} else if (index == 1) { // 1为屏幕控制
this.startScreen()
} else if (index == 2) { //2为音效控制
this.soundEffectInit()
} else if (index == 3) { //3 音箱控制
this.getSystemInfo()
this.timerSystemInfo = setInterval(e => {
this.getSystemInfo()
}, 3000)
}
},
handleChangeList (index) {
this.activeList = index
if (index == 1001) {
this.getNetEaseBangMenu()
} else if (index == 1002) {
this.getMyMusicMenu()
}
},
setPageTitle (str) {
document.title = str
},
initSocket () {
this.createSocket()
// 创建接收消息函数
this.getSocketData = e => {
const data = e && e.detail.data
if ((typeof data) == 'string') {
let jData = JSON.parse(data)
if (jData.code != 200) {
// console.log('code : ' + jData.code)
console.error(jData)
return;
} else if (jData.type == 'get_info') {
//更新设备信息
this.deviceInfo = JSON.parse(jData.data)
} else if (jData.type == 'get_eq_config') {
// console.log('get_eq_config')
this.soundEffect = JSON.parse(jData.data)
} else if (jData.type == 'send_message') {
} else if (jData.type == 'stop_screencap' || jData.type == 'start_screencap') {
} else if (jData.type == 'input') {
} else if (jData.type == 'shell' && jData.type_id == 'query') {
this.setSystemInfo(jData.data)
} else if (jData.type == 'shell' && jData.type_id == 'packages') {
this.setListPackages(jData.data)
} else if (jData.type == 'shell' && jData.type_id == 'myshell') {
let time = new Date().Format('hh:mm:ss')
console.group('shell执行结果' + time)
console.dir(jData)
console.log('%c data : \n ' + jData.data + ' ', 'background:#000;color:#fff')
console.groupEnd('shell执行结果' + time)
} else if (jData.type == 'list') {
let l = JSON.parse(jData.data)
// console.log(l)
l.playList.map(el => {
let [_id, _dt] = el.itemId.split(',')
el.itemId = _id
el.dt = _dt
});
this.list = l
}
else {
// console.log(jData)
// console.log(JSON.parse(jData.data))
}
} else if ((typeof data) == 'object') {
this.updateScreencap(data)
} else {
// console.log(data)
}
}
//注册监听事件
window.addEventListener('onmessageWS', this.getSocketData)
},
createSocket () {
this.Socket && this.Socket.close()
if (!this.Socket) {
console.log('建立websocket连接')
this.Socket = new WebSocket('ws://' + hostname + ':' + port);
//发送心跳
this.Socket.onopen = this.onopenWS
//接收消息
this.Socket.onmessage = this.onmessageWS
//连接失败重连
this.Socket.onerror = this.onerrorWS
//断开重连
this.Socket.onclose = this.oncloseWS
} else {
console.log('websocket已连接')
}
},
onopenWS (e) {
// 发送心跳
clearInterval(this.setIntervalWesocketPush)
let data = null
data = JSON.stringify(apis()['info'])
this.Socket.send(data);
this.setIntervalWesocketPush = setInterval(() => {
this.Socket.send(data);
}, 950)
},
onmessageWS (e) {
window.dispatchEvent(new CustomEvent('onmessageWS', {
detail: {
data: e.data
}
}))
},
// 断开重连
onerrorWS (e) {
this.Socket.close()
clearInterval(this.setIntervalWesocketPush)
console.log(' ,连接失败重连中')
if (this.Socket.readyState !== 3) {
this.Socket = null
this.createSocket()
}
},
oncloseWS (e) {
console.log('websocket 断开: ' + e.code + ' ' + e.reason + ' ' + e.wasClean)
clearInterval(this.setIntervalWesocketPush)
console.log('websocket已断开....正在尝试重连')
if (this.Socket.readyState !== 2) {
this.Socket = null
this.createSocket()
}
},
//发送数据但连接未建立时进行处理等待重发
//message 需要发送的数据
connecting (message) {
let timeout = setTimeout(() => {
if (this.Socket.readyState === 0) {
this.connecting(message)
} else {
this.Socket.send(JSON.stringify(message))
}
clearTimeout(timeout)
}, 1000)
},
sendWSPush (message) {
if (this.Socket !== null && this.Socket.readyState === 3) {
this.Socket.close()
this.createSocket()
} else if (this.Socket.readyState === 1) {
this.Socket.send(JSON.stringify(message))
} else if (this.Socket.readyState === 0) {
this.connecting(message)
}
},
//打开音效开关,获取音效数据
soundEffectInit () {
//获取音效数据
this.sendWSPush(apis()['eqConfig']);
},
//响度开关
btnLoudness (val) {
this.sendWSPush(apis(val)['loudnessEnable'])
this.soundEffectInit()
},
btnBass (val) {
this.sendWSPush(apis(val)['bassEnable'])
this.soundEffectInit()
},
btnEq (val) {
this.sendWSPush(apis(val)['eqEnable'])
this.soundEffectInit()
},
//设置音量
setVolume (vol) {
if (vol != 0) {
vol = vol || this.deviceInfo.vol
}
this.sendWSPush(apis(vol)['vol']);
this.deviceInfo.vol = vol
},
//设置响度
setLoudness () {
this.sendWSPush(apis(this.soundEffect.loudness.Current_Gain)['loudnessGain'])
},
//设置低音
setBass () {
this.sendWSPush(apis(this.soundEffect.bass.Current_Strength)['bassStrength'])
},
//设置音效
setEq (index, level = null) {
this.sendWSPush(apis(index, level || this.soundEffect.eq.Bands.list[index].BandLevel)['eqBandlevel'])
},
//选择音效模式
setEqMode (index) {
// console.log(index)
this.sendWSPush(apis(this.soundEffect.eq.Preset_list[index].Preset)['eqPreset'])
this.soundEffectInit()
},
// 设置自定义音效模式
async setMyEqMode (index) {
for (let item of this.myEqMode[index].BandList) {
await this.setEq(item.Band, item.BandLevel)
}
await this.soundEffectInit()
},
//用户定义的模式
async setMyEqMode2 (index) {
for (let item of this.myEqMode2[index].BandList) {
await this.setEq(item.Band, item.BandLevel)
}
await this.soundEffectInit()
},
BluetoothControl (val) {
if (val) {
this.BluetoothOpen()
} else {
this.BluetoothClose()
}
},
BluetoothOpen () {
this.sendWSPush(apis('打开蓝牙', 1)['bluetooth'])
},
BluetoothClose () {
this.sendWSPush(apis('关闭蓝牙', 2)['bluetooth'])
},
musicLightControl (val) {
if (val) {
this.musicLightOpen()
} else {
this.musicLightClose()
}
},
musicLightOpen () {
this.sendWSPush(apis('打开氛围灯', 1)['musicLight'])
},
musicLightClose () {
this.sendWSPush(apis('打开氛围灯', 0)['musicLight']);
},
musciLightLuma (val) {
this.sendWSPush(apis(val)['musciLightLuma']);
},
musicLightChroma (val) {
this.sendWSPush(apis(val)['musicLightChroma']);
},
//氛围效果
musicLightMode (val) {
this.sendWSPush(apis(this.musicLightModes[val], val)['musicLightMode'])
},
screenInit () {
if (this.screen == null) {
this.screen = document.getElementById('screen');
}
this.screen.addEventListener('click', this.screenOnclick)
this.screen.addEventListener("touchstart", this.handleTouchEvent, false);
this.screen.addEventListener("touchend", this.handleTouchEvent, false);
this.screen.addEventListener("touchmove", this.handleTouchEvent, false);
this.screen.addEventListener("mousewheel", this.screenOnmousewheel, false);
this.screen.addEventListener("contextmenu", this.screenOncontextmenu, false);
},
// 开始截图
startScreen () {
this.sendWSPush(apis('start_screencap')['screen']);
document.onkeydown = function (data) {
if (data.keyCode == 13) {
this.sendKeyevent(23);
return false;
} else if (data.keyCode == 37) {
this.sendKeyevent(21);
return false;
} else if (data.keyCode == 38) {
this.sendKeyevent(19);
return false;
} else if (data.keyCode == 39) {
this.sendKeyevent(22);
return false;
} else if (data.keyCode == 40) {
this.sendKeyevent(20);
return false;
}
};
},
//停止截图
stopScreen () {
this.sendWSPush(apis('stop_screencap')['screen']);
document.onkeydown = function () { };
document.onkeyup = function () { };
},
//更新截图
updateScreencap (blob) {
//this.screencap = host + '/screencap?t=' + new Date().getTime();
if (this.reader == null) {
this.reader = new FileReader();
this.reader.onload = (e) => {
this.screencap = e.target.result
// console.log(e.target.result)
}
}
this.reader.readAsDataURL(blob)
},
//发送按键事件
sendKeyevent (key) {
this.sendWSPush(apis('keyevent ' + key)['keyEvent'])
},
handleTouchEvent (e) {
let that = this.screen
let cw = that.clientWidth
let ch = that.clientHeight
let nw = that.naturalWidth
let nh = that.naturalHeight
let x = e.changedTouches[0].clientX;
let y = e.changedTouches[0].clientY;
x = parseInt((x / cw) * nw);
y = parseInt((y / ch) * nh);
if (e.type == 'touchstart') {
this.startx = x;
this.starty = y;
} else if (e.type == 'touchend') {
if (this.startx == -1 || this.starty == -1) {
return
}
if (y - this.starty < 50 && x - this.startx < 50) {
if (this.starty - y < 50 && this.startx - x < 50) {
this.startx = -1;
this.starty = -1;
return;
}
}
this.sendWSPush(apis('swipe ' + this.startx + ' ' + this.starty + ' ' + x + ' ' + y)['keyEvent'])
this.startx = -1;
this.starty = -1;
} else if (e.type == 'touchmove') {
e.preventDefault(); //阻止滚动
}
},
screenOnclick (e) {
let that = this.screen
let cw = that.clientWidth
let ch = that.clientHeight
let nw = that.naturalWidth
let nh = that.naturalHeight
this.sendWSPush(apis('tap ' + parseInt((e.offsetX / cw) * nw) + ' ' + parseInt((e.offsetY / ch) * nh))['keyEvent'])
},
screenOnmousewheel (e) {
e.preventDefault();
let that = this.screen
let cw = that.clientWidth
let ch = that.clientHeight
let nw = that.naturalWidth
let nh = that.naturalHeight
let x = e.offsetX;
let y = e.offsetY;
let new_y = 0
let mousewheel_interval = -1
x = (x / cw) * nw;
y = (y / ch) * nh;
if (e.deltaY > -1) {
new_y = y - 100;
} else {
new_y = y + 100;
}
if (new Date().valueOf() - mousewheel_interval > 0) {
mousewheel_interval = new Date().valueOf() + 100;
this.sendWSPush(apis('swipe ' + x + ' ' + y + ' ' + x + ' ' + new_y)['keyEvent'])
}
},
screenOncontextmenu (e) {
e.preventDefault();
this.sendKeyevent(4)
},
addEqMode () {
if (this.eqModeName.length < 1) {
this.notification('', '没有输入名字', 'error')
return
} else {
this.dialogVisible = false;
let band = this.soundEffect.eq.Bands.list
let obj = {
Name: this.eqModeName,
BandList: [
{ Band: 0, BandLevel: band[0].BandLevel },
{ Band: 1, BandLevel: band[1].BandLevel },
{ Band: 2, BandLevel: band[2].BandLevel },
{ Band: 3, BandLevel: band[3].BandLevel },
{ Band: 4, BandLevel: band[4].BandLevel }
]
}
this.eqlsControl('set', [obj])
this.eqModeName = ''
}
},
updateEqMode () {
let modes = this.eqlsControl('get') || []
this.myEqMode2 = modes
},
delEqMode (item) {
console.log(item)
if (item.Name == '电音') {
return
}
let old = this.eqlsControl('get')
let delIndex = old.findIndex(i => i.Name == item.Name)
if (delIndex > -1) {
old.splice(delIndex, 1)
}
this.eqlsControl('del')
this.eqlsControl('set', old)
},
eqlsControl (type = 'set', val) {
let key = 'myEqMode'
if (type == 'set') {
let old = JSON.parse(window.localStorage.getItem(key)) || []
let delIndex = old.findIndex(i => i.Name == val[0].Name)
if (delIndex > -1) {
old.splice(delIndex, 1)
}
window.localStorage.setItem(key, JSON.stringify([...old, ...val]))
this.myEqMode2 = [...old, ...val]
} else if (type == 'get') {
return JSON.parse(window.localStorage.getItem(key)) || ''
} else if (type == 'del') {
window.localStorage.removeItem(key)
this.myEqMode2 = []
} else {
this.notification('错误', 'type 设置错误', 'error')
}
},
//通知
notification (title = '测试', msg = '没有内容', type = 'error') {
this.$notify({
title: title,
message: msg,
type: type,
duration: 2000
});
},
//灯开关
light (val = false) {
let shell = val ? 'lights_test set 7fffff8000 ffffff' : 'lights_test set 7fffff8000 0'
this.sendWSPush(apis('开灯', shell)['shell'])
},
//打开网络连接
netConfig () {
this.sendWSPush(apis()['netConfig'])
},
//执行自定义shell命令
executeShell () {
if (this.shellStr) {
this.sendWSPush(apis('myshell', this.shellStr)['shell'])
} else {
console.log('输入信息为空')
}
},
//重启app
restartApp (app, type) {
app = app || this.listPackagesIndex
this.stopApp(app)
setTimeout(() => {
this.startApp(app)
}, 3000)
},
stopApp (app) {
app = app || this.listPackagesIndex
let shell = '/system/bin/am force-stop ' + app
this.sendWSPush(apis('停止', shell)['shell'])
this.notification('正在停止app', app, 'success')
},
startApp (app) {
app = app || this.listPackagesIndex
let shell = '/system/bin/am start ' + app + '/.ui.MainActivity'
this.sendWSPush(apis('启动', shell)['shell'])
this.notification('正在启动app', app, 'success')
},
//重启音箱
reboot () {
let shell = 'stop adbd&&start adbd&&adb reboot'
this.sendWSPush(apis('重启音箱', shell)['shell'])
},
getListPackages () {
let shell = '/system/bin/pm list packages'
this.sendWSPush(apis('packages', shell)['shell'])
},
setListPackages (data) {
this.listPackages = []
for (let item of data.split("\r\n")) {
let i = item.split(':')
if (i[1] && i[1] != 'android') {
this.listPackages.push(i[1])
}
}
},
//清除闹钟
clear () {
let shell = '/system/bin/pm clear com.phicomm.speaker.device'
this.sendWSPush(apis('清除', shell)['shell'])
this.restartApp('com.phicomm.speaker.device')
},
// 获取系统信息
getSystemInfo () {
let shell = 'cat /proc/meminfo&&cat /proc/stat&&echo incremental:$(getprop ro.build.version.incremental)'
this.sendWSPush(apis('query', shell)['shell'])
},
// 处理与存储系统信息
setSystemInfo (data) {
for (let item of data.split("\r\n")) {
let i = item.split(':')
// console.log(i[0], this.systemInfo.hasOwnProperty(i[0]))
if (this.systemInfo.hasOwnProperty(i[0])) {
this.systemInfo[i[0]] = parseInt(i[1])
} else {
let index = item.indexOf(' ')
let key = item.substring(index, 0)
if (this.systemInfo.hasOwnProperty(key)) {
if (key == 'btime') {
this.systemInfo[key] = item.substring(index) * 1000
} else {
this.systemInfo[key] = item.substring(index)
}
}
}
}
},
//切换主题色
toggleTheme () {
if (this.theme == 'light') {
this.theme = 'dark'
} else {
this.theme = 'light'
}
localStorage.setItem('theme', this.theme)
},
//音乐播放控制,播放暂停,上一首,下一首
play () {
this.deviceInfo.play_state = true
this.sendWSPush(apis()['play'])
},
pause () {
this.deviceInfo.play_state = false
this.deviceInfo.music_info.state = 2
this.sendWSPush(apis()['pause'])
},
prev () {
this.deviceInfo.play_state = true
this.sendWSPush(apis()['prev'])
this.getSongInfo()
},
next () {
this.deviceInfo.play_state = true
this.sendWSPush(apis()['next'])
},
//把歌曲添加到喜欢
collect () {
this.sendWSPush(bandaoapis()['collect'])
},
//把歌曲从喜欢中移除
cancelCollect () {
this.sendWSPush(bandaoapis()['cancelCollect'])
},
//播放音乐,并且把当前歌曲在页面置中
playMusic (e) {
let targetEl = e.target
let i = 0
while (i < 5) {
i++
if (targetEl.className && targetEl.className.indexOf('track playlist') != -1) {
let index = targetEl.dataset.index
this.sendWSPush(apis(index)['playMusic'])
this.list.playIndex = index
this.scrollIntoCenter(targetEl)
break;
} else {
targetEl = targetEl.parentNode;
// console.log(targetEl)
}
}
},
//静音
mute () {
let volume = this.deviceInfo.vol
if (volume == 0) {
volume = this.getVolume || 2
} else {
localStorage.setItem('volume', volume)
volume = 0
}
this.setVolume(volume)
this.deviceInfo.vol = volume
},
//设置播放模式
setPlayMode (mode) {
// 1: 随机;2: 顺序;3: 单曲
mode = mode || this.deviceInfo.play_mode == 3 ? 1 : this.deviceInfo.play_mode + 1
// console.log(mode, this.deviceInfo.play_mode)
this.deviceInfo.play_mode = mode
// console.log(this.deviceInfo.play_mode)
this.sendWSPush(apis(mode)['setPlayMode'])
},
getList () {
this.sendWSPush(apis()['list'])
},
// 获取单前播放中的音乐信息
getSongInfo () {
let id = this.deviceInfo.music_info.id.split(',')[0]
// console.log(id)
new Promise((res, rej) => {
let DetailPromise = this.getMusicDetail(id)
DetailPromise.then(list => {
// console.log(list)
res(list.itemList[0])
})
}).then(res => {
// artist: "郑鱼"
// id: "MUSIC_180216407"
// link: "http://www.kuwo.cn/yinyue/180216407"
// lrc: "[00:02.29]怎叹 - 郑鱼\r\n[00:04.58]词:Listen Dream\r\n[00:06.87]"
// name: "怎叹"
// pic: "http://img2.kuwo.cn/star/albumcover/500/16/9/3784544836.jpg"
this.songInfo = {
artist: res.artist,
id: res.itemId,
link: '',
name: res.title,
pic: 'http://p4.music.126.net/dbMimdGInV87myZFakgHeA==/109951163176668498.jpg?param=34y34'
}
// console.log(this.songInfo)
})
},
// 通过半岛ws去点播列表歌曲
bandaoWsPlayMenu (list) {
let Socket = new WebSocket('ws://' + hostname + ':' + 9998);
Socket.onopen = () => {
this.notification('成功', '正在点播,请稍等', 'success')
Socket.send(JSON.stringify(bandaoApis(list)['playMenu']))
//不传下面这些就不播放
Socket.send(JSON.stringify({ type: 'sendMsg', what: 4, arg1: 11, arg2: -1, dataType: 'int', data: 0 }))
Socket.send(JSON.stringify({ type: 'sendMsg', what: 4, arg1: 2, arg2: -1, dataType: null, data: null }))
Socket.send(JSON.stringify({ type: 'sendMsg', what: 4, arg1: 3, arg2: -1, dataType: null, data: null }))
Socket.close()
}
},
//把毫秒转为秒(可大于60)
typeMmss (ss) {
if (ss) {
return new Date(ss).totalDay('mm:ss')
}
return ss
},
//获取网易云榜单
getNetEaseBangMenu () {
if (this.netEaseBangMenu.length > 0) {
return
}
this.isLoading.playMusicNavmenu = true
axios({
method: 'get',
baseURL,
url: '/toplist',
}).then(resp => {
if (resp.status == 200 && resp.data.code == 200) {
let d = resp.data
if (d.list.length) {
let item = {
name: '网易云音乐榜',
list: []
}
for (let i of d.list) {
let _list = {
id: i.id,
intro: i.description,
name: i.name,
pic: i.coverImgUrl,
pub: i.updateFrequency,
}
item.list.push(_list)
}
this.netEaseBangMenu.push(item)
// console.log(this.netEaseBangMenu)
}
}
}).finally(() => {
this.isLoading.playMusicNavmenu = false
})
},
getListDetail (id) { //获取歌单详细信息
return axios({
method: 'get',
baseURL,
url: '/playlist/detail',
params: {
id: id,
}
}).then(res => {
return res
})
},
// 获取歌曲详情,调用此接口 , 传入音乐 id 字符串(支持多个 id, 用 , 隔开), 可获得歌曲详情(ids=347230,347231)
getMusicDetail (ids) {
return axios({
method: 'get',
baseURL,
url: '/song/detail',
params: {
ids: ids,
}
}).then(res => {
// console.log(res)
let songs = res.data.songs
let list = {
index: 0,
asrResult: null,
pageIndex: 1,
totalPage: 1,
itemList: [],
}
for (let i of songs) {
let item = {
itemType: 0,
title: i.name,
url: `http://music.163.com/song/media/outer/url?id=${i.id}.mp3`,
itemId: `${i.id},${i.dt}`,
album: i.al.name,
artist: i.ar[0].name,
duration: i.dt, //传过去没反应,只能用id传过去了
}
list.itemList.push(item)
}
// console.log(list)
return list
})
},
// 格式化歌单id
formatTrackIds (trackIds) {
/**
* trackIds[{
alg: null
at: 1685491973418
f: null
id: 2049512697
lr: 1
ratio: 345
rcmdReason: ""
sc: null
sr: null
t: 0
uid: 1
v: 3
* }]
*/
let ids = ''
for (let i of trackIds) {
ids += (',' + i.id)
}
return ids.slice(1)
},
// 准备播放歌单
goToPlayList (id) {
// console.log(id)
this.getListDetail(id).then(res => {
return this.formatTrackIds(res.data.playlist.trackIds)
}).then(ids => {
return this.getMusicDetail(ids)
}).then(res => {
return this.bandaoWsPlayMenu(res)
})
},
// 准备播放单曲
goToPlay () { },
// 根据用户uid 获取用户歌单
getMyMusicMenu (refresh = false) {
if (!(netEaseUid - 0 > 0)) {
return
}
// 避免除了手动刷新以外,进行了错误刷新
if (refresh) { } else if (this.myMusicMenu.length > 0) {
return
}
this.isLoading.playMusicNavmenu = true
axios({
method: 'get',
baseURL,
url: '/user/playlist',
params: {
uid: netEaseUid,
}
}).then(res => {
if (res.status == 200 && res.data.code == 200) {
let playlist = res.data.playlist
if (playlist.length > 0) {
// 重置
this.myMusicMenu = []
let item = {
name: '我的歌单',
list: []
}
for (let i of playlist) {
if (i.trackCount > 0) {
let _list = {
id: i.id,
intro: i.description,
name: i.name,
pic: i.coverImgUrl,
pub: i.updateFrequency,
}
item.list.push(_list)
}
}
this.myMusicMenu.push(item)
}
}
}).finally(() => {
this.isLoading.playMusicNavmenu = false
})
},
// 刷新我的歌单
refreshMyMenu () {
if (!(netEaseUid - 0 > 0)) {
return
}
this.getMyMusicMenu(true)
},
// 收藏网易云歌单
collectMusicList () {
this.getListDetail(this.netEaseLId).then(res => {
this.setCollectMusicList(res.data.playlist)
})
},
setCollectMusicList (list) {
this.delCollectMusicList(list.id)
let _list = {
id: list.id,
intro: list.description,
name: list.name,
pic: list.coverImgUrl,
pub: list.updateFrequency,
}
this.collectList[0].list.push(_list)
},
delCollectMusicList (id) {
let l = this.collectList[0].list
let n = []
for (let i of l) {
if (i.id != id) {
n.push(i)
}
}
this.collectList[0].list = n
},
scrollIntoCenter (el) {
if (!el) {
console.log('需要滚动的元素不存在')
return
}
el.scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'center'
})
}
},
computed: {
Bluetooth () {
if (this.deviceInfo.device_state == 3) {
return true
} else {
return false
}
},
isPlay () {
let di = this.deviceInfo
let result = di.play_state || (di.music_info && di.music_info.state != 2)
return result
},
getVolume () {
return localStorage.getItem('volume')
},
},
watch: {
'deviceInfo.music_info.id': {
handler (val, old) {
if (val) {
this.getList()
this.getSongInfo()
let info = this.deviceInfo.music_info
this.setPageTitle('' + info.title + '_' + info.artist)
} else {
this.setPageTitle(defaultTitle)
}
},
immediate: true
},
nextTracksPage (val, old) {
// console.log(val)
if (val) {
this.$nextTick(e => {
this.scrollIntoCenter(this.$refs['playList' + this.list.playIndex][0])
})
}
},
'list.playIndex': {
handler (val, old) {
if (this.nextTracksPage) {
this.scrollIntoCenter(this.$refs['playList' + this.list.playIndex][0])
}
},
},
currentMusicProgress (val, old) {
this.cmp = old
},
'collectList': {
handler (val, old) {
localStorage.setItem('collectList', JSON.stringify(this.collectList))
},
deep: true,
},
}
})
}
vueBox()
addCss(myStyle)
/*
let timer = setInterval(function () {
//console.log(getEl('#input')[0])
// 判断页面完成加载与否
if (getEl('body pre')[0] != undefined) {
DelEl(getEl('body pre')[0])
addMeta
vueBox();
loadCss('https://unpkg.com/element-ui/lib/theme-chalk/index.css');
addCss(myStyle)
clearInterval(timer);
}
}, 500);
*/
</script>
</html>
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/amizcmi/tv.git
git@gitee.com:amizcmi/tv.git
amizcmi
tv
tv
master

搜索帮助