久久亚洲成a人片熟女精品色一区二区三区|国产精品视频第一精品视频|av天堂热无码手机版|亚洲?v无码久久无遮挡|国产精品偷伦视频免费观看国产|麻豆国产自产精品丰满熟妇|av无码av不卡一区二区|久久亚洲精品中文字

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營的一線實(shí)戰(zhàn)洞察。

Java在線音樂播放系統(tǒng)實(shí)戰(zhàn):從流式播放到接口設(shè)計(jì)全解析

Java在線音樂播放系統(tǒng)實(shí)戰(zhàn):從流式播放到接口設(shè)計(jì)全解析 寫這篇東西之前我先說個(gè)背景。很多人在學(xué)校、公司內(nèi)部或者接私活的時(shí)候碰到過類似的需求——做一個(gè)“基于Java的在線音樂播放系統(tǒng)”??雌饋硎莻€(gè)老掉牙的題目網(wǎng)上相關(guān)的項(xiàng)目源碼也一抓一大把但真正自己動(dòng)手做一遍或者在原有代碼上改一改就會(huì)發(fā)現(xiàn)這里面坑不少音頻文件怎么存、播放進(jìn)度怎么續(xù)傳、歌單和歌曲的關(guān)系怎么不寫成一團(tuán)亂麻、多端訪問時(shí)接口怎么設(shè)計(jì)才不打架。這篇文章不打算講那些網(wǎng)上抄來抄去的理論而是拆一個(gè)我實(shí)際帶過的項(xiàng)目基于 Java 的在線音樂播放系統(tǒng)從需求分析、表結(jié)構(gòu)設(shè)計(jì)、后端接口實(shí)現(xiàn)到前端播放器對(duì)接再到上線前容易踩的坑一條線捋下來。適合的人群就是兩類一是馬上要做相關(guān)課程設(shè)計(jì)或者畢業(yè)設(shè)計(jì)的同學(xué)二是在公司里要做內(nèi)部音樂點(diǎn)播、語音素材管理等相似系統(tǒng)的后端工程師。廢話不多說直接進(jìn)入正題。1. 動(dòng)手前先想清楚在線音樂系統(tǒng)到底在解決什么問題很多人在寫這種系統(tǒng)的時(shí)候第一步就是建 Spring Boot 項(xiàng)目然后開始寫增刪改查。這在我看來是順序錯(cuò)了。開發(fā)這種業(yè)務(wù)系統(tǒng)最先應(yīng)該花時(shí)間想清楚的是三個(gè)前提問題而不是先寫代碼。1.1 “在線播放”和“文件下載”是兩碼事我見過很多半成品系統(tǒng)所謂的在線播放其實(shí)是把音頻文件直接塞到前端audio標(biāo)簽的 src 里然后讓瀏覽器自己下載完再播。這樣實(shí)現(xiàn)極其簡(jiǎn)單但體驗(yàn)和后期問題都很大大文件加載慢、刷新就從頭開始、帶寬浪費(fèi)、無法做權(quán)限控制。真正的在線播放本質(zhì)上是一個(gè)“流式Streaming讀取”過程。客戶端向服務(wù)端發(fā)一個(gè)請(qǐng)求服務(wù)端從磁盤里讀文件按字節(jié)一點(diǎn)一點(diǎn)吐給客戶端。這時(shí)候 HTTP 協(xié)議里有一個(gè)很關(guān)鍵的東西叫Range 請(qǐng)求頭HTTP Range Header。簡(jiǎn)單說就是瀏覽器會(huì)告訴服務(wù)器“我不需要整個(gè)文件我只要從第 N 個(gè)字節(jié)到第 M 個(gè)字節(jié)的這段數(shù)據(jù)”。服務(wù)端如果能正確處理這種請(qǐng)求就能實(shí)現(xiàn)拖動(dòng)進(jìn)度條播放、快進(jìn)快退、斷點(diǎn)續(xù)傳而不是傻傻地每次從零開始傳。所以剛開始做的時(shí)候我就把系統(tǒng)的核心定位成能正確處理 Range 請(qǐng)求的音頻流接口。這一條確定下來后面整個(gè)接口設(shè)計(jì)都會(huì)不一樣。1.2 管理端和播放端要分離開這個(gè)系統(tǒng)的使用方看起來很簡(jiǎn)單用戶登錄、搜歌、聽歌。但實(shí)際落地的時(shí)候一定會(huì)有“誰把歌傳上來的”這個(gè)問題。我參與的這個(gè)項(xiàng)目里最初沒人管上傳這回事結(jié)果導(dǎo)致所有歌曲都得靠程序員往數(shù)據(jù)庫里手工插數(shù)據(jù)一次插幾十條效率低不說還很容易出現(xiàn)封面路徑寫錯(cuò)、時(shí)長(zhǎng)寫錯(cuò)這些問題。所以在設(shè)計(jì)上從一開始就要明確兩個(gè)角色管理員負(fù)責(zé)維護(hù)曲庫上傳音頻、填寫歌曲信息、管理歌手和專輯普通用戶只負(fù)責(zé)聽瀏覽、搜索、創(chuàng)建自己的歌單。這個(gè)區(qū)分不是界面上的花架子它直接決定了接口的權(quán)限分配比如上傳接口必須鑒權(quán)刪除操作必須限定角色普通用戶的接口則最多做登錄校驗(yàn)不應(yīng)該動(dòng)不動(dòng)就 403。1.3 版權(quán)和存儲(chǔ)策略不能抄網(wǎng)上的思路網(wǎng)上下載的一些源碼很多直接把歌曲文件塞到項(xiàng)目根目錄的 static 文件夾里然后數(shù)據(jù)庫存一個(gè) /static/music/xxx.mp3 了事。這在演示階段沒問題但對(duì)稍微正式一點(diǎn)的項(xiàng)目就是隱患項(xiàng)目重新打包部署時(shí)static 目錄可能被覆蓋文件說沒就沒靜態(tài)資源如果被 Nginx 直接映射出去任何人都能拼 URL 下載完全繞過了權(quán)限校驗(yàn)幾百首歌塞進(jìn) jar/war 包里包變得巨大啟動(dòng)都慢。正確的做法是把音頻文件和代碼徹底分開文件放到獨(dú)立的本地目錄或者對(duì)象存儲(chǔ)里數(shù)據(jù)庫只保存邏輯路徑通過接口動(dòng)態(tài)輸出。這一點(diǎn)我會(huì)在第 5 節(jié)專門展開講。2. 技術(shù)選型不是越新越好而是越順手越好做 Java 后端的人對(duì)技術(shù)棧通常都有一些偏好但在這個(gè)項(xiàng)目上我最終采用的是非?!皠?wù)實(shí)”的一套組合沒有刻意追新Spring Boot 2.7 MyBatis-Plus MySQL 8.0 Redis可選 Vue 3 Element Plus。2.1 后端為什么用 Spring Boot 而不是 Spring Cloud音樂播放系統(tǒng)本質(zhì)上是一個(gè)單體的中小型應(yīng)用沒必要上微服務(wù)那一套。Spring Boot 自帶內(nèi)嵌 Tomcat打包成一個(gè) jar 就能跑開發(fā)調(diào)試都簡(jiǎn)單。用 Spring Cloud 反而會(huì)把 Nacos 注冊(cè)中心、配置中心等概念引進(jìn)來徒增部署復(fù)雜度。持久層框架我用的是 MyBatis-Plus。很多人糾結(jié)到底用 MyBatis 還是 Spring Data JPA我的看法是這個(gè)系統(tǒng)涉及比較多的多表關(guān)聯(lián)查詢歌單里查歌曲、歌曲關(guān)聯(lián)歌手MyBatis 的 SQL 寫起來可控性更強(qiáng)而 MyBatis-Plus 又把單表 CRUD 給封裝掉了不用寫一堆重復(fù)的 BaseMapper 方法。查歌單的時(shí)候稍微加一點(diǎn)注解或 XML 就能完成關(guān)聯(lián)查詢效率很高。2.2 前端是 SPA 還是服務(wù)端渲染前端我試過兩條路一條是 Thymeleaf 服務(wù)端渲染另一條是前后端分離的 Vue 單頁應(yīng)用。第一條路實(shí)現(xiàn)起來很快但播放器做交互的時(shí)候很難受頁面一刷新狀態(tài)就沒了。第二條路一開始要多寫一點(diǎn)接口對(duì)接代碼但播放列表、音量、播放模式這些狀態(tài)都放在瀏覽器內(nèi)存里體驗(yàn)好得多。如果你要在一個(gè)月內(nèi)交項(xiàng)目我不建議前后端完全分離因?yàn)檫€要配 Nginx 或者處理跨域。折中一點(diǎn)的做法是后端只提供 RESTful API前端用 Vue Vite 單獨(dú)開發(fā)調(diào)試的時(shí)候用開發(fā)代理比如 Vite 的 server.proxy把 /api 轉(zhuǎn)發(fā)到后端 8080 端口部署時(shí)再統(tǒng)一放到同一個(gè)域的路徑下這樣既不難受又能講清楚架構(gòu)。2.3 項(xiàng)目包結(jié)構(gòu)設(shè)計(jì)我實(shí)際開發(fā)的包結(jié)構(gòu)大概長(zhǎng)這樣src/main/java/com/example/music ├── MusicApplication.java ├── config │ ├── WebConfig.java // 跨域、攔截器配置 │ └── MybatisPlusConfig.java // 分頁插件 ├── controller │ ├── UserController.java │ ├── SongController.java │ ├── SongListController.java │ └── StreamController.java // 音頻流播放接口 ├── service │ ├── UserService.java │ ├── SongService.java │ ├── SongListService.java │ └── OssFileService.java // 本地文件存儲(chǔ)服務(wù) ├── mapper ├── entity ├── dto └── common ├── Result.java └── BizException.java這套結(jié)構(gòu)不算復(fù)雜但把配置、控制層、業(yè)務(wù)層、持久層、通用類都分開了。項(xiàng)目到后期加了定時(shí)統(tǒng)計(jì)功能也只是在 service 下面加一個(gè) StatisticService不影響原有代碼。3. 數(shù)據(jù)庫設(shè)計(jì)表結(jié)構(gòu)決定后面少改多少需求這個(gè)系統(tǒng)的表設(shè)計(jì)是我花時(shí)間最多的地方。我見過很多爛設(shè)計(jì)比如“歌單里直接存一串歌曲 ID”查一次歌單要把字符串拆開來再查幾十遍。這里把邏輯完整理一遍。3.1 核心表與關(guān)系整個(gè)系統(tǒng)一共有 6 張核心表user 用戶表 singer 歌手表 song 歌曲表 song_list 歌單表 list_song 歌單-歌曲關(guān)聯(lián)表 upload_record 上傳記錄表可選關(guān)系是這樣的一個(gè)歌手可以有多首歌一對(duì)多一首歌可以出現(xiàn)在多個(gè)歌單里一個(gè)歌單也能包含多首歌所以歌單和歌曲是多對(duì)多必須用中間表 list_song 連接用戶可以創(chuàng)建多個(gè)歌單用戶和歌單是一對(duì)多。3.2 關(guān)鍵表結(jié)構(gòu)腳本下面給出一段我實(shí)際使用的核心 SQL雖然不能覆蓋所有字段但最能說明設(shè)計(jì)意圖的是 song 表和 list_song 表。CREATE TABLE song ( id bigint NOT NULL AUTO_INCREMENT, singer_id bigint DEFAULT NULL COMMENT 歌手ID, name varchar(128) NOT NULL COMMENT 歌曲名稱, cover_url varchar(512) DEFAULT NULL COMMENT 封面圖相對(duì)路徑, file_url varchar(512) NOT NULL COMMENT 音頻文件相對(duì)路徑, duration int DEFAULT NULL COMMENT 音頻時(shí)長(zhǎng)秒, play_count int DEFAULT 0 COMMENT 播放次數(shù), status tinyint DEFAULT 1 COMMENT 1-上架 0-下架, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_singer_id (singer_id), KEY idx_name (name) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE list_song ( id bigint NOT NULL AUTO_INCREMENT, song_list_id bigint NOT NULL, song_id bigint NOT NULL, sort_order int DEFAULT 0, create_time datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_list_song (song_list_id, song_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;這里有兩個(gè)容易被忽略的設(shè)計(jì)點(diǎn)。第一song 表里單獨(dú)存了singer_id為什么不直接在 song 表里冗余一個(gè)歌手名字段因?yàn)楦枋中畔⒁院髸?huì)擴(kuò)展地區(qū)、簡(jiǎn)介、頭像如果冗余字段以后同步更新會(huì)非常麻煩。歌手表穩(wěn)定下來之后查詢時(shí) JOIN 一下成本很低。第二list_song 表沒有用復(fù)合主鍵而是單獨(dú)弄了一個(gè)自增 id同時(shí)加了聯(lián)合唯一索引uk_list_song。這樣做的目的是避免以后出現(xiàn)“同一首歌在同一個(gè)歌單里被重復(fù)添加”的情況程序里做判斷容易漏數(shù)據(jù)庫層面直接擋住更穩(wěn)。3.3 duration 字段的重要性很多初學(xué)者做歌曲管理的時(shí)候根本不存音頻時(shí)長(zhǎng)。這在前端展示時(shí)問題不大但做播放列表進(jìn)度條和“最近播放”功能時(shí)會(huì)發(fā)現(xiàn)沒有時(shí)長(zhǎng)就很難展示。獲取時(shí)長(zhǎng)并不是 Java 代碼直接能讀出來的我當(dāng)時(shí)的方案是上傳完音頻之后調(diào)用 FFmpeg 的命令行工具去探測(cè)文件時(shí)長(zhǎng)。命令大概是ffprobe -v error -show_entries formatduration -of defaultnoprint_wrappers1:nokey1 /path/to/audio.mp3Java 這邊用 ProcessBuilder 去執(zhí)行這個(gè)命令把輸出解析成 int 秒數(shù)存到 duration 字段里。你也可以用現(xiàn)成的庫比如 jaudiotagger但碰到某些特殊編碼的音頻FFmpeg 明顯更穩(wěn)。這條經(jīng)驗(yàn)在后來處理一大批用戶上傳的錄音文件時(shí)幫了大忙。3.4 搜索查詢的索引設(shè)計(jì)用戶搜歌都是按歌名模糊搜SQL 基本長(zhǎng)這樣SELECT * FROM song WHERE name LIKE CONCAT(%, #{keyword}, %) LIMIT 20;這種寫法在數(shù)據(jù)量小的時(shí)候沒問題但數(shù)據(jù)庫里如果有了幾萬首歌全表掃描就會(huì)變慢。我們當(dāng)時(shí)的處理是把 name 字段加了索引并且配合 MySQL 的覆蓋索引優(yōu)化查詢?cè)偻髷?shù)據(jù)量大了更專業(yè)的做法是接入 Elasticsearch但對(duì)大多數(shù)場(chǎng)景來說加索引已經(jīng)足夠。不要一上來就整個(gè) ES那是過度設(shè)計(jì)。4. 后端核心接口登錄、播放、歌單管理的實(shí)現(xiàn)邏輯這部分是系統(tǒng)的主干。我會(huì)挑幾個(gè)最關(guān)鍵的接口講重點(diǎn)不是說把所有代碼貼出來而是講接口的設(shè)計(jì)邏輯和邊界處理。4.1 登錄用 JWT 還是 Session考慮到這個(gè)系統(tǒng)可能有 H5 端和管理端兩個(gè)前端同時(shí)訪問用的技術(shù)棧還不一樣我選了 JWT 而不是傳統(tǒng) Session。原因很簡(jiǎn)單Session 依賴瀏覽器 Cookie在 App 端、小程序端對(duì)接時(shí)要處理 Cookie 同步很麻煩JWT 就是一個(gè)字符串前端登錄后存到 localStorage 里每次請(qǐng)求放在請(qǐng)求頭 Authorization 里就行。JWT 的問題也同樣明顯服務(wù)端不好主動(dòng)把某個(gè) token 作廢。所以我做了一套小方案用戶登錄信息會(huì)緩存到 Rediskey 是用戶 IDvalue 是當(dāng)前 token。修改密碼或者被封禁時(shí)直接刪掉 Redis 中對(duì)應(yīng) key。這個(gè)設(shè)計(jì)簡(jiǎn)便宜實(shí)現(xiàn)也把 JWT 最大的痛點(diǎn)解決掉了。登錄請(qǐng)求的核心邏輯大致是public ResultString login(LoginDTO dto) { LambdaQueryWrapperUser wrapper new LambdaQueryWrapper(); wrapper.eq(User::getUsername, dto.getUsername()); User user userMapper.selectOne(wrapper); if (user null || !PasswordUtil.matches(dto.getPassword(), user.getPassword())) { throw new BizException(用戶名或密碼錯(cuò)誤); } String token JwtUtil.createToken(user.getId(), user.getRole()); redisTemplate.opsForValue().set(login:token: user.getId(), token, Duration.ofDays(7)); return Result.success(token); }密碼不是明文存儲(chǔ)的而是用 BCrypt 加密。審核代碼的時(shí)候要認(rèn)真檢查有沒有人為了省事把密碼明文落庫這是紅線。4.2 流播放接口的實(shí)現(xiàn)這是整個(gè)系統(tǒng)最核心的接口我建議單獨(dú)用一個(gè) Controller 來管。實(shí)現(xiàn)流程是這樣的前端把歌曲 id 傳給后端或者直接傳一個(gè)帶簽名 token 的 URL后端根據(jù) id 查庫拿到 fileUrl后端把本地文件包裝成org.springframework.core.io.Resource通過ResponseEntity返回關(guān)鍵是處理 Range 請(qǐng)求頭。如果你只返回文件不處理 Range瀏覽器確實(shí)也能播但進(jìn)度條拖動(dòng)會(huì)非常遲鈍。處理 Range 的代碼我直接給出要點(diǎn)public ResponseEntityResource stream(PathVariable Long id, RequestHeader(value Range, required false) String range) { Song song songService.getById(id); File file ossFileService.getFile(song.getFileUrl()); long fileLength file.length(); long start 0; long end fileLength - 1; if (range ! null range.startsWith(bytes)) { String[] parts range.replace(bytes, ).split(-); start Long.parseLong(parts[0]); if (parts.length 1 !parts[1].isEmpty()) { end Long.parseLong(parts[1]); } } long contentLength end - start 1; InputStreamResource resource new InputStreamResource(new FileInputStream(file), start, contentLength); return ResponseEntity.status(HttpStatus.PARTIAL_CONTENT) .header(HttpHeaders.CONTENT_TYPE, audio/mpeg) .header(HttpHeaders.CONTENT_LENGTH, String.valueOf(contentLength)) .header(HttpHeaders.CONTENT_RANGE, bytes start - end / fileLength) .body(resource); }這段邏輯其實(shí)并不復(fù)雜關(guān)鍵是你知道有這個(gè)機(jī)制、去實(shí)現(xiàn)它。不處理 Range音頻播放“在線感”會(huì)差一大截。4.3 歌單和歌曲的關(guān)聯(lián)操作歌單接口最容易出問題的是添加歌曲時(shí)的雙重校驗(yàn)。場(chǎng)景是這樣的用戶把一首歌添加到歌單 A如果歌單里已經(jīng)有了這首歌應(yīng)該提示“已存在”而不是再插一條重復(fù)數(shù)據(jù)。程序上當(dāng)然可以先查一次 list_song 表再?zèng)Q定插不插但如果兩個(gè)請(qǐng)求并發(fā)過來還是會(huì)插進(jìn)去兩條。所以我除了加數(shù)據(jù)庫唯一索引之外插入時(shí)還用了一條 SQL 直接擋INSERT INTO list_song(song_list_id, song_id, sort_order) SELECT #{songListId}, #{songId}, #{sortOrder} FROM dual WHERE NOT EXISTS ( SELECT 1 FROM list_song WHERE song_list_id #{songListId} AND song_id #{songId} );這條語句成功插入返回 1重復(fù)插入返回 0代碼里判斷一下返回結(jié)果就知道有沒有插成功。這種做法比“先查再插”要穩(wěn)得多也省一次數(shù)據(jù)庫往返。4.4 播放次數(shù)的統(tǒng)計(jì)播放次數(shù)不能每一次用戶點(diǎn)擊都去 UPDATE 一次會(huì)有并發(fā)寫問題。我當(dāng)時(shí)的做法是前端每次點(diǎn)擊播放時(shí)調(diào)一個(gè)異步接口后端只把“歌曲ID 時(shí)間戳”扔進(jìn)一個(gè)內(nèi)存隊(duì)列再寫一個(gè)定時(shí)任務(wù)每隔 30 秒把隊(duì)列里的數(shù)據(jù)聚合一次批量 UPDATE song 表的 play_count 字段。這樣數(shù)據(jù)庫的壓力很小代碼也只多了一個(gè)類而已。如果想要更精確這個(gè)數(shù)據(jù)還可以落到 Redis 里定期持久化但對(duì)校內(nèi)部系統(tǒng)來說批處理足夠。5. 音頻文件的存儲(chǔ)與安全設(shè)計(jì)這節(jié)單獨(dú)拿出來講是因?yàn)槲矣X得很多網(wǎng)上的項(xiàng)目在文件這一塊處理得太隨意了。5.1 存儲(chǔ)目錄規(guī)劃我在服務(wù)器上規(guī)劃了這樣的目錄/data/music-platform/ ├── uploads/ │ ├── covers/ # 封面圖片 │ └── audio/ # 音頻文件 └── backup/數(shù)據(jù)庫里的 file_url 字段只存相對(duì)路徑比如/uploads/audio/20240715_163000_4821.mp3。為什么不存絕對(duì)路徑因?yàn)椴渴瓠h(huán)境的 IP、域名、端口都可能變服務(wù)端只拿相對(duì)路徑去拼接移動(dòng)環(huán)境時(shí)只改一個(gè)配置項(xiàng)就夠了。文件名生成用“日期_時(shí)間戳_隨機(jī)數(shù)”的方式。為什么不直接用原文件名用戶上傳的文件名很容易出現(xiàn)中文、空格、特殊字符直接落盤后 URL 編碼各種問題都會(huì)冒出來改成系統(tǒng)生成的名字一勞永逸。原始名稱可以存到數(shù)據(jù)庫的 remark 字段里。5.2 不能直接暴露靜態(tài)目錄靜態(tài)資源控制器是這么配的Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler(/static/**) .addResourceLocations(file:/data/music-platform/uploads/); }這樣配置以后前端用img src/static/covers/xxx.jpg就能直接展示封面圖開發(fā)時(shí)很方便。但是注意音頻文件千萬不要這么暴露。原因我在開頭就說了一旦暴露任何人都可以繞過鑒權(quán)直接下載整個(gè)音頻系統(tǒng)的登錄機(jī)制等于形同虛設(shè)。音頻必須走第 4.2 節(jié)的 stream 接口并且接口里要判斷用戶是否登錄。更細(xì)一步可以生成一個(gè)帶過期時(shí)間的簽名 URL比如/api/stream/123?tokenxxxexpire1720000000過期就失效防住那種把播放鏈接抓出去外傳的場(chǎng)景。對(duì)于學(xué)生項(xiàng)目或者內(nèi)部系統(tǒng)做到判斷登錄這一層已足夠簽名 URL 屬于加分項(xiàng)。5.3 上傳文件的大小限制Spring Boot 默認(rèn)的上傳文件大小是 1MB一個(gè)音頻動(dòng)輒幾十 MB不配置就直接被拒了。這個(gè)坑我見過好幾個(gè)人踩。配置在 application.yml 里spring: servlet: multipart: max-file-size: 50MB max-request-size: 60MB另外單次上傳一個(gè)大文件如果體積超過 100MB還需要考慮分片上傳這已經(jīng)超出本文范圍。一般處理 50MB 以下的音頻直接 MultipartFile 上傳完全夠用。6. 前端播放器的對(duì)接細(xì)節(jié)前端我用的是 Vue 3。播放器本身是 HTML5 的audio標(biāo)簽但要做成一個(gè)能正常工作的在線播放器需要處理很多細(xì)節(jié)。6.1 播放列表是什么數(shù)據(jù)結(jié)構(gòu)播放器內(nèi)部維護(hù)一個(gè)播放隊(duì)列這個(gè)隊(duì)列其實(shí)就是一個(gè)歌曲數(shù)組。用戶的歌單可能包含幾十首歌切歌的時(shí)候不能每次都去找歌單接口所以前端是先把整個(gè)歌單的歌曲拉下來存到播放器 store 里再根據(jù)當(dāng)前歌曲 id 計(jì)算下一首。具體邏輯是這樣的store 里的 playList 存放所有歌曲對(duì)象playIndex 記錄當(dāng)前下標(biāo)點(diǎn)擊列表中的歌曲時(shí)重新設(shè)置 playList 和 playIndex播放結(jié)束后根據(jù)播放模式列表循環(huán)、單曲循環(huán)、隨機(jī)播放計(jì)算下一個(gè) index。function playSong(song, index) { store.playList [...currentSongList]; store.playIndex index; audioElement.src getStreamUrl(song.id); audioElement.play(); }6.2 獲取歌詞和封面歌詞和封面這種信息如果每次都從接口拉會(huì)拖慢頁面。我的建議是歌單列表接口里就冗余返回歌曲的基礎(chǔ)信息封面 URL、歌手名、時(shí)長(zhǎng)點(diǎn)擊播放時(shí)再去拉音頻流地址。音頻流地址確實(shí)每次都要重新拼因?yàn)閹Я藭r(shí)間戳參數(shù)可以防止瀏覽器和 Nginx 緩存住舊的鏈接。一個(gè)很有意思的細(xì)節(jié)是音頻文件的流播放接口不能用普通的 axios 去請(qǐng)求然后拿 blob 播放那樣內(nèi)存會(huì)爆。應(yīng)該直接賦給audio.src讓瀏覽器原生去處理流式加載。很多第一次做播放器的人會(huì)在這一步卡半天實(shí)際上就是沒搞明白audio.src和 axios 的區(qū)別。6.3 播放進(jìn)度條需要 source 支持 range如果后端的流接口沒有實(shí)現(xiàn) Range 處理前端拖動(dòng)進(jìn)度條后會(huì)聽到聲音但是進(jìn)度條會(huì)拉回原位置點(diǎn)擊暫停再播放又從頭開始體驗(yàn)非常差。這不是前端代碼的問題而是后端流接口不支持隨機(jī)讀。我調(diào)試的時(shí)候踩過這個(gè)坑后來補(bǔ)上 Range 處理后一切正常。所以前后端聯(lián)調(diào)時(shí)要在瀏覽器 Network 面板里檢查 Response Headers 里有沒有Content-Range有就說明后端處理對(duì)了。7. 部署與性能調(diào)優(yōu)從能跑到能扛一個(gè)系統(tǒng)從能在本地跑到部署在服務(wù)器上讓別人用中間還隔著不少事。7.1 用 Nginx 做動(dòng)靜分離雖然系統(tǒng)是一個(gè) Spring Boot 的 jar 包但在生產(chǎn)環(huán)境我建議前面再掛一個(gè) Nginx。Nginx 負(fù)責(zé)三件事監(jiān)聽 80/443 端口把 /api 下的請(qǐng)求反向代理到內(nèi)網(wǎng)的 8080直接服務(wù) /static 下的封面圖片減輕 Tomcat 的壓力配置 Gzip 壓縮讓 JSON 響應(yīng)更小。Nginx 里音頻的流播放請(qǐng)求不建議開太大的 proxy_buffer否則邊下邊播時(shí)候內(nèi)存占用會(huì)比較詭異。實(shí)測(cè)下來保持默認(rèn)值即可。7.2 大并發(fā)下的熱點(diǎn)緩存“熱歌排行榜”對(duì)應(yīng)的 SQL 很簡(jiǎn)單SELECT * FROM song ORDER BY play_count DESC LIMIT 10;真到幾十萬播放量的時(shí)候每次首頁打開都去執(zhí)行這條 SQL數(shù)據(jù)庫壓力會(huì)很大。我把它做了 Redis 緩存key 是 hot_songs緩存時(shí)間 5 分鐘。播放次數(shù)異步更新后緩存最多落后 5 分鐘對(duì)排行榜這種非實(shí)時(shí)數(shù)據(jù)來說完全能接受。實(shí)現(xiàn)上用Cacheable或者手動(dòng) redisTemplate 都行關(guān)鍵是想清楚這個(gè)數(shù)據(jù)允許“最終一致”不需要強(qiáng)一致。7.3 音頻資源防泄露部署完成后我還做了一件事給音頻流接口加了一層 referer 校驗(yàn)。不是嚴(yán)格的安全手段但對(duì)于內(nèi)部系統(tǒng)足夠當(dāng)請(qǐng)求的 Referer 域不是自己系統(tǒng)的域名時(shí)直接返回 403。這個(gè)在 Nginx 里一個(gè)配置就能實(shí)現(xiàn)location /api/stream/ { valid_referers example.com; if ($invalid_referer) { return 403; } proxy_pass http://127.0.0.1:8080; }加上這個(gè)以后別人把播放鏈接貼在其它網(wǎng)站上基本是打開就 403。這招成本極低效果卻很好。7.4 常見運(yùn)行期報(bào)錯(cuò)我在部署階段遇到過幾個(gè)高頻報(bào)錯(cuò)直接列出來上傳文件時(shí) 413通常不是 Java 的問題而是 Nginx 的client_max_body_size默認(rèn)只有 1M需要在 http 或 server 塊里加client_max_body_size 60m;??缬驁?bào)錯(cuò)開發(fā)環(huán)境前端在 5173 端口后端在 8080必須配置 CORS。生產(chǎn)環(huán)境用 Nginx 同域代理后跨域問題自然消失。中文文件名導(dǎo)致 404如果把前端傳入的中文路徑直接拼 URL容易有問題最好統(tǒng)一格式化為 URL 編碼或者干脆按前面說的避免存中文文件名。數(shù)據(jù)庫時(shí)區(qū)報(bào)錯(cuò)連接 MySQL 時(shí)如果 serverTimezone 沒配啟動(dòng)時(shí)會(huì)報(bào)時(shí)間相關(guān)的異常直接serverTimezoneAsia/Shanghai即可。8. 最后再分享幾個(gè)小經(jīng)驗(yàn)這節(jié)算是我的一點(diǎn)點(diǎn)總結(jié)吧想到哪寫到哪。第一樹形結(jié)構(gòu)不要硬造。歌單和歌曲本來就是個(gè)標(biāo)準(zhǔn)的多對(duì)多模型中間表是繞不開的。早期我圖省事用逗號(hào)分隔歌曲 id后來加排序功能時(shí)被自己坑慘了只好重構(gòu)。數(shù)據(jù)庫的規(guī)范性是在為未來的擴(kuò)展能力買單不要圖當(dāng)前幾行代碼簡(jiǎn)單。第二文件路徑能相對(duì)就不要絕對(duì)。凡是所有用戶數(shù)據(jù)相關(guān)的資源路徑都存相對(duì)路徑部署時(shí)統(tǒng)一拼接 base path換服務(wù)器不至于把數(shù)據(jù)庫里的幾百條數(shù)據(jù)改一遍。第三如果你只有一周時(shí)間最優(yōu)先要做的是把“播放”這一條鏈路跑通而不是在歌單管理上糾結(jié)太多。所謂“跑通”就是從數(shù)據(jù)庫查到歌曲、流式接口輸出 Range 響應(yīng)、前端點(diǎn)一下能正常播放、能拖進(jìn)度條。這一條鏈路通了這個(gè)項(xiàng)目的核心價(jià)值已經(jīng)交付了大半剩下的是錦上添花。第四遇到問題先看瀏覽器 Network 面板再看后端日志。很多音頻播放不了的問題其實(shí)就是 Response Header 里少了某個(gè)字段或者 MP3 文件本身是壞的。先前后端各自定位能少走很多彎路。這些經(jīng)驗(yàn)是我在實(shí)際項(xiàng)目里一個(gè)個(gè)踩出來的希望能讓準(zhǔn)備做類似系統(tǒng)的人少折騰幾個(gè)晚上。如果你也在做 Java 音樂系統(tǒng)歡迎按著這篇文章的思路先把數(shù)據(jù)庫和流接口搭起來再繼續(xù)往細(xì)節(jié)深挖。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
国产一区在线观看无码AV| 91欧美长吊| 玖玖久久久| 内射黑人| 久久天堂婷婷网| 欧美不卡在线一区二区| 69天堂| 2026国产精品视频| 欧美亚洲成人在线一区二区三区| 亚洲图片欧美91N| 国产不卡免费在线视频| 欧美精品999| 91AV入口| 精品高清一区二区三区三州| 欧洲久久一二线| 久久久月天| 亚洲综合校园春色| 久操九九九九九九九九九九九九九九九九九九九九九九九九九九九九 | 中国熟女91| 啊啊啊啊啊啊啊好爽不要| 国产热RE99久久6国产精品首| 黄色片,com| 九九九精品成人免费视频小说| 精品免费囯产一区二区三区| 91亚.色| 亚洲999综合| 秋霞男人网| 91原创在线观看| 99精品无码| 曰韩无码777| 在线观看日韩av不卡| 一类av片在线看| 国产最火爆久久国产网站网站| 日本孕妇一区二区视频操逼免费看| 久久久久久中文| 啊啊啊啊啊啊啊啊啊在线观看| 天天综合网91入口| 亚洲吊色| 日韩欧美中文字亚洲慕| 无卡一区=区| 亚洲无码一区成人免费午夜| 97国产精品一区| 亚洲超碰在线| 91碰超| 91色欧美| 蜜臀久久99精品久久久久| 人妻无码一区二区三区久久99| 97资源免费视频| 97中文字幕色| 亚洲脚交| 9Ⅰ超碰| 精品视频一区二区| 人人操人人色人人摸| 乱伦一二三区| 亚洲av综合色区无码一| 女优视频第10页| 亚洲男人天堂Av| 欧美综合骚| 久久99国产综合精品女同| 男人天堂.AB| 蜜臀AV成人精品蜜臀AV久久| 久久大陆| 东北女人高潮视频| 免费亚洲黄色视频在线观看| 2024人人操人人摸| 江都AV在线| 中文97国产| 91热热色| 97人人操人人摸| 日本在线激情一区二区三区| 天天透伊人| 久久久久久久久久久999| 亚洲性综合| 情色图区| 国产极品精品美女视频| 亚洲天堂,男人| 亚洲色图欧美色图制服诱惑| 九九九精品| 国产家庭乱伦性爱视频| av天堂影视中文在字幕在线中文| 成人精品视频| 97超碰人人模人人拍人人| 欧美性爱无码一区二区三区| 婷婷国产精品九区| 蜜臀中文无码午夜| ?亚洲伊人伊成久久人综合网| 日本不卡卡一区| 欧亚成人在线视频| 污色区网站| 被体育老师抱着c到高潮| 亚洲国产欧美日韩精品一区二区三区,国产一区二区三区在线看片,欧美性猛交 XXX | 久久久久久久久久久久久久久性生活视频| 久久亚洲色图中文字幕| 久久精品国产亚洲AV无码做| 九九久久99| 美欧色综合| 永久免费发布性爱网| 青青草日韩无码| 97国产中文| 无码国产Av| 操学生天天| 性综合网| 91精品电影18| 久操视频这里只有精品| 午夜高清成人在线视频| 中文字幕人乱码中文字的预防方法| av中亚| 99久在线精品99re8热| 亚洲人妖网| 国产中文字幕在线点播| 午夜性| 婷婷爽人人婷婷爽视频| 欧美激情综合| 综合夜夜| 亚洲综合色在线| 国产精品亚洲无码| 日韩精彩视频| 欧美99热| 欧美性91| 亚洲精品色| 2017大香蕉| 99无码| 精品对白久久不卡| av中文字幕在线熟女| 狼人狠干| 清清一区二区三区四区不卡视频| 91激情| 91老司机在线视频免费观看| 最新日本中文字幕| 蜜桃精品视频一区| 十八禁成人网站在线观看| 国产精品视频在线播放 | 免费啊啊啊| 3D污黄视频在线观看| 2017超碰| 超碰99在线观看| 91色夜| 视频在线观看一二三区| 高清一区AV无码| 久久久久久裸体| 国产欧美亚洲精品a第2页| 五十路熟女,国产欧美精品区一区二区三区 | 色婷婷五月天| 国内毛片热久久思思热| 欧美综合传媒| 九热大香蕉| 操逼不卡中文字幕| 女生看匆91网站| 久久精品视频28| 国产中文字幕曰本毛片| 在线不欧美| 日韩天堂av电影在线观看| 手机午夜电影神马久久| 久久久日本电影| 国产青一二三| 久草视频分类在线| 亚洲最新中文字幕免费| 校园春色亚洲| 色拍偷亚洲| 欧美黑人性猛交91| 欧美一级做a爰片免费视频| 老妇女91| 天天激色| 欧美一区二区在线资源| 大香交伊人网| 在线 制服丝袜中出 人妻| 精品久久久久久无码| 91操熟女视频| 久久国产精品熟女人妻| 日韩在线女优天天干| 把腿张开老子CAO烂你| 秋霞Av理论一级在线| 久久九操在线观看| 男女激情中文字幕| 口爆综合网| 国产精品蜜乳AV| 啊啊啊啊啊在线| 亚洲精品久久一区二区三区蜜桃臀| 国产伦精品免编号公布| 免费视频无码| 99在线精品观看99| 亚洲九区| 国产一区二区啪啪视频| 夜夜影视四色| 很黄很色的视频在线观看| 偷拍 亚洲 欧美| 偷拍片久久| 久草新免费| 久久久久久久少妇| 国产亚洲欧洲在线观看| 亚洲日本男人天堂网| 色吧五月| 欧美躁死她一区二区| 久久久久国产精品片区无码直播| 日韩激情中文字幕有码| 三级特黄60分钟播放| 色综合加勒比| 色97干| 热热色青青草| 大干人妻| 日韩大香蕉AV影片| 精品无码少妇| 清纯唯美综合| 一级二级在线观看| 亚洲图片欧美| 国产精品毛片?v一区二区三区| 欧美乱伦专区| 操逼网免费无码视频| 国产 亚洲 丝袜 制服| 国产亲戚伦亲在线| aⅴ日韩成人电影av在线免费看av大全 | 国产一区二区在线播放量| 亚洲无线观看久久| 777琪琪午夜免费A片| 国产最新小视频在线播放下载| 91啦人妻| 国产精品久久久久亚洲av | 99热国产| 中文乱码字幕观看视频| 奇米四色影视777久久久| 国产一级内射无挡观看| 精品伊人久久久大香线蕉小说| 精品伊人久久久大香线蕉小说| HEYZO高无码国产精品227| 久久亚洲AV无码专区国产精品 | 内射黑人| 91欧美巨乳| 日韩本不卡视频在线观看 | 国产视频一区二区在线| 99国产精品久久久在线播放| 亚洲区小说| 超碰美女97| 你懂的在线观看区国产| 国产精品久久久三级无码| 五月丁香| 欧美一区二区成人一卡| 久久久久久久久久久久97| 国产精品扒开腿做爽爽爽视频| 国产1024在线播放| 久久久精品视频免费观看| 婷婷丁香五月激情啪啪| 久久99黄色卞西瓜| 久湿久久| 成 人片 黄色大片| 日韩素人无码一区二区三区三州| 日韩啪啪啪视频| 亚洲乱熟女一区二区| 999热这里只有精品| av绯色| 色婷婷电影| 有码免费观看| 97视频免费| 1769一区| 国产激情视频在线观看| 91精品婷婷国产综合久久竹菊| 青青草原香蕉日本Ap| 操逼视频色| 婷婷久久五月| 男人的天堂无码| 麻豆久久一区二区三区| 91精品人妻电影| 蜜臀在线免费观看在线免费观看| 中文字幕一区二区三区人妻不卡| 人妻系列无码专区中文有码| 久久宗合亚洲| 亚洲伊人a线观看视频| 熟女精品一区二区三区| 天天干夜夜肏| 中文字幕日本久久| 都市激情人妻一区二区青青操视频 | 欧美性爱中文字幕无线码| 欧美久久草熟女| 久久久久久久久久久久97| 久久av成人无码免费| 日本熟人妻中文字幕在线|...久久国产精品-国产精品_日本一区二区三区中文字幕 | 亚洲激情综合| 久艹免费| 久久久久免费少妇| 久久大香蕉97| 很很热性爱视频| 欧美一级专区免费大片| 久久三| 亚洲精品97中文字幕| 国产精品人妻无码久久久老鸭窝 | 久久AV无码AV| 亚洲精品久久久久久久久豆丁网| 97在线视频网站| 99综合免费视频| 中文字幕一区二区三区人妻不卡 | 天天亚洲综合| 少妇厨房愉情理伦片bd在线观看 | V A在线| 亚洲人精| 久草尤物| 丝袜高跟澳门91视频| 精品一区二区综合熟妇| 视频黄站| 久热91| 国产路线专区| 日韩中字av一区| av毛片aaaaa免费看| 91人妻人人妻| 人人贴人人摸| 日本黄页视频在线观看| 91强奸乱轮| 漂亮人妻被强中文字幕hd| 91婷婷| 人人操人人色网| 精品四五区| a片偷拍视频| 91欧美成人色站| 中国一级操逼视频| 91欧美www| 精精夜夜| 91精品啪在线观看国产城中村| 欧美亚洲韩国视频十五区| 超碰人人超在线观看| 日本道人妻久久久在线不卡色视频| 久久五月婷| 又大又大又大又粗爽高潮观看| 丰满翘臀美女影院视频| 欧美日韩在线国产在线| 91热| 日本99一区二区| 一区二区三区免费岛国片| 国产少妇内射| 岛国小电影| 手机在线人成免费视频| 国产精品天堂| 日本天堂在线播放| 9/A片 | 精品一久久久| 99精品网| 亚洲黄色a级片| 欧亚日韩中文在线| 激情黄色五月天| www.婷婷| 午夜偷拍久久熟女| 男人的天堂午夜av| 91欧| 国产精品粉嫩福利在线| 四虎国产成人精品免费一女五男| 欧美综合站| 91成人久久| 中英熟女操女| 人人操人人摸超碰| 九九九只有精品| 一区 欧美 日韩 麻豆| 97久久视频| 久久九九视频九九视频| 久久狠狠色噜噜狠狠狠狠97| 欧美日韩亚洲少妇寂寞影院正在播放 | 顶级丝袜熟女一区二区三区 | 亚洲男人的天堂V| 秋霞视频一区二区 | 玖玖草久草99蜜月一区二区三区| 日韩在线AB| 激情综合婷婷| 久久久久9999| 丁香六月婷婷久久综合| 99日精品欧美国产| 国产精品久久久久久片| www.91人妻.com| 欧美一级黄色免费专区| 久艹日日日| 欧美精品系列| 超碰97人人乐| 欧美色图99| 蜜臀av网址| 亚州高清色综合| 婷婷五月天无码 | 久久久久久久97| 日本一二三免费久久| 嫩草黄页| 超碰欧美97资源| 久久原创中文| 台湾佬中文娱乐网久久久久久久久久com | 中文字幕乱亚洲美女精品一区| 精品少妇高潮久久| 亚洲 欧美综合| 9久9久9久9久视频网站| 精品丰满熟妇人妻一区| 限制级中的三级片中的黑粗大屌屌日人妻熟女| 欧美熟妇亚洲版| 亚洲自拍一区夜夜操| 中文字幕超碰CAO| 男人的天堂2000| 黄色片G G G| 走光一区92下载| 久久宗合亚洲| 欧美亚洲韩国视频十五区| 97伊人超碰| 亚洲高清91| 国产精品人妻无码久久久老鸭窝| 日韩性爱视频在线免费观看| 国产一区二区在线电影| 六月丁丁香| 国产后入精品| 操淫穴亚洲五月丁香 | 97精品久久久久中文字幕| 日本道日本道中文字幕日本道最新日本道在线观看 | 日日超碰亚洲| 欧美视频一区二区在线| 99ri在线视频| 动漫片子网站3黄| 婷婷10月天青娱乐| 久久久久久久久久久久九| 青娱乐久久艹| 农村妇女一级二级三级视频| 色狠狠综合噜一二三区| 久久精品视| 欧美 亚洲精品首页| 久久婷婷电影网| 国产网红精品| 嗯啊不要在线| 久日综合网| 欧美日韩久久精品爱爱| 久久精品国产99精品亚洲蜜...| 99久久久er直播网址| 五月天激情网图片| 亚洲。天堂。日本在线观看| 精品人妻av区天天看片| 日本免费专区| 91N五十路| 久久久91福利姬| 91狠狠| 人妻aa| 97爱亚洲综合色| 在线啊啊啊| 无码人妻一区二区三区色欲aⅴ| 奇米狠999| 色av中文字| 欧美图片色五月天| 精品欧美А∨无码黑人大荫蒂 | 白丝jkav| 免费一二区| 日韩黄色一区二区三区| 78久久久| 大学生美女口爆| 色五月激情网| 玖日综合网| 国产乱伦性爱区| 日本三级人妻a人妻一在线| 欧美一区二区三熟女剧情| 呦呦影院| 福利风月五月天影院| 97精品一区二区视频在线观看| 在线岛| 96AV久久久| 天天综合网日韩| 婷婷五月天影院| 美国三级日本三级久久99| 乱伦一二三区| 欧洲Au麻豆| 一区二区不卡视| 精品久久久亚洲AV成人网站| 熟妇高潮二区三区| 日本色色色视频| 少妇色综合| 久久黄色视频一区二区三区| 欧美一二在线| 成在线人在线观看视频| 欧美91在线+|+欧美| 欧美不卡五十路| 偷拍欧美激情| jizz啪啪| 亚州久久9| 91碰超| 亚洲日韩乱码中文无码蜜桃臀网站| 天天躁日日躁成人字幕aⅴ| 91 丝袜在线| 久思思热视频在线观看| 欧美亚州色的图| 亚洲最新a在线观看| 在线小视频| 国产精品999zyz| 男人的天堂久久狠| 大香蕉人妻| juliaann丝袜| 久久內射| 操逼网免费无码视频| 97射欧美| 麻豆 欧美 日韩| 国产精品不卡av免费在线观看| 亚洲AV乱码专区国产噜噜亚洲| 国产精品白领在线观看| 伊人伊人LD| 一本一道vs波多野结衣| 96超碰网| 亚州精品丝袜-不卡成人免费| 亚洲天堂一区二区久久| 欧美亚洲色的图| 丁香六月婷婷久久综合| 久久这里只精品免费福利| 久热大香蕉网站| 99热思思| 综合久久久久久久综合网| 久久精品高清无码一区| 亚洲人成色9999精品久久| 欧美探花网| 97在线日韩中文字幕| 99青草| 26uuu国产日韩综合在线观看| 国内外毛片在线观看| 口爆综合网| 日韩人妻一二三区视频| 日本不卡一二区| 欧美 日韩 另类 亚洲| aⅴ日韩成人电影av在线免费看av大全| 强乱老妇中文字幕| 国产美女激情| 天天流夜夜操| 久久亚洲AV成人精品无码| 色香欲影| 97在线欧| 亚洲欧美一区二区不卡视频播放 | 丁香7月婷婷| 欧州色图区| 日韩人妻 中文字幕| 97av在线观看| 欧美色图99| 天美精品一区二区三区四区在线观看| 五月婷婷激情网| 超碰成人最新最好看| 国产v亚洲v日韩v欧美v片另类| 欧亚揄拍偷拍精品视频| 精品美女在线视频| 国产在线76页| 999岛国大片| 日韩99精品视频综合区| 欧美中出| 欧美一二三| 丝袜美腿91| 色情婷婷久久五月天| 亚洲欧洲精品成人| 日本一二区免费| 激情五月婷婷| 99日精品欧美国产| 天堂中文资源在线bt| 国产视频一区二区三区在线免费观看| 亚洲天天操| 色爱亚洲| 久久精品熟妇丰满人妻99| 老熟妇一区二区三区| 天天内射| 少妇内射www在线观看视频| 午夜福利久久久噜久噜久久综合 | 亚洲国内精品成人不卡| 超碰 av 女人天堂| 欧美永久激情一区二区| GVH-003 母子姦 青木玲-麻豆视频,麻豆视传媒短视频网站入口,麻豆视传媒官网直 | 国产成年女黄特黄| 青春草莓视频在线观看网址| 啊啊啊啊操死我| 天天亚洲| 欧美色偷偷| 欧美色图20p| 91亚洲综合| 亚洲在线| 香伊人在线| 免费啪啪av| 日韩久久.一级黄色片| 国产操逼逼网| 99久久久久| 久久五月丁香| 日韩偷拍色图| 夜夜高潮夜夜爽| 欧美性爱一区二区三区四区| 欧美精品三区| 超碰97人人乐| 啊啊啊在线观看| 手机午夜电影神马久久| 一级片在线观看高清无码| 家庭乱伦性爱av| 激情五月天丁香社区| 色九月婷婷| 人妻精品综合中文字幕在线| 亚洲和欧美裸体美女双飞视频| 日本免费一区二区不卡| AV有码在线| 亚洲乱码精品一区二区| 中日韩久久久| 天天舔天天| 蜜臀99999| 97超碰影音| 一区二区三区国产在线播放| 亚欧性爱无码| 天天操夜夜操| 青青伊人久久| 97在线看| 蜜乳性色无码专日粉嫩骚逼AV| 婷婷在线精品| 97精品97| 亚洲在线a| 亚洲字幕一区二区| 2010男人的天堂| 午夜后入| 老女人综合网| 国产尹人在线视频免费| 色鬼在线综合| 无套后入双马尾| 亚洲?V无码专区在线电影| 青青草天天亲夜夜操网| 91欧美美女日韩国产婷婷| 熟女少妇视频| 91人妻素女| 亚洲日本男人天堂网| 日韩电影免费网站麻豆视频| 亚洲无码超碰免费| 欧美熟女少妇| 久久久久幕乱码| 国产美女口爆吞精视频| 丁香六月激情| 呻吟 欧美 日本 中出| 五月丁香黄色网| 99激情| 激情久久日韩精品中文字幕麻豆| 一区AV| 69超碰综合| 亚洲少妇自拍中文字幕懂色| 黄色视频60分钟| 欧美日韩国第一区| 美女91在线| 日本污ww视频网站| 欧美精品,四区。五区| 国产午夜福利专区综合| 亚洲天天艹| 欧美天天搞| 久久女婷| 少妇天堂| 五月婷婷综合网| 91久热| 精品久久人妻成人网| Aa东京男人的天堂| 日韩欧美tv一区二区在线观看| 亚洲人妻熟妇三十三区| se吧提供91精品国产91久久久久久| 成人欧美一区二区三区黑人一| 精品大全99999| 国产精选三级在线观看| 51一区二区三区| 亚洲中文字幕精品久久久久久直播| 少妇第一页| 太久视频| 人妻另类| 九九九九久久久| 欧美亚洲激情| 区一在线观看| AV和黑人在线播放| 精品美女久久一二三| 日韩欧美国产一区二区三区四区| 60秒免费小视频| 黄色网址在线免费观看| 亚洲区小说| 日本99视频| 欧美人妻少妇| 操逼精品视频| 国产 日韩 欧美 中文 另类,国产 欧美 另类 制服 变态,高清 日韩 欧美 中文,高 | 人人摸人人干| 电家庭影院午夜69久久夜色精品国产69乱| 日本不卡高清免v欧美日韩在线观看| 国产一级舔足在线观看| 久久鲁夜| 欧美成人一区二区三区在线播放| 91久久国产精品| 精品女人999| 八戒午夜福利理论片| 九一综合网| 啪啪综合网| 伊人热综合| 久久美国毛片| 综合色图区| 强奸乱伦免费网站| 97在线亚洲| 久久综合18p| 国产av波波国产精品| 色九色久| 口爆欧美91| 久久性爱大全| 亚洲无码视频免费在线观看网址!| 99热导航| 五月婷婷丁香六月| 99久久久无码精品国产人| 国产日韩中文字幕欧美| 国产日韩精品一区二区三区| 污污汅18禁网站在线永久免费观看| 美女天天干| 日韩二三区| 九热视频| 在线观看免费视频国产| 99热一区二区三区四区| 美欧老女人97| 大香蕉碰碰| 中文字幕交换人妻| 亚洲高清视频在线免费观看| 超碰免费欧美7| 麻豆视频test| 亚洲高清无码免费观看视频| 天天做天天爱夜夜爽毛片试看| 亚洲综合草草| 伊人久久大香线蕉亚洲五月天,青草青草欧美日本一区二区,欧美日产欧美日产国产 | 亚洲欧美色图小说| 亚洲小说视频| 亚洲诱惑天堂 | 超碰97极品9| 国产精品久久久久久久久久久久久久久| 天天干,天天日| 欧美久久人人网| 操逼视频国产无套| 91狠狠综| 欧美劲爆第一页| 久久久久深夜无码| 伊人久久大香线蕉亚洲五月天,青草青草欧美日本一区二区,欧美日产欧美日产国产 | 青青草在线视频美女| 久久国产对白激情浪潮| 性色avv| 能看的av| 五月婷婷激情综合| 午夜无码精品免费看性色| 亚洲天堂五月天国产| 中文字幕后石码四区五区| 啊啊啊啊,啊啊好多水| 大乔未久88一区| 怡春苑东京热| 啊啊啊啊啊好大好舒服想要| 99热色这里只有精品| 五月香婷婷| 激情五月丁香五月| 97人人射| 人妻AV在线| 五月丁香| 五月婷婷综合网| 久久精品国产精品亚洲艾通辽熟妇 | 伊人久久大香线蕉亚洲五月天,青草青草欧美日本一区二区,欧美日产欧美日产国产 | 91黑人无码激情在线| 人人人人插| 在线强奷到舒服的无码视频 | 91高清日| 黑人在线91| 舔足天天操天天射| 欧美人妻少妇| 亚洲人妻在线精品| 无码久久亚洲高清,| 粉嫩av平台| 成人性爱AV在线免费观看| 第四色奇米影视777| 中文字幕日韩电影人妻| 加勒比在线观看一区二区| 操逼免费视频无码国产| 中文字幕精品一区二区精| 久久久久久久国产a∨| 国产AV无码AV| 国产成人网| 久无码| 老熟妇综合| 亚洲综合 欧美| 国产精品另类一区大香蕉| 欧美综合综合| 啪啪视频免费在线观看| 国产一区二区三三视频| 亚洲最大的综合性av| 极品极品色影院| 欧日韩不卡视.频| 狠狠搞 亚洲91| 午夜无码熟妇丰满人妻| 亚欧美综合网| 操操逼视频| 国产精品自产拍在线观看社区| 日本三级大片| 91av天美性媒精品视频| WWW美腿丝袜香蕉中文| 91精品人妻一区二区三区蜜桃| 亚洲无992tv| 久久久国产亚洲精品系列| 91Chinese在线| 精品久久久久黄少妇| 丝袜色综合| 男人天堂网站| 亚洲欧美日韩精品久久久一区二区| 五月婷婷大香蕉| 99在线观看无大码| 欧美色九九| 国产 日韩 欧美高清| 婷婷久久综合| 天堂伊人久久| 中文字幕三四区| 黄色视频特级毛片| 日韩精品高清资源在线| 日韩欧美久久婷婷网站| 亚洲国产精品成人综合| 欧美 亚洲 偷拍自拍| 超碰1024久久| 91制服丝袜中文字幕| 精品久久久久av影院| 色哟哟国产精品免费网址| 偷拍新久久| 亚洲囯产精品女人久久久| 国产91美女高潮| 天操天操夜操夜月月年年操操| 日韩性爱小视频| 97色在线| www久久精品| 亚洲性爱免费电影| 中文字幕91综合| 国产精品97视频| 日韩精品 视频一区二区| 亚91亚洲网| 亚洲天堂资源网| 人妻-91porn| 中文字幕久久亚州无码| 精品人妻视频入口| 神马久久久久眼| 国内毛片四区| 国产精品久久久久久久久AV大片| 97精品97| 欧美大香蕉久| 天天日日本| 婷婷色综合欧美日韩| 五月丁香激情综合网| 天天在线91| h无码动漫在线观看| 久操网在线| 亚洲图片日本AⅤ欧美在线| 精品网站9999| 超碰97色| 九久久九精品视频| 欧美精品宗合| 日本免费一区二| TS人妖另类精品视频系列| 日韩有码免费视频| 东京热毛片177b2viP| 裸体美女免费看网站青草| 天堂性色| 精品精品精品| 欧美一级A一级a爱片久久| 精品丰满人妻一区二区三区免费观| 亚洲图片小说欧洲| 97人人干| 亚洲色图91| 欧美久久婷| 美国黄片aaa| 久久超碰大香蕉| 精品亚洲国产成人精品| 加勒比综合a∨| 精品人妻美妇91job| 无马一区二区| 色av中文字| 午夜福利国产欧美日韩夜夜| 天天综合网1| 国产高清MV操逼视频| 热热色国产一二区AV| 超碰免费人人| 天堂无码| 欧洲一区二区三区免费| 国产精品制服丝袜清纯唯美 | 亚洲最大AV网| 91bbbbbb| 宗合情欲网| 色色香蕉| 大香蕉中文网| 久久婷婷在线观看视频| 久久东京伊人一本到鬼色| 国产精品97超碰| 天美AV片| 无码天天操| 清纯唯美第一页| 超碰亚洲欧美日韩无| a一区二区三区乱码在线| 久久久久久久综合,国产| 爽爽淫人网| 在线色导航| 亚洲高潮影院| 日韩99神马视频播放| 国产懂色精品国产av| 九九九九热| 亚洲熟女偷拍在线观看| 日日狠狠久久偷偷色综合免费| 少妇熟女1区2区3区| 中精品一区二区三区| 亚洲综合97中文网| 秋霞蝌科网日本一区| 91丨人妻丨国产丨丝袜| 97精品97久久| 久久久久久久少妇| 被体育老师抱着c到高潮| 亚洲婷婷丁香在线| 福利五区| 亚洲国成人情色好看电影| 亚洲综合婷婷| 欧美αv.com| 九九热九九| 综合情欲网| 成人色女网| 蜜臀av在线播放一区二区三区| 色综合天天| 欧美一级在线观看成人| 97在线/亚洲| 中文字幕人乱码中文字的预防方法 | 欧亚日韩综合精品国产| 有码免费观看| 欧美日韩成人| 免费A V在线播放| 性爱网站一区二区| 综合 亚洲 欧美| 四虎884| 色悠久久久av| 精品无码一二三四区| 久久久精品日本一道| 婷婷亚洲色| 精品亚洲国产成人AV制服丝袜| 国产精品久久久久久久电影渣男| 久久久久久久久久9| 欧美第五页| 蜜桃视频啊啊啊啊| 婷婷五月天无码| 欧美婷婷久久| 国产性刺激| 亚洲欧洲美腿丝袜| 欧美亚洲综合色| 天天做天天爱天天爽| 一级A啪啪啪啪| 久久久免费一级黄片| 亚洲精品国产熟女久久久久久| 日韩欧洲操屄视频| 日韩一级久久毛片| 久久精品国产亚洲AV先锋| 神马麻豆福利院| 一卡二卡三卡| 中国韩国明星一极片一区乱码毛片人妻熟女一区二区三区 | 天堂无码| 百度百度日本操逼| 国产呦精品系列在线观看| 天天插网| 国产资源中文字幕在线 | 啊啊啊好大好湿| 精品9区| 久9久精品视频| 少妇专区一二三四五| 青青欧美| KK色在线影院| 一二三区视频在线观看| 99re视频这里只有精品| 九九九九九精品| 思思热一热婷婷热一热| 中国熟妇| 97免费在线观看| 国产又黄又爽| 国产传媒午夜理伦精品| 夜夜天天噜狠狠爱2021| 国产精品久久久久中文字幕| 一级久久久久久久久久久| 中文字幕 国产 精品| 日本福利社| 欧美天堂日韩三级国产传媒| 免费网站观看www在线观| 欧洲小说色图视频另类| 天天热精品| 97这里有精品| 色综合一本| 探花一区二区三| 亚洲av乱伦色图网站| 亚洲性爱高潮影院| A啊啊在线观看| 9ⅰ久久久天天| 91成人无码| 澳门黄片一香蕉视频| 久久婷五月| 国产按摩一区二区三区| 日韩伦理视频| 欧洲小说色图视频另类| 蜜臀中文无码午夜| 最新国产精品| 免费在线黄片视频| julia高潮后不停追击中出| 色诱中文字幕| 男人的天堂三级| 97超碰人人操人人操| 中国乱伦一区二区| 男人兔费天堂| ai欧美亚洲小说| 精品午夜福利| 国产成人手机视频激情| 爽爽歪在线视频| 久久久久921| 男人午夜天堂| a级理论午夜日本| 麻豆久久久久久久久丝袜| 精品一区二区久久| 搡老熟女免费视频| 色婷婷五月综合激情中文字幕| 日韩影片中文字幕一区二区三区| 欧美色图97| 色在线综合| 天堂岛av| 欧美综合色综合| 无码久久亚洲高清,| 超碰在线成人| 亚洲综合情色| 被操高清无码视频| 日韩一区二区精品视频| 欧洲亚洲综合| 国内精品久久人妻性色av| 五月天婷婷基地| 综合一区二区影视| 亚洲熟女乱色一区二区三区| 亚洲激情久久| 亚洲,欧美,综合网| 成人无码电影在线观看网| 婷婷香蕉欧美在线一区二区三区| 舔舔啊| 国产精品无码av| 亚洲永久永久永久永久一级一级一级精品 | 欧美熟妇亚洲版| 18禁止看精品中文字幕| 欧美后进式| 91免费看中出视频| 91丨熟女丨丰满熟女| 久久久久久久久久久999| 12一15性XXXX粉嫩国产| 爽爽淫人网| 久草免费在线视频| 9久久精品| 啊啊啊轻点在线观看| h无码动漫在线观看| 亚洲 另类 丝袜 自拍 动漫| 久久精品国产欧美日韩亚洲欧美日韩中文久久国产一区 | 涩综合导航| 日韩AV一区二区三区三州三州| 亚洲色宗合| 美中韩AV综合网| 偷拍视频青青草在线视频| 五月丁香大香蕉| 欧美日韩狠狠爱| 色播综合| 超碰97COm中文| 天综合网| 国产在线综合福利网站| 厕所偷拍在线| 乱性AV| 国产午夜视频| 婷婷去俺也去六月色| 9999九九九久久久| 人人操人人摸人| 5252色欧美在线男人的天堂| 黄色av一区二区在线| 久久日韩肥臀| 情侣开房子拍 日韩无码 女的很漂亮| 日本一二区不卡| 色月天AV导航| 久久精品国产AV一区二区三区| 97色色国产视频| 欧洲成人性爱视频| 久久宗合97| 夂久色| 在线播放成人高清免费视频| 久久久穴999| 日本激情免费大片| 东京男人天堂| 天天综合在线4| 亚洲精品乱码线路中文字幕| 中文字幕女同在线| 90后性网国产欧美| 国产97在线视频| 国厂麻豆77q4| 一级A啪啪啪啪| 欧美综合自拍| 欧美国产一区二区三区麻豆传媒| 青草青草久热| 国产精品96久久久久久| 狠狠干精品一二三四五六2022| 超97在线精品视频| 欧美激情高清性猛交| 亚洲国产一级中文综合久久天堂在线免费观看 | 国产免费一区在线观看| 女性91网站| 欧美论理片| 五月婷婷六月天| 久久久精品91八戒| chaopen97久久| 蜜臀在线免费观看在线免费观看| 日韩亚洲中文有码视频| 亚洲高清91| 97视频900| 极品色社| 91快色色色色色| 一区二区高清视频| 狠狠做深爱婷婷久久二区| 欧美日韩丝袜| 人人摸人人干人人拍97| 超碰95| 99视频自拍区| 99蜜桃臀亚洲成人在线观看| 99自拍视频| 国产精品久久久久亚洲av| 亚洲欧美不卡线| 久男人久久| 欧洲精品在线播放| 婷婷丁香六月天| 93人人操人人| 最新无码国产| 色吊丝 日日骚 清纯唯美| 蜜臀99999| 九九热精品免费视频| 午夜黄色免费在线观看| 99re热有精品视频国产| 日本媚薬中文字幕在线| 超碰免费欧美7| 色眯眯射| 国产乱码久久| 五月天大香蕉| 國產尤物AV尤物在線觀看| 久9re热视频这里只有精品| 久久久久久十| 欧美日韩国产色五月综合在线| 精品一区二区麻豆| 国产天天骚| 日本天天吊| 99在线精品视频| 免费看日本操逼视频| 男人高清无码一区二区| 91伊人久| 99人妻碰碰碰久久久久禁片| 91人妻人人澡人人爽人人精品| 中文字幕免费看| 亚洲性感丝袜诱惑在线观看| 欧美色997| 裸模AV女优| 国产久久视频| 嫩草 人人网精品| 99久久com免费视频′| 激情五月综合网| 99这里有精品视频| 99精品在线观看| 婷婷色五月激情| 五月婷婷激情网| 毛片电影一区二区三区| 超碰社区97| 93人人操人人| 天天干干天天干干| 人妻中文字幕精品无码| 蜜乳视频网站| 亚洲高清无毛一区二区| 午夜男女爽爽大片免费观看| 99久久久无码国产精品性啊聊| 97 色综合| 中文字幕欧美日韩三级| 久久久新亚洲AV| 测评在线观看AV| 三级日本一区二区三区| 国产乱伦亚洲色图高清无码| 午夜视频黄| 九月丁香婷婷色| 国产高清在线观看欧美| 国产剧情AV不卡在线观看| 留下AⅤ黄色片| 操91| 日韩美女久久一区二区三区| 男女激情中文字幕| 狠操91,com| 91亚洲黄色网|