微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在 PHP 中将 MediaRecorder 流保存到 OGG 文件?包括元数据

如何解决如何在 PHP 中将 MediaRecorder 流保存到 OGG 文件?包括元数据

我在浏览器中使用 Javascript 向我的用户提供录音:

navigator.mediaDevices.getUserMedia(media.gUM).then(_stream => 
{
    stream = _stream;
    recorder = new MediaRecorder(stream);

    recorder.ondataavailable = e => 
    {
        // push data to chunks
        chunks.push(e.data);

        // recording has been stopped
        if(recorder.state == 'inactive') 
        {
            blob = new Blob(chunks,{type: media.type });
            blob_url = URL.createObjectURL(blob);
            
            $('.rec_result_audio').attr({
                'src': blob_url
            });
            
            // send data to server
            // append file to object to be sent
            var filedata = new FormData();
            filedata.append('recfile',blob,blob_url);

            // send by AJAX/POST
        }
    };
}

PHP 中,我像这样获取和存储流:

if(!empty($_FILES)) 
{
    $filename = $_FILES['recfile']['name'];
    $file_locationtmp = $_FILES['recfile']['tmp_name'];
    $filetype = $_FILES['recfile']['type'];
    $filesize_bytes = $_FILES['recfile']['size'];
    
    // add file extension to string
    $_FILES['recfile']['name'] = $_FILES['recfile']['name'].'.ogg';

    // save to filesystem
}

现在 OGG 文件(带有 opus 编解码器的 webm)存储在服务器上。但是,所有元数据都丢失了。因此播放栏不起作用。请参阅此处了解更多信息:HTML5 Audio - Progressbar/Playbar is not working for OGG audio file / Issue with 206 Partial Content

ogg metadata empty

Length 缺失。还有 Bit rateChannelsAudio sample rate

显然用PHP直接保存到文件系统是不够的。

PHP 代码中缺少什么,以便稍后将该文件识别为 OGG 文件

我是否必须添加元数据,如果是,如何添加

解决方法

我可能遗漏了一些明显的东西,但是 - 你不应该指定你想要 the Javascript stream to be OGG/Vorbis 吗?

recorder = new MediaRecorder(stream,{ mimeType: "audio/ogg; codecs=vorbis" });

我可能弄错了,但是你得到的文件:

现在 OGG 文件(带有 opus 编解码器的 webm)存储在服务器上。但是,所有元数据都丢失了。

实际上不是 OGG 文件——它是一个 WEBM 文件。因此,给它一个 .ogg 扩展名而不是 .webm,正如您所做的那样,可能会混淆系统,这就是文件显示为“不可读且缺少元数据”的原因。

,

最简单的解决方案是下载一个已经编译好的 ffmpeg 二进制文件并将你的脚本指向它。在 FFmpeg 下载页面上,请参阅获取包部分以获取指向 Linux、Windows 和 macOS 的最新静态构建的链接。

您可以使用 FFmpeg Wiki:PHP 中所示的 shell_exec() 并提供下载的二进制文件的完整路径。

,

目前我仅通过使用 ffmpeg 来转换文件服务器端来解决这个问题 - 但不是直接在 PHP 中使用。

  1. 使用 sudo apt install ffmpeg

    在您的服务器上安装 ffmpeg
  2. 在您的 PHP 脚本中使用 ffmpeg:

// physical path to uploaded file
$filelocationtmp = $_FILES['recfile']['tmp_name'];

// call ffmpeg script to convert file
shell_exec("ffmpeg -y -i ".$filelocationtmp." -c:a libvorbis -vn -b:a 48k ".$filelocationtmp.".oga");

// rename oga file to original file (overrides original)
shell_exec("mv ".$filelocationtmp.".oga ".$filelocationtmp);

注意:ffmpeg 不能同时读取输入文件和写入输出文件。这就是为什么第二个命令行是必要的。



⚠️ 这不是一个纯粹的 PHP 解决方案。所以问题仍然悬而未决。

,

另一种选择是使用 ogg:// 包装器编写,它知道元数据。
PECL libvorbis 包看起来有点过时,但最终它仍会为 PHP 7 构建。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。