如何通过PHP结合wavesurfer.js播放局域网PC中的音频文件
解决方案:用PHP + wavesurfer.js播放局域网PC存储的音频文件
我来帮你搞定这个问题,核心要解决两个点:一是wavesurfer.load()的正确调用方式,二是让浏览器能访问到局域网共享里的音频文件(毕竟浏览器没法直接读取SMB共享路径)。
一、先搞懂wavesurfer.load()的正确语法
wavesurfer.load() 必须接收一个浏览器能直接访问的HTTP URL,不能是本地磁盘路径或者\\192.168.1.xx\musicfiles这种SMB路径。举个例子:
// 相对路径(音频文件在Web服务器可访问目录下) wavesurfer.load('/audio/song.mp3'); // 或者通过PHP代理的URL wavesurfer.load('audio-proxy.php?file=song.mp3');
二、局域网音频文件的播放方案
浏览器没法直接访问SMB共享,所以得靠PHP做中间层,把局域网的音频转成浏览器能识别的HTTP资源。这里给你两种可行方案:
方案1:PHP代理读取并输出音频文件
创建一个单独的audio-proxy.php脚本,专门负责从局域网共享取文件,再输出给浏览器:
audio-proxy.php 代码
<?php // 配置局域网共享信息 $smbPath = '\\\\192.168.1.xx\musicfiles'; $user = "Administrator"; $pass = "xxxxxx"; $driveLetter = "Z"; // 挂载共享目录(如果没挂载的话) system("net use ".$driveLetter.": \"".$smbPath."\" ".$pass." /user:".$user." /persistent:no>nul 2>&1"); // 获取前端请求的文件名 $requestedFile = $_GET['file'] ?? ''; $fullFilePath = $driveLetter.":/2412/".$requestedFile; // 校验文件是否存在且是有效文件 if (!file_exists($fullFilePath) || !is_file($fullFilePath)) { http_response_code(404); exit("文件不存在"); } // 设置响应头,告诉浏览器这是音频文件 $mime = mime_content_type($fullFilePath); header("Content-Type: ".$mime); header("Content-Length: ".filesize($fullFilePath)); // 输出文件内容 readfile($fullFilePath); ?>
然后修改你的主页面代码,让wavesurfer.load()指向这个代理脚本:
修改后的主页面代码
<!doctype html> <html lang="en"> <head> <meta name="Generator" content="EditPlus®"> <meta name="Author" content=""> <meta name="Keywords" content=""> <meta name="Description" content=""> <title>Document</title> <meta charset="UTF-8"> <script src="https://unpkg.com/wavesurfer.js"></script> </head> <body> <?php $path = '\\\\192.168.1.xx\musicfiles'; $user = "Administrator"; $pass = "xxxxxx"; $drive_letter = "Z"; system("net use ".$drive_letter.": \"".$path."\" ".$pass." /user:".$user." /persistent:no>nul 2>&1"); $location = $drive_letter.":/2412"; $audio = []; if ($handle = opendir($location)) { while (false !== ($entry = readdir($handle))) { // 跳过.和..这两个系统目录 if ($entry != "." && $entry != "..") { $audio[] = $entry; } } // 确保数组有足够元素再取第三个(索引3),避免报错 $file = isset($audio[3]) ? $audio[3] : ''; closedir($handle); } ?> <div id="waveform" style="position:relative"></div> <div class="controls" style="text-align:center;"> <button class="playin" onclick="wavesurfer.playPause()"> Play / Pause </button> </div> </body> <script type="text/javascript"> console.clear(); var wavesurfer = WaveSurfer.create ({ container: '#waveform', waveColor: 'violet', progressColor: 'purple' }); var audioFile = '<?php echo htmlspecialchars($file) ?>'; console.log(audioFile); // 只有当文件名有效时才加载 if (audioFile) { // 调用代理脚本,注意用encodeURIComponent处理文件名,避免特殊字符问题 wavesurfer.load('audio-proxy.php?file=' + encodeURIComponent(audioFile)); } else { console.error('没有选中有效的音频文件'); } wavesurfer.on('ready', function () { wavesurfer.backend.ac.resume(); wavesurfer.play(); }); </script> </html>
方案2:把共享目录映射到Web服务器的可访问目录
如果你的Web服务器(比如Apache、Nginx)允许,也可以直接把局域网共享目录挂载到Web根目录的某个子文件夹:
- Windows环境:把共享目录映射成Z盘后,在Web服务器里创建一个虚拟目录(比如
/audio)指向Z盘的2412文件夹。 - Linux环境:用
mount -t cifs命令把SMB共享挂载到Web根目录下的audio文件夹。
这样你就能直接用相对路径加载音频了,不需要代理脚本:
wavesurfer.load('/audio/<?php echo htmlspecialchars($file) ?>');
三、几个关键注意点
- 要确保Web服务器的运行用户(比如Windows下的IIS_IUSRS、Linux下的www-data)有访问局域网共享目录的权限,不然PHP读不到文件。
- 用
htmlspecialchars()和encodeURIComponent()处理文件名,避免XSS攻击和路径注入的问题。 - 如果挂载共享目录的操作失败,可以去掉
>nul 2>&1看具体错误信息,排查权限或网络问题。
内容的提问来源于stack exchange,提问作者Learner0617
相关产品推荐
相关产品推荐

