From a7420f5ae0a5c7a1186e25d7baa80e791fb13b91 Mon Sep 17 00:00:00 2001 From: cph Date: Wed, 9 Oct 2024 20:21:33 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=AC=E6=AD=8C=E8=AF=86=E6=9B=B2=E5=AE=8C?= =?UTF-8?q?=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/MusicController.java | 6 +- .../com/cph/musicbackend/entity/Music.java | 2 + .../cph/musicbackend/rd3/AcrCloudUtil.java | 1 - .../src/main/resources/application.yaml | 12 +- package-lock.json | 14 ++ package.json | 1 + src/App.css | 19 ++ src/App.js | 231 ++++++++++++++++-- src/assets/images/micro.png | Bin 0 -> 27228 bytes src/assets/images/tinggeshiqu.png | Bin 0 -> 7441 bytes src/assets/images/tinggeshiqu40x40.png | Bin 0 -> 8438 bytes src/components/MusicPlayer.tsx | 5 +- src/utils/api.js | 4 +- 13 files changed, 260 insertions(+), 35 deletions(-) create mode 100644 src/assets/images/micro.png create mode 100644 src/assets/images/tinggeshiqu.png create mode 100644 src/assets/images/tinggeshiqu40x40.png diff --git a/musicBackend/src/main/java/com/cph/musicbackend/controller/MusicController.java b/musicBackend/src/main/java/com/cph/musicbackend/controller/MusicController.java index a0ef282..b481864 100644 --- a/musicBackend/src/main/java/com/cph/musicbackend/controller/MusicController.java +++ b/musicBackend/src/main/java/com/cph/musicbackend/controller/MusicController.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.util.Date; import java.util.List; +import java.util.Map; import java.util.stream.Collectors; @RestController @@ -101,6 +102,7 @@ public Object like(@RequestBody Music song) { } @PostMapping("/api/uploadAudio") + @RecognizeAddress public Object recongnizeMusic(@RequestParam("audio") MultipartFile file) { if (file.isEmpty()) { return "{\"error\": \"请选择一个文件上传\"}"; @@ -116,7 +118,9 @@ public Object recongnizeMusic(@RequestParam("audio") MultipartFile file) { // 保存文件 File destFile = new File(dir.getAbsolutePath() + File.separator + fileName); file.transferTo(destFile); - return acrCloudUtil.recongizeByFile(dir.getAbsolutePath() + File.separator + fileName); + Map resultMap = acrCloudUtil.recongizeByFile(dir.getAbsolutePath() + File.separator + fileName); + musicMapper.insert(new Music().setArtist(resultMap.get("artist")).setTitle(resultMap.get("title"))); + return resultMap; // return MusicRecUtil.recongnizeFile(dir.getAbsolutePath() + File.separator + fileName); } catch (IOException e) { diff --git a/musicBackend/src/main/java/com/cph/musicbackend/entity/Music.java b/musicBackend/src/main/java/com/cph/musicbackend/entity/Music.java index 0fe1306..2bad33f 100644 --- a/musicBackend/src/main/java/com/cph/musicbackend/entity/Music.java +++ b/musicBackend/src/main/java/com/cph/musicbackend/entity/Music.java @@ -4,10 +4,12 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import lombok.Data; +import lombok.experimental.Accessors; import java.util.Date; @Data +@Accessors(chain =true) public class Music { @TableId(type = IdType.AUTO, value = "id") diff --git a/musicBackend/src/main/java/com/cph/musicbackend/rd3/AcrCloudUtil.java b/musicBackend/src/main/java/com/cph/musicbackend/rd3/AcrCloudUtil.java index b97b690..741b596 100644 --- a/musicBackend/src/main/java/com/cph/musicbackend/rd3/AcrCloudUtil.java +++ b/musicBackend/src/main/java/com/cph/musicbackend/rd3/AcrCloudUtil.java @@ -22,7 +22,6 @@ public Map recongizeByFile(String filename) { HashMap resultMap = new HashMap<>(); String result = re.recognizeByFile(filename, 1); // 使用示例结果进行解析 -// String result = "{\"status\":{\"msg\":\"Success\",\"version\":\"1.0\",\"code\":0},\"metadata\":{\"timestamp_utc\":\"2024-10-08 12:08:34\",\"music\":[{\"lan\":\"国语\",\"duration_ms\":200000,\"external_ids\":{},\"db_begin_time_offset_ms\":4080,\"artists\":[{\"name\":\"周杰伦\"}],\"db_end_time_offset_ms\":14600,\"sample_begin_time_offset_ms\":0,\"sample_end_time_offset_ms\":10520,\"play_offset_ms\":15540,\"result_from\":3,\"title\":\"前世情人\",\"label\":\"JVR\",\"score\":100,\"acrid\":\"e3c887cf408db8991a68a843f1afd5a0\",\"language\":\"zh\",\"external_metadata\":{},\"release_date\":\"2016-06-24\",\"album\":{\"name\":\"周杰伦的床边故事\"}},{\"duration_ms\":200460,\"external_ids\":{},\"db_begin_time_offset_ms\":4060,\"artists\":[{\"name\":\"周杰伦\"}],\"label\":\"杰威尔音乐有限公司\",\"db_end_time_offset_ms\":14500,\"sample_begin_time_offset_ms\":0,\"sample_end_time_offset_ms\":10440,\"play_offset_ms\":15520,\"result_from\":3,\"title\":\"前世情人\",\"score\":100,\"language\":\"zh\",\"acrid\":\"0eb1c19384ec445e15c6cb3c11c706ba\",\"release_date\":\"2016-06-24\",\"external_metadata\":{},\"album\":{\"name\":\"周杰伦的床边故事\"}}]},\"result_type\":0,\"cost_time\":0.029999971389771}"; System.out.println(result); try { diff --git a/musicBackend/src/main/resources/application.yaml b/musicBackend/src/main/resources/application.yaml index 2f2a78f..dfd9c42 100644 --- a/musicBackend/src/main/resources/application.yaml +++ b/musicBackend/src/main/resources/application.yaml @@ -33,15 +33,15 @@ mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl mapper-locations: classpath:mybatis/*.xml - -file: - upload: - path: /root/nginx/share/nginx/media/ - url: https://app102.acapp.acwing.com.cn/media/ +# #file: # upload: -# path: D://audio// +# path: /root/nginx/share/nginx/media/ # url: https://app102.acapp.acwing.com.cn/media/ +file: + upload: + path: D://audio// + url: https://app102.acapp.acwing.com.cn/media/ logging: level: diff --git a/package-lock.json b/package-lock.json index 4ade850..df8d362 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "axios": "^1.7.7", + "lamejs": "^1.2.1", "react": "^18.3.1", "react-audio-player": "^0.17.0", "react-dom": "^18.3.1", @@ -12445,6 +12446,14 @@ "node": ">= 8" } }, + "node_modules/lamejs": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/lamejs/-/lamejs-1.2.1.tgz", + "integrity": "sha512-s7bxvjvYthw6oPLCm5pFxvA84wUROODB8jEO2+CE1adhKgrIvVOlmMgY8zyugxGrvRaDHNJanOiS21/emty6dQ==", + "dependencies": { + "use-strict": "1.0.1" + } + }, "node_modules/language-subtag-registry": { "version": "0.3.23", "resolved": "https://registry.npmmirror.com/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz", @@ -17578,6 +17587,11 @@ "requires-port": "^1.0.0" } }, + "node_modules/use-strict": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/use-strict/-/use-strict-1.0.1.tgz", + "integrity": "sha512-IeiWvvEXfW5ltKVMkxq6FvNf2LojMKvB2OCeja6+ct24S1XOmQw2dGr2JyndwACWAGJva9B7yPHwAmeA9QCqAQ==" + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmmirror.com/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/package.json b/package.json index 3f7d555..ea97394 100644 --- a/package.json +++ b/package.json @@ -8,6 +8,7 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "axios": "^1.7.7", + "lamejs": "^1.2.1", "react": "^18.3.1", "react-audio-player": "^0.17.0", "react-dom": "^18.3.1", diff --git a/src/App.css b/src/App.css index f14cf51..69401c7 100644 --- a/src/App.css +++ b/src/App.css @@ -123,3 +123,22 @@ html, body { width: 150px; height: 150px; } + +@keyframes breathe { + 0% { + transform: scale(1); + opacity: 0.8; + } + 50% { + transform: scale(1.05); + opacity: 1; + } + 100% { + transform: scale(1); + opacity: 0.8; + } +} + +.breathing-image { + animation: breathe 2s ease-in-out infinite; +} \ No newline at end of file diff --git a/src/App.js b/src/App.js index 8642ed0..9ae30e7 100644 --- a/src/App.js +++ b/src/App.js @@ -4,9 +4,13 @@ import './App.css'; import PlayList from './components/PlayList.tsx'; import 'react-vant/es/styles'; import MusicPlayer from './components/MusicPlayer.tsx'; -import React, { useState, useEffect, useCallback, useRef } from 'react'; -import { Image, Toast, Search } from 'react-vant' +import React, { useState, useEffect, useRef, useCallback } from 'react'; +import { Image, Toast, Search, Loading, Space } from 'react-vant' import { instance } from './utils/api'; +import { Music, MusicO, Close, createFromIconfontCN } from '@react-vant/icons'; +import tinggeshiqu from './assets/images/tinggeshiqu.png'; +import tinggeshiqu40x40 from './assets/images/tinggeshiqu40x40.png'; + // 添加获取 URL 参数的函数 function getParameterByName(name, url = window.location.href) { @@ -18,6 +22,42 @@ function getParameterByName(name, url = window.location.href) { return decodeURIComponent(results[2].replace(/\+/g, ' ')); } +// 添加以下辅助函数 +function writeString(view, offset, string) { + for (let i = 0; i < string.length; i++) { + view.setUint8(offset + i, string.charCodeAt(i)); + } +} + +function floatTo16BitPCM(output, offset, input) { + for (let i = 0; i < input.length; i++, offset += 2) { + let s = Math.max(-1, Math.min(1, input[i])); + output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true); + } +} + +function writeAudioBufferToWav(audioBuffer, numChannels, sampleRate) { + const buffer = new ArrayBuffer(44 + audioBuffer.length * 2); + const view = new DataView(buffer); + + writeString(view, 0, 'RIFF'); + view.setUint32(4, 36 + audioBuffer.length * 2, true); + writeString(view, 8, 'WAVE'); + writeString(view, 12, 'fmt '); + view.setUint32(16, 16, true); + view.setUint16(20, 1, true); + view.setUint16(22, numChannels, true); + view.setUint32(24, sampleRate, true); + view.setUint32(28, sampleRate * numChannels * 2, true); + view.setUint16(32, numChannels * 2, true); + view.setUint16(34, 16, true); + writeString(view, 36, 'data'); + view.setUint32(40, audioBuffer.length * 2, true); + + floatTo16BitPCM(view, 44, audioBuffer); + + return new Blob([view], { type: 'audio/wav' }); +} function App() { const [currentSong, setCurrentSong] = useState(null); @@ -27,41 +67,36 @@ function App() { const searchRef = useRef(null); const searchInputRef = useRef(null); const [isShowPlayList, setIsShowPlayList] = useState(false); - // 添加 sourceEnv 状态 const [sourceEnv, setSourceEnv] = useState(null); const playlistRef = useRef(null); + const [isRecording, setIsRecording] = useState(false); + const [mediaRecorder, setMediaRecorder] = useState(null); + const [audioContext, setAudioContext] = useState(null); + const [audioInput, setAudioInput] = useState(null); + const [recorder, setRecorder] = useState(null); useEffect(() => { - // 获取 sourceEnv 参数 const envParam = getParameterByName('sourceEnv'); setSourceEnv(envParam); console.log('sourceEnv:', envParam); - // 根据 sourceEnv 的值执行相应的操作 if (envParam) { switch (envParam) { case 'production': - // 生产环境的逻辑 console.log('Running in production environment'); - // 这里可以添加生产环境特定的逻辑 break; case 'plugin': - // 开发环境的逻辑 console.log('Running in development environment'); - // 这里可以添加开发环境特定的逻辑 break; default: - // 默认逻辑 console.log('Running in default environment'); } } - // 获取播放列表 const fetchPlaylist = async () => { try { const response = await instance.get("/musicList"); setPlaylist(response.data); - // 设置第一首歌为当前歌曲 if (response.data.length > 0) { setCurrentSong(response.data[0]); } @@ -73,6 +108,7 @@ function App() { fetchPlaylist(); }, []); + const handlePrevSong = () => { if (playlist.length === 0) { Toast.info('播放列表为空'); @@ -93,12 +129,12 @@ function App() { setCurrentSong(playlist[nextIndex]); }; + const handleError = (error) => { console.error("Error playing song:", error); Toast.fail(currentSong.title + ' 播放出错,请稍后重试'); }; - // 修改 isInChromeExtension 函数 const isInChromeExtension = () => { return sourceEnv === 'plugin' }; @@ -106,9 +142,9 @@ function App() { const handleKeyDown = useCallback((event) => { if (event.ctrlKey && event.key === 'x') { event.preventDefault(); - setShowSearch(prevState => !prevState); // 切换搜索框的显示状态 + setShowSearch(prevState => !prevState); if (showSearch) { - setSearch(''); // 如果正在隐藏搜索框,清空搜索内容 + setSearch(''); } } }, [showSearch]); @@ -124,11 +160,9 @@ function App() { }, [showSearch, isShowPlayList]); useEffect(() => { - // 添加事件监听器 document.addEventListener('keydown', handleKeyDown); document.addEventListener('mousedown', handleClickOutside); - // 清理函数 return () => { document.removeEventListener('keydown', handleKeyDown); document.removeEventListener('mousedown', handleClickOutside); @@ -142,12 +176,130 @@ function App() { }, [showSearch]); const updateSongInPlaylist = (updatedSong) => { - setPlaylist(prevPlaylist => - prevPlaylist.map(song => + setPlaylist(prevPlaylist => + prevPlaylist.map(song => song.id === updatedSong.id ? updatedSong : song ) ); }; + const stopRecording = async () => { + if (audioContext && audioInput && recorder && mediaRecorder && isRecording) { + setIsRecording(false); // 立即设置为非录音状态 + + if (mediaRecorder.stream) { + mediaRecorder.stream.getTracks().forEach(track => track.stop()); + } + + recorder.disconnect(); + audioInput.disconnect(); + + if (audioContext.state !== 'closed') { + await audioContext.close(); + } + + const audioData = mediaRecorder.audioChunks.reduce((acc, chunk) => { + return new Float32Array([...acc, ...chunk]); + }, new Float32Array()); + + const wavBlob = writeAudioBufferToWav(audioData, 1, audioContext.sampleRate); + + setAudioContext(null); + setAudioInput(null); + setRecorder(null); + setMediaRecorder(null); + + Toast.success('识别中...'); + + await sendAudioToBackend(wavBlob); + } + }; + + const startRecording = useCallback(async () => { + if (isRecording) { + await stopRecording(); + } + + try { + const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); + const context = new (window.AudioContext || window.webkitAudioContext)(); + const source = context.createMediaStreamSource(stream); + const node = context.createScriptProcessor(4096, 1, 1); + + let audioChunks = []; + + node.onaudioprocess = (e) => { + const inputBuffer = e.inputBuffer; + const channelData = inputBuffer.getChannelData(0); + audioChunks.push(new Float32Array(channelData)); + }; + + source.connect(node); + node.connect(context.destination); + + setAudioContext(context); + setAudioInput(source); + setRecorder(node); + setMediaRecorder({ audioChunks, stream }); + setIsRecording(true); + + // Toast.success('开始录音'); + } catch (error) { + console.error('录音失败:', error); + Toast.fail('无法访问麦克风'); + } + }, [isRecording, stopRecording]); + + const sendAudioToBackend = async (audioBlob) => { + try { + const formData = new FormData(); + const timestamp = Date.now(); + formData.append('audio', audioBlob, `recording_${timestamp}.wav`); + + const response = await instance.post('/uploadAudio', formData, { + headers: { + 'Content-Type': 'multipart/form-data', + }, + }); + + Toast.success({ + message: "识别结果:《" + response.data.title + "》," + response.data.artist, + duration: 5000 // 设置持续时间为 5000 毫秒(5 秒) + }); + + } catch (error) { + console.error('音频上传失败:', error); + Toast.fail({ + message: '音频上传失败', + duration: 5000 // 错误消息也设置为 5 秒 + }); + } + }; + + useEffect(() => { + return () => { + if (audioContext && audioContext.state !== 'closed') { + audioContext.close(); + } + if (audioInput) { + audioInput.disconnect(); + } + if (recorder) { + recorder.disconnect(); + } + if (mediaRecorder && mediaRecorder.stream) { + mediaRecorder.stream.getTracks().forEach(track => track.stop()); + } + }; + }, [audioContext, audioInput, recorder, mediaRecorder]); + + // useEffect(() => { + // return () => { + // // 组件卸载时的清理函数 + // if (isRecording) { + // stopRecording(); + // } + // }; + // }, [isRecording, stopRecording]); return (
@@ -173,7 +325,6 @@ function App() { onSearch={async (val) => { const response = await instance.post("/search", { "title": val }); if (response.data instanceof Array) { - // 设置一首歌为当前歌曲 if (response.data.length > 0) { setCurrentSong(response.data[0]); } @@ -212,7 +363,7 @@ function App() { onError={handleError} setIsShowPlayList={setIsShowPlayList} setCurrentSong={setCurrentSong} - updateSongInPlaylist={updateSongInPlaylist} // 新增这一行 + updateSongInPlaylist={updateSongInPlaylist} /> {isShowPlayList && (
@@ -228,9 +379,45 @@ function App() { )}
+
+ {isRecording ? ( + + ) : ( + <> + + 听歌识曲 + + 听歌识曲 + + )} +
); } -export default App; +export default App; \ No newline at end of file diff --git a/src/assets/images/micro.png b/src/assets/images/micro.png new file mode 100644 index 0000000000000000000000000000000000000000..3b026b44818a8fdb6eb28be53354b1724f036b80 GIT binary patch literal 27228 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 literal 0 HcmV?d00001 diff --git a/src/assets/images/tinggeshiqu40x40.png b/src/assets/images/tinggeshiqu40x40.png new file mode 100644 index 0000000000000000000000000000000000000000..f63cf182c3b4be85a7aa308061648ccc48680f6f GIT binary patch literal 8438 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 { const minutes = Math.floor(seconds / 60); @@ -32,7 +31,7 @@ const MusicPlayer = ({ currentSong, onPrevSong, onNextSong, onError, setIsShowPl likeState: status }); Toast.success(response.data); - + // 更新播放列表中的歌曲状态 updateSongInPlaylist(updatedSong); } catch (error) { diff --git a/src/utils/api.js b/src/utils/api.js index 0df6ee1..7a13472 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -1,8 +1,8 @@ import axios from 'axios'; export const instance = axios.create({ - // baseURL: 'https://app102.acapp.acwing.com.cn/api', - baseURL: 'http://localhost:8809/api', + baseURL: 'https://app102.acapp.acwing.com.cn/api', + // baseURL: 'http://localhost:8809/api', headers: { 'Content-Type': 'application/json',