从服务器检索和播放音频文件

时间:2018-02-16 18:54:19

标签: javascript php audio

我一直试图找到一种方法来隐藏用户的音频文件(mp3)。我正在创建一个具有不同权限级别的网站,并且为了安全起见,希望播放未存储在webroot目录中的特定音频文件。我不希望人们能够访问example.com/music/mymusic.mp3,所以我在webroot之前存储音乐。我从服务器播放音频文件时遇到麻烦。这就是我为测试目的而做的事情。

 $.ajax({
                type: 'POST',
                url: '/php/song.php',
                success: function(text) {
                    var buf = new ArrayBuffer(text.length * 2); 
                    for(var i = 0; i < text.length; i++){
                        buf[i] = text[i];
                    }
                    console.log(buf);
                    window.AudioContext = window.AudioContext || window.webkitAudioContext;
                    var context = new AudioContext();

                    context.decodeAudioData(buf, function(buffer) {
                          var source = context.createBufferSource();
                          source.buffer = buffer;
                          source.connect(context.destination);
                          source.start(0);
                    }, console.log('fail'));
            }

(请注意,mp3 im检索仍然在webroot目录中,因为我只是想在更改目录之前将其播放)

这会调用song.php

<?php
echo file_get_contents($_SERVER["DOCUMENT_ROOT"] . "/school_bell.mp3");
?>

我收到错误“Uncaught(in promise)DOMException:无法解码音频数据”这是因为我没有为我的音频数据正确创建数据缓冲区吗?我应该在php中创建arraybuffer,还是通过字符串发送它并在javascript中将其更改为arraybuffer?另外,还有其他存储我的mp3文件的可能性吗?任何建议将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:0)

您的song.php没有发送正确的标题,就像您在记事本中打开.mp3文件一样 - 它无法播放。发送正确的标头会通知浏览器您发送的数据实际上是媒体文件。这是一个例子:

header("Content-Transfer-Encoding: binary");
header("Content-Type: audio/mpeg");
header('Content-length: ' . filesize($_SERVER["DOCUMENT_ROOT"] . '/school_bell.mp3'));
header('Content-Disposition: inline; filename="school_bell.mp3"');
readfile($_SERVER["DOCUMENT_ROOT"] . '/school_bell.mp3');

注意readfile()的用法 - 它会直接将文件读取到输出缓冲区,而不是将其读入内存然后回显它。