仕事のプロジェクトのニーズにより、曲の再生が必要となり、さまざまな資料を参考にして、NetEase Cloud Musicの再生を模倣したインターフェースを作成し、音楽再生機能を完全に実現しました。 フロントエンドでは、vue コンポーネントとオーディオ タグを使用してプレーヤー インターフェイスを実装し、バックエンドでは NetEase Cloud の API を呼び出して対応する曲情報を取得します。 さっそくコードを見てみましょう 曲再生インターフェース (musicPlay.vue) <テンプレート> <div class="メインページ"> <audio :src="songInfo.url" id="music" autoplay="自動再生"></audio> <div クラス="背景フリッター" :style="`背景画像: url(${songInfo.cover})`" </div> <div class="play-mini"> <div class="プログレスバー" @click="handleProgressClick" ref="トラック"> <div クラス="プログレスボックス" :style="{ width: audioProgressPercent }" </div> </div> <div class="songInfo"> <img class="poster" :src="songInfo.cover" alt="" /> <!-- 曲名、歌手名--> <div class="info"> <p style="font-weight: 600; color: #fff;">{{ songInfo.name }}</p> <p style="font-size: 14px; color: #fff">{{ songInfo.artistsName }}</p> </div> </div> <div class="controls"> <!-- 前の曲のヒント--> <Tooltip content="前の曲" theme="light" :delay="1500"> <a href="javascript:;"> <アイコン タイプ="md-skip-backward" @click="戻る" サイズ= "26" 色 = "白" /> </a> </ツールチップ> <!-- 再生一時停止 --> <Tooltip content="再生 一時停止" theme="light" :delay="1500"> <画像 @click="音楽を再生" クラス="ステータス" v-show="!再生中" src="@/assets/play_icon.png" 代替案="" /> <画像 クラス="ステータス" @click="音楽を再生" v-show="再生中" src="@/assets/play-02.png" 代替案="" /> </ツールチップ> <!-- 次の曲のヒント --> <Tooltip content="次の曲" theme="light" :delay="1500"> <a href="javascript:;"> <アイコン タイプ="md-skip-forward" @click="次へ進む" サイズ= "26" 色 = "白" /> </a> </ツールチップ> </div> <div class="右下"> <div class="text-div"></div> <!-- ボリューム --> <a href="javascript:;"> <アイコン :type="ボリュームタイプ" サイズ= "26" 色 = "白" @click="音量変更" /> </a> <div class="text-div"></div> <スライダー スタイル="幅: 80px; z-index: 99999" @on-input="changeVolum" v-model="ボリューム" </スライダー> <div class="text-div"></div> <div class="text-div"></div> <div class="text-div"></div> <!-- 曲の再生タイプ --> <ツールチップ:content="showPlayType" theme="light" :delay="1500"> <a href="javascript:;"> <アイコン :custom="プレイステータス" @click="再生タイプ変更" サイズ="26" 色 = "白" /> </a> </ツールチップ> <div class="text-div"></div> <div class="text-div"></div> <div class="プレイリスト"> <!-- プレイリスト --> <ツールチップコンテンツ="リスト" テーマ="ライト" :delay="1500"> <a href="javascript:;"> <アイコン custom="iconfont icon-bofangqi-xuanji" @click="引き出し = true" サイズ="36" 色 = "白" /> </a> </ツールチップ> </div> </div> </div> <div class="song-cover-lyric"> <div class="ディスクコンテナ"> <div class="poster" ref="回転"> <img :src="songInfo.cover" alt="" /> </div> <div class="song-name">{{ songInfo.name }}</div> <div class="song-artistsName">{{ songInfo.artistsName }}</div> </div> <div class="lyric"> <mscroll ref="歌詞" :color="色" :colorLight="カラーライト" :lineHeight="行の高さ" :paddingTop="パディングトップ" :fontSize="フォントサイズ" :lyricIndex="歌詞インデックス" :lyricsList="歌詞情報" </mスクロール> </div> </div> <引き出し title="プレイリスト" 配置="左" 幅="320" :closeable="false" です v-model="引き出し" > <div class="リストコンテナ"> <div クラス="songInfo" v-for="(item, index) in songList" :key="インデックス" @click="PlayListMusic(インデックス)" > <img :src="item.cover" alt="" /> <div class="info"> <div class="name">{{ item.name }}</div> <div class="歌手">{{ item.アーティスト名 }}</div> </div> </div> </div> </引き出し> </div> </テンプレート> <スクリプト> 「../../publicMethod/publicMethods」から { showMessage } をインポートします。 「./lyricScroll.vue」からMscrollをインポートします。 「../../utils/timeConversion」からcommonJsをインポートします。 「axios」からaxiosをインポートします。 エクスポートデフォルト{ データ() { 戻る { volumeNum: 80, //保存されたボリューム volumeStatus: true, //ボリュームアイコンの変更 volumeType: "md-volume-up", //ボリュームアイコン playStatus: "iconfont icon-xunhuanbofang", //再生タイプアイコン playing: false, 引き出し: 偽、 再生インデックス: 0, 曲情報: {}, 曲リスト: [], 音量: 80, // 音量 lyricInfo: [], playType: 1, // 再生タイプ: 1-リスト ループ、2-ランダム再生、3-シングル ループshowPlayType: "リスト ループ", オーディオ進行状況: 0, 親指の翻訳X: 0, 歌詞インデックス: 0, color: "#fff", //歌詞のデフォルト色 colorLight: "#40ce8f", //歌詞のハイライト色 fontSize: "16px", //歌詞のフォントサイズ lineHeight: "42", //各段落の高さ paddingTop: "300px", //ハイライトされた歌詞部分を中央に配置}; }, 作成された() {}, コンポーネント: Mscroll、 }, 計算: { オーディオ進行度パーセント() { `${this.audioProgress * 100}%` を返します。 }, }, マウント() { const music = document.getElementById("music"); if (this.$route.query.play) { this.ClickPlay(); } それ以外 { this.GetSongList(); } if (this.playing) { // 再生中。クリックすると一時停止します。this.playing = false; this.$refs.rotate.style.animationPlayState = "一時停止"; 音楽.一時停止(); } それ以外 { // 一時停止。クリックすると再生されます。this.playing = true; this.$refs.rotate.style.animationPlayState = "実行中"; 音楽を再生します。 } }, メソッド: { //音量の変更 volumeChange() { if (this.volumeStatus) { this.volumeStatus = false; this.volumeNum = this.volume; this.volume = 0; this.volumeType = "md-volume-off"; } それ以外 { this.volumeStatus = true; this.volume = this.volumeNum; this.volumeType = "md-volume-up"; } }, //曲の再生タイプが変わる playTypeChange() { (this.playType == 1)の場合{ 再生タイプ = 2; this.showPlayType = "ランダム再生"; this.playStatus = "iconfont icon-suijibofang"; 戻る; } (this.playType == 2)の場合{ this.playType = 3; this.showPlayType = "シングルループ"; this.playStatus = "iconfont icon-danquxunhuan"; 戻る; } (this.playType == 3)の場合{ this.playType = 1; this.showPlayType = "リストループ"; this.playStatus = "iconfont icon-xunhuanbofang"; 戻る; } }, クリック再生() { このオーディオを初期化します。 this.getMusicList(this.songInfo.id); this.$refs.rotate.style.animationPlayState = "実行中"; this.playing = true; タイムアウトを設定する(() => { 音楽を再生します。 }, 100); }, GetSongList() { axios.get("/musicController/getMusicList").then(this.GetSongListInfo); }, GetSongListInfo(res) { myList を作成します。 (res.code == "0000"の場合){ myList = res.data; } それ以外 { console.log("データが見つかりません"); myList = [ { アーティスト名:「地主の猫」 カバー: "https://p3.music.126.net/KkrcSwKbRsd8GuaOHILlxA==/109951166077317301.jpg", id: 1857630559、 名前: 「新入生」 URL: "https://music.163.com/song/media/outer/url?id=1857630559.mp3", 歌詞: : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : }, ]; } this.songList = myList; this.songList[0] をコピーします。 this.getMusicList(this.songInfo.id); //再生中の曲のIDから、再生中の曲のURL歌詞情報を取得します。this.audioInit(); }, オーディオ初期化() { that = this とする; let progressL = this.$refs.track.offsetWidth; // プログレスバーの合計の長さ music.addEventListener("timeupdate", () => { // 現在の再生時間 let compareTime = music.currentTime; (i = 0 とします; i < that.lyricInfo.length; i++) { 比較時間 > parseInt(that.lyricInfo[i].time) の場合 { 定数インデックス = that.lyricInfo[i].index; if (i === parseInt(index)) { that.lyricIndex = i; } } } that.currentTime = commonJs.TimeToString(music.currentTime); that.audioProgress = music.currentTime / music.duration; that.thumbTranslateX = (that.audioProgress * progressL).toFixed(3); }); music.addEventListener("終了", () => { スイッチ(parseInt(that.playType)){ ケース1: // リストループ that.playIndex = that.playIndex + 1 >= that.songList.length ? 0 : that.playIndex + 1; 壊す; ケース 2: // ランダムに再生する that.playIndex = Math.floor(Math.random() * that.songList.length); 壊す; ケース 3: // 単一ループ break; } that.songInfo = that.songList[that.playIndex]; this.getMusicList(that.songInfo.id); タイムアウトを設定する(() => { this.$refs.rotate.style.animationPlayState = "実行中"; 音楽を再生します。 }, 200); }); }, //再生と一時停止 playMusic() { if (this.playing) { // 再生中。クリックすると一時停止します。this.playing = false; this.$refs.rotate.style.animationPlayState = "一時停止"; 音楽.一時停止(); } それ以外 { // 一時停止。クリックすると再生されます。this.playing = true; this.$refs.rotate.style.animationPlayState = "実行中"; 音楽を再生します。 } }, プレイリストミュージック(インデックス) { this.playIndex = インデックス; this.songInfo = this.songList[this.playIndex]; this.getMusicList(this.songInfo.id); this.playing = true; this.drawer は false です。 タイムアウトを設定する(() => { this.$refs.rotate.style.animationPlayState = "実行中"; 音楽を再生します。 }, 200); }, //プログレスバーをクリック handleProgressClick(event) { let progressL = this.$refs.track.offsetWidth; // プログレスバーの合計の長さ let clickX = event.offsetX; time = (clickX / progressL).toFixed(2) とします。 this.setProgress(時間); }, setProgress(x) { music.currentTime = music.duration * x; }, // 前の曲 skipBack() { this.skipFn("スキップバック"); }, // 次の曲 skipForward() { this.skipFn("前方へスキップ"); }, // 上部と下部のヘッダーのカプセル化 skipFn(type) { スイッチ(parseInt(this.playType)){ ケース 2: // ランダムに再生 this.playIndex = Math.floor(Math.random() * this.songList.length); 壊す; デフォルト: if (type == "skipBack") { this.playIndex - 1 >= 0 ? this.playIndex-- : 0; } それ以外 { this.playIndex = this.playIndex + 1 >= this.songList.length ? この曲リストの長さ - 1 : this.playIndex + 1; } 壊す; } this.songInfo = this.songList[this.playIndex]; this.getMusicList(this.songInfo.id); this.playing = true; タイムアウトを設定する(() => { this.$refs.rotate.style.animationPlayState = "実行中"; 音楽を再生します。 }, 200); }, //音量を調整する changeVolum(c) { 音楽の音量をc/100に設定します。 音楽の音量が0の場合 this.volumeType = "md-volume-off"; } それ以外 { this.volumeType = "md-volume-up"; } }, //再生する曲のURL情報を取得する getMusicList(id) { that = this とする; axios.get("/musicController/getMusicURLInfo/" + id).then(function (res) { スイッチ (res.code) { ケース "0000": that.songInfo.url = res.data.url; 歌詞のリストを取得します。 壊す; ケース「1111」: メッセージを表示します("警告", res.message); 壊す; } }); }, 歌詞リストを取得する(lrc) { lyricsObjArr = [] とします。 const regNewLine = /\n/; const lineArr = lrc.split(regNewLine); // 各行の歌詞の配列 const regTime = /\[\d{2}:\d{2}.\d{2,3}\]/; lineArr.forEach((item) => { if (item === "") 戻り値: 定数obj = {}; 定数時間 = item.match(regTime); obj.lyric = item.split("]")[1].trim() === "" ? "" : item.split("]")[1].trim(); obj.time = 時間 ? commonJs.TimeToSeconds(time[0].slice(1, time[0].length - 1)) : 0; obj.uid = Math.random().toString().slice(-6); obj.lyric === "" の場合 { console.log("この行には歌詞がありません"); } それ以外 { 歌詞をObjArr.push(obj); } }); this.lyricInfo = lyricsObjArr.map((item, index) => { アイテム.index = インデックス; 戻る { ...アイテム、 }; }); }, }, }; </スクリプト> <style lang="less" スコープ> .メインページ { 幅: 100%; 高さ: 100%; 位置: 絶対; 背景: rgba(15, 15, 15, 0.4); オーバーフロー: 非表示; .background-flitter { 位置: 絶対; zインデックス: 0; 背景繰り返し: 繰り返しなし; 幅: 100%; 高さ: 100%; 上: 0; 左: 0; 背景サイズ: カバー; 背景位置: 50%; フィルター: ぼかし(8px); // マージン: -20px; 不透明度: 0.7; オーバーフロー: 非表示; ボックスのサイズ: 境界線ボックス; } .play-mini { 位置: 絶対; 下部: 0; 左: 0; 幅: 100%; 高さ: 72px; // 背景: #fff; ディスプレイ: フレックス; アイテムの位置を中央揃えにします。 パディング: 6px 0; ボックスのサイズ: 境界線ボックス; zインデックス: 10; .songInfo{ 最小幅: 360px; 最大幅: 480px; 位置: 相対的; パディング: 0 18px; ボックスのサイズ: 境界線ボックス; ディスプレイ: フレックス; .ポスター{ 幅: 52px; 高さ: 52px; 境界線の半径: 5px; 上マージン: 4px; 右マージン: 20px; } 。情報 { 最小幅: 280px; 高さ: 100%; 行の高さ: 30px; フォントサイズ: 16px; } } .コントロール{ 幅: 280ピクセル; 高さ: 100%; ディスプレイ: フレックス; アイテムの位置を中央揃えにします。 画像 { 幅: 40px; 高さ: 40px; カーソル: ポインタ; } 。状態 { 幅: 40px; 高さ: 40px; 左マージン: 36px; 右マージン: 36px; カーソル: ポインタ; } } .プログレスバー{ 位置: 絶対; zインデックス: 10; 上: -5px; 幅: 100%; 高さ: 5px; 背景: rgba(255, 255, 255, 0.5); カーソル: ポインタ; .progress-box { 高さ: 100%; 背景: #40ce8f; 位置: 相対的; } } .右下{ 位置: 相対的; 幅: 420ピクセル; 高さ: 100%; ディスプレイ: フレックス; アイテムの位置を中央揃えにします。 .text-div { 色: #fff; 高さ: 100%; 行の高さ: 60px; 左マージン: 5px; 右マージン: 5px; } .プレイリスト{ 位置: 絶対; 右: 0px; } { 色: #333; } } } .song-cover-lyrics { 位置: 相対的; 幅: 100%; 高さ: 100%; パディング下部: 72px; ボックスのサイズ: 境界線ボックス; ディスプレイ: フレックス; オーバーフロー: 非表示; .ディスクコンテナ{ 幅: 50%; 高さ: 100%; 位置: 相対的; .ポスター{ 位置: 相対的; 幅: 280ピクセル; 高さ: 280px; 境界線の半径: 50%; 背景: rgba(255, 255, 255, 0.3); 左: 50%; 上: 100px; 左マージン: -140px; ボックスの影: 0 0 0 12px rgba(255, 255, 255, 0.4); アニメーション: animations1 12 秒の線形無限前進; アニメーション再生状態: 一時停止; オーバーフロー: 非表示; 下部マージン: 160px; 画像 { 幅: 100%; 高さ: 100%; } } .曲名{ 幅: 100%; 高さ: 40px; テキスト配置: 中央; フォントサイズ: 32px; フォントの太さ: 600; 色: #fff; 行の高さ: 40px; } .song-artistsName { 幅: 100%; 高さ: 40px; テキスト配置: 中央; フォントサイズ: 28px; フォントの太さ: 600; 色: #fff; 行の高さ: 40px; 上マージン: 24px; } @keyframesアニメーション1 { から { 変換: 回転(0度); } に { 変換: 回転(360度); } } } .歌詞{ 幅: 50%; 高さ: 600px; 位置: 相対的; オーバーフロー: 非表示; } } } </スタイル> <スタイル lang="less"> .ivu-引き出し本体{ .リストコンテナ{ 幅: 100%; 高さ: 100%; オーバーフロー:自動; 位置: 相対的; .songInfo{ 幅: 100%; 高さ: 42px; ディスプレイ: フレックス; アイテムの位置を中央揃えにします。 下部マージン: 12px; カーソル: ポインタ; 画像 { 幅: 36ピクセル; 高さ: 36px; 境界線の半径: 5px; 右マージン: 12px; } 。情報 { 位置: 相対的; 幅: 240ピクセル; 高さ: 36px; 行の高さ: 18px; 。名前 { 幅: 100%; 高さ: 18px; フォントサイズ: 14px; フォントの太さ: 600; テキストオーバーフロー: 省略記号; オーバーフロー: 非表示; 空白: ラップなし; 行の高さ: 18px; } .歌手{ 幅: 100%; 高さ: 18px; フォントサイズ: 12px; テキストオーバーフロー: 省略記号; オーバーフロー: 非表示; 空白: ラップなし; 行の高さ: 18px; } } } } } </スタイル> 歌詞部分 (lyricScroll.vue) <テンプレート> <!--歌詞--> <div ref="音楽歌詞" クラス="音楽-歌詞" :style="{'padding-top': paddingTop}" > <div class="music-lyric-items" :style="lyricTop"> <テンプレート v-if="歌詞リスト.length > 0"> <p v-for="(item, index) in lyricsList" :key="インデックス" :data-index="インデックス" ref="歌詞" :style="{ 色: lyricIndex === インデックス? colorLight: 色、 'フォントサイズ': フォントサイズ、 }" > {{ item.lyric }} </p> </テンプレート> <p style="color: #fff" v-else>歌詞を読み込んでいます。 。 。 。 。 </p> </div> </div> </テンプレート> <スクリプト> const COMPONENT_NAME = "スクロール"; エクスポートデフォルト{ 名前: COMPONENT_NAME、 小道具: { // 歌詞リスト lyricsList: { タイプ: 配列、 デフォルト: () => [], }, // 現在の歌詞インデックス lyricIndex: { タイプ: 数値、 デフォルト: 0, }, // 歌詞のデフォルトの色 color: { タイプ: 文字列、 デフォルト: "#fff", }, // 歌詞のハイライト colorcolorLight: { タイプ: 文字列、 デフォルト: "#40ce8f", }, フォントサイズ: { タイプ: 文字列、 デフォルト: "16px", }, 行の高さ: { タイプ: 文字列、 デフォルト: "42", }, パディングトップ: { タイプ: 文字列、 デフォルト: "300px", }, }, データ() { 戻る { top: 0, // 歌詞を中央に表示 // 歌詞リストの例 lyricListDemo: [ { インデックス: 0, 歌詞:「作曲:CMJ」 時間: 0, }, { インデックス: 1, 歌詞:「作詞:タオ・ジウ」 時間: 0.29、 }, { インデックス: 2, 歌詞:「晩秋の落ち葉を聴く」 時間: 0.89、 }, { インデックス: 3, 歌詞:「さよならをため息とともに聞く」 時間: 5.14、 }, { インデックス: 4, 歌詞:「私はそれを鑑賞するために一人残された」 時間: 9.39、 }, { インデックス: 5, 歌詞:「海と山と風と月」 時間: 13.14、 }, ]、 }; }, マウント() {}, 時計: 歌詞インデックス(新しい値、古い値) {}, }, 計算: { 歌詞トップ() { `transform :translate3d(0, ${(0 - this.lineHeight) * を返します (this.lyricIndex - this.top)}px, 0);色: ${this.color};行の高さ: ${ this.lineHeight }px`; }, }, メソッド: {}, }; </スクリプト> <style lang="less" スコープ> /*歌詞部分*/ .音楽歌詞{ パディング上部: 300px; ボックスのサイズ: 境界線ボックス; オーバーフロー: 非表示; テキスト配置: 中央; マスク画像: 線形グラデーション( 一番下まで、 RGBA(255, 255, 255, 0) 0, RGBA(255, 255, 255, 0.6) 5%, RGBA(255, 255, 255, 1) 15%, RGBA(255, 255, 255, 1) 85%, RGBA(255, 255, 255, 0.6) 95%, RGBA(255, 255, 255, 0) 100% ); .music-lyric-items { テキスト配置: 中央; フォントサイズ: 16px; 色: #fff; 変換: translate3d(0, 0, 0); 遷移: transform 0.6s イーズアウト; テキストオーバーフロー: 省略記号; オーバーフロー: 非表示; 空白: ラップなし; 。の上 { 色: #40ce8f; } } } </スタイル> 時間変換JS (timeConversion.js) /** * @著者 lyq * @時間 2021年11月21日 21:08:48 * * 秒を時間、分、秒に変換します* @name TimeToString * @example 秒を時間、分、秒に変換します* @param {String} seconds 秒*/ const TimeToString = (秒) => { param = parseInt(秒)とします。 hh = "", とします。 ミリメートル = "", ss = ""; パラメータ >= 0 && パラメータ < 60 の場合 { param < 10 ? (ss = "0" + param) : (ss = param); "00:" + ssを返します。 } そうでない場合 (パラメータ >= 60 && パラメータ < 3600) { mm = parseInt(パラメータ / 60); mm < 10 ? (mm = "0" + mm) : mm; パラメータ - parseInt(mm * 60) < 10 ? (ss = "0" + String(param - parseInt(mm * 60))) : (ss = パラメータ - parseInt(mm * 60)); mm + ":" + ssを返します。 } } 基本的なフロントエンドコードはここにあり、以下はバックエンドのインターフェースロジック層コードです。 /** * @著者: [LiuYanQiang] * @バージョン: [v1.0] * @クラス名: MusicServiceImpl * @description: [このクラスの機能の説明] * @createTime : [2021/11/16 14:28] * @updateUser : [LiuYanQiang] * @更新時間 : [2021/11/16 14:28] * @updateRemark: [この変更の説明] */ @サービス 翻訳者 パブリッククラス MusicServiceImpl は MusicService を実装します { オートワイヤード プライベート環境環境; /* * @バージョン V1.0 * タイトル: getMusicList * @author 劉燕強 * @description ホットソングリストのランダムな20曲の情報を取得します* @createTime 2021/11/16 14:32 * @パラメータ [] * @return java.util.Map*/ @オーバーライド パブリックリスト<Map<文字列、オブジェクト>> getMusicList() { JSONArray 結果オブジェクト = null; // URL を連結し、対応するリクエストを送信します。StringBuffer url = new StringBuffer(); url.append("https://api.vvhan.com/api/rand.music?type=all&sort=Hot Song List"); // インターフェイスの戻り値を取得します。String body = HttpUtils.sendGet(url.toString()); 結果オブジェクト = JSONObject.parseArray(body); リスト<Map<String, Object>> リスト = 新しい ArrayList<>(); (int i = 0; i < resultObject.size(); i++) の場合 { HashMap<String, Object> マップ = 新しい HashMap<String, Object>(); JSONオブジェクト jsonObject = resultObject.getJSONObject(i); map.put("カバー", JSONObject.parseObject(jsonObject.get("アルバム").toString()).getString("picUrl")); map.put("アーティスト名", JSONObject.parseArray(jsonObject.get("アーティスト").toString()).getJSONObject(0).getString("名前")); map.put("名前", jsonObject.getString("名前")); map.put("id", jsonObject.getString("id")); リストにマップを追加します。 } ランダム random = new Random(); int num = random.nextInt(179) % (179 - 0 + 1) + 0; リスト = list.subList(num, num + 20); リストを返します。 } /* * @バージョン V1.0 * タイトル: getMusicURLInfo * @author 劉燕強 * @description 音楽プレーヤーのURL情報を取得します * @createTime 2021/11/19 9:22 * @param [Id——音楽ID] * @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>*/ @オーバーライド パブリックマップ<String, Object> getMusicURLInfo(String Id) { JSONオブジェクト結果オブジェクト = null; // URL を連結し、対応するリクエストを送信します。StringBuffer url = new StringBuffer(); url.append("https://api.vvhan.com/api/music?id=" + Id + "&type=song&media=netease"); // インターフェイスの戻り値を取得します。String body = HttpUtils.sendGet(url.toString()); 結果オブジェクト = JSONObject.parseObject(本文); HashMap<String, Object> マップ = 新しい HashMap<String, Object>(); //第三者から提供された音楽URLが有効かどうかを判断します。無効の場合は公式URLに置き換えます if(this.isValid(resultObject.get("mp3url").toString())){ map.put("id", resultObject.get("song_id").toString()); map.put("名前", resultObject.get("名前")); map.put("アーティスト名", resultObject.get("著者")); map.put("カバー", resultObject.get("カバー")); map.put("url", resultObject.get("mp3url")); map.put("歌詞", this.getMusicLyricById(Id) != null ? this.getMusicLyricById(Id) : null); } それ以外{ map.put("id", Id); map.put("url", "https://music.163.com/song/media/outer/url?id="+Id+".mp3"); map.put("歌詞", this.getMusicLyricById(Id) != null ? this.getMusicLyricById(Id) : null); } マップを返します。 } /* * @バージョン V1.0 * タイトル: isValid * @author 劉燕強 * @description リンクが有効かどうかを判定する* @createTime 2021/11/20 10:23 * @param [strLink——入力リンク] * @return ブール値 * */ パブリックブール値isValid(文字列strLink) { URL URL; 試す { url = 新しいURL(strLink); HttpURLConnection 接続 = (HttpURLConnection) url.openConnection(); connt.setRequestMethod("HEAD"); 文字列 strMessage = connt.getResponseMessage(); if (strMessage.compareTo("見つかりません") == 0) { false を返します。 } 接続を切断します。 } キャッチ (例外 e) { false を返します。 } true を返します。 } /* * @バージョン V1.0 * タイトル: getRandomFiveMusic * @author 劉燕強 * @description 5曲をランダムに再生します。頻繁に呼び出さないでください。そうしないと、NetEase Cloud APIコールバックが異常になります。 * @createTime 2021/11/19 9:08 * @パラメータ [] * @return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>*/ @オーバーライド パブリックリスト<Map<文字列、オブジェクト>> getRandomFiveMusic() { リスト<Map<String, Object>> リスト = 新しい ArrayList<>(); (int i = 0; i < 5; i++) の場合 { JSONオブジェクト結果オブジェクト = null; // URL を連結し、対応するリクエストを送信します。StringBuffer url = new StringBuffer(); url.append("https://api.vvhan.com/api/rand.music?type=json&sort=Hot Song List"); // インターフェイスの戻り値を取得します。String body = HttpUtils.sendGet(url.toString()); 結果オブジェクト = JSONObject.parseObject(本文); JSONObject 情報 = JSONObject.parseObject(resultObject.get("info").toString()); HashMap<String, Object> マップ = 新しい HashMap<String, Object>(); map.put("id", info.get("id").toString()); map.put("名前"、info.get("名前")); map.put("アーティスト名", info.get("作者")); map.put("カバー", info.get("picUrl")); map.put("url", info.get("mp3url")); map.put("歌詞", this.getMusicLyricById(info.get("id").toString()) != null ? this.getMusicLyricById(info.get("id").toString()) : null); リストにマップを追加します。 log.info("呼び出しは成功しました" + i + "回"); } リストを返します。 } /* * @バージョン V1.0 * タイトル: getMusicLyricById * @author 劉燕強 * @description 歌詞情報を取得* @createTime 2021/11/16 19:23 * @param [Id——音楽ID] * @return java.lang.String*/ @オーバーライド パブリック文字列 getMusicLyricById(文字列 ID) { 試す { JSONオブジェクト結果オブジェクト = null; // URL を連結し、対応するリクエストを送信します。StringBuffer url = new StringBuffer(); url.append("https://music.163.com/api/song/media?id=" + Id); // インターフェイスの戻り値を取得します。String body = HttpUtils.sendGet(url.toString()); 結果オブジェクト = JSONObject.parseObject(本文); (resultObject.get("lyric").toString() != null) の場合 { resultObject.get("lyric").toString() を返します。 } それ以外 { null を返します。 } } キャッチ (例外 e) { e.printStackTrace(); } null を返します。 } } 要約する これで、NetEase Cloud Music Player インターフェースを模倣した Vue の簡単な実装に関するこの記事は終了です。Vue NetEase Cloud Music Player インターフェースの関連コンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
>>: ウェブページにプレーヤーを埋め込む埋め込み要素の自動開始が false 無効
画像内に下線付きのリンクが表示されても驚かないでください。実はとても簡単なので、あなたにもできるので...
お使いのコンピュータが Mac の場合、homebrew を使用して MySQL をインストールする...
ssh に入り、次のコマンドを入力してパスワードをリセットします (コマンドの末尾の「testpas...
htmlコードをコピーコードは次のとおりです。 <SPAN class=tag><...
1. 戻るボタンhistory.back() を使用してブラウザの「戻る」ボタンを作成します。 &l...
1. 設定ファイルディレクトリを作成するcd /ホームディレクトリmkdir frp最終的なディレク...
序文この記事では、Vue コンポーネントがどのように解析され、レンダリングされるかを説明します。 V...
[LeetCode] 185. 部門別給与上位3位従業員テーブルにはすべての従業員が保持されます。...
目次1. はじめに2. 原則III. 実践3.1 インデックスプッシュダウンを使用しない3.2 イン...
HTML では、一般的な URL はさまざまな方法で表現されます。相対 URL:コードをコピーコード...
目次1. Linuxホスト名を設定するクライアントホストを構成するサーバーホストを構成する2. ホス...
以下は私がまとめた基本的なSQL知識です。主に参考資料として、また将来の他の初心者の助けとして、私自...
ブロック引用の定義と使用法<blockquote> タグは引用ブロックを定義します。 &...
目次1. データベース論理バックアップとはどのようなバックアップですか? 2. よく使われる論理バッ...
背景すべては、WeChat 技術グループのクラスメートが「写真の主な色を取得する方法はあるか」と尋ね...