【问题标题】:Merge two mp3 php合并两个mp3 php
【发布时间】:2011-04-28 21:13:14
【问题描述】:

你知道使用 PHP 合并两个 MP3 文件的类吗?

我在 Google 上一无所获。

【问题讨论】:

    标签: php http merge mp3 ogg


    【解决方案1】:

    对于现在有兴趣做同样事情的任何人,您可以使用我编写的以下库(重构?): https://github.com/falahati/PHP-MP3

    composer require falahati/php-mp3
    

    合并两个 MP3 文件:

    $audio1 = \falahati\PHPMP3\MpegAudio::fromFile("1.mp3")->stripTags();
    $audio2 = \falahati\PHPMP3\MpegAudio::fromFile("2.mp3")->stripTags();
    $audio1->append($audio2)->saveFile("3.mp3");
    

    请注意,这是一个 MP3 解析器库,它不会对 MP3 文件进行编码、解码或重新编码。此解决方案与此处的其他解决方案基本相同,但始终会生成结构上正确且标准的 MP3 文件。


    -- 回答关于文件无效持续时间的评论:

    MP3 文件没有标题,仅由 MPEG 帧组成。这个库保留了 MPEG 帧头(因为没有这些就无法播放),因此这里描述的问题并不完全正确。

    但是,从需要提取MP3文件时长的播放器或工具的角度来看,在没有ID3标签的情况下,应该读取整个文件并逐帧计算时长。这是计算密集型和内存密集型的,尤其是对于大文件。

    因此,许多工具可能会尝试读取第一帧并根据文件的总大小猜测总帧数,并根据该信息和第一帧的属性简单地计算文件的可能持续时间。这本身没问题,并且应该与实际文件的持续时间几乎没有区别。

    当您尝试将两个截然不同的 MP3 文件合并在一起时,就会出现真正的问题。由于这个库不重新编码文件,它不会更改帧,只是简单地将它们彼此相邻地添加,相信播放器可以独立于其他帧读取每一帧的 MP3 帧头。某些播放器和工具并非如此,因为他们倾向于忽略每个帧属性,只读取第一帧的属性并期望所有其他帧都相似,从而提高性能。

    这是您的持续时间问题的原因,而不是由于此库中的错误或缺少功能。您只需要在属性(比特率等)方面为库提供类似的文件;否则,您将把文件的命运交给播放器的 MP3 解码器实现。

    通过此库将完全不同的文件缝合在一起的其他问题以及不良的播放器实现包括快节奏或慢节奏播放、播放时出错、播放失真等。因此,请确保您的文件彼此尽可能接近,如果文件的可移植性是您关心的(可能共享文件以供下载)或使用兼容的播放器(在我的测试中,Chrome、Firefox 和 Telegram 软件兼容;不知道也不记得其他的) )。

    【讨论】:

    • 对于任何使用此解决方案的人,请注意它不会改变输出文件的标题,结果是一个持续时间错误的 mp3 文件
    【解决方案2】:

    要记住的重要事项:

    • 比特率必须匹配。确保速率 (Hz) 和立体声/单声道匹配也是一个好主意(我使用了 Audacity)。
    • Content-length 标头是两个文件的长度。

    这是我的文字转语音项目中的一个示例。我需要在动态生成的 MP3 音频末尾添加 1 秒的静音:

    $output_audio = textToMP3("Hello World");               // Original audio
    $silent_audio = file_get_contents("silence.mp3");       // 1 second silence
    $content_length = strlen($output_audio) + strlen($silent_audio);
    
    // Output the audio stream
    header('Content-type: audio/mpeg');
    header('Content-length: ' . $content_length);
    header('Cache-Control: no-cache');
    header("Pragma: no-cache");
    header("Expires: 0");
    echo $audio . $silent_audio;
    

    【讨论】:

    • 您好,写信是想告诉您两件事 1)感谢您提供的非常有见地的内容 2)您的项目是开源的还是可用的?对你的 textToMp3 函数很感兴趣!
    • 恐怕我已经没有该项目的源代码了。我可以告诉你的是,textToMp3 函数所做的唯一事情就是将文本发送到第 3 方 API,该 API 会以 MP3 文件进行响应。我不记得是哪个 API,但有很多可供您选择。
    • 谢谢安德鲁感谢您的回复。是的,事实上我按照你说的做了,并使用了第 3 方 API,有时不需要重新发明轮子 ey :) 问候!
    【解决方案3】:

    如果 .mp3 文件只是 MPEG-1 或 MPEG-2 Layer III 音频,则可以将这些文件串联起来。整个文件的标题没有真正的概念。每个帧都有一个标题,后面跟着数据,而文件只是由一系列帧组成,称为比特流。比特率、立体声模式等在比特流中不一定必须相同,因此您可以连接不同的文件。维基百科文章解释了这一点,但我认为规范实际上更容易理解。

    文件中的 ID3 标签或其他数据(从技术上讲会使其成为不合规的比特流)可能会在解码器端造成混乱。

    MPEG-1 和 MPEG-2 音频的规范实际上非常简单。编写一个解析器将文件分块成帧,然后解释标题并没有那么多工作。我上次这样做时,只花了一两个小时。

    ID3 规范也没有那么复杂,所以我怀疑在连接之前编写一些代码来去除标签应该很容易,但我从来没有这样做过。

    getID3() 库 (http://getid3.sourceforge.net/) 也可以提供一些指导。好久没用了,不过它可能也已经支持打开MP3和去掉ID3标签了。

    HTH

    【讨论】:

      【解决方案4】:

      如果合并是指将一个音频放在另一个音频之上,那么请忽略此答案。

      如果您不想重新编码 MP3,您可以只附加它们。我知道这适用于 MPEG 电影,所以我想它也适用于 MP3。另一种选择是将 audo 文件添加到没有压缩的 Zip 存档中,然后将扩展名重命名为 .mp3。

      我做了一个快速测试,这个

      file_put_contents('combined.mp3',
          file_get_contents('file1.mp3') .
          file_get_contents('file2.mp3'));
      

      工作正常。 ID3 标签将是错误的,但生成的文件包含两个音频文件。 For some other possible gotchas, see the link in Pekka's answer.

      另外,一些快速的谷歌搜索导致

      还有一些讨论

      【讨论】:

      • 这听起来有点……嗯……脏。
      • @Gordon:对不起,我应该更清楚一点:连接两个文件并没有那么脏。许多格式都是这样工作的。我说的是 ZIP 解决方案。这对我来说似乎相当复杂和不必要。
      • @elusive 使用 Zip 文件还有一个额外的好处,那就是能够解压缩并重新获得 mp3。而且,当另一个答案是“不可能”时,有两个解决方案可供选择是相当不错的,你不认为:)
      • @Gordon:就像我说的那样,串联解决方案很好,但 ZIP 不是使用标头吗? MP3 解码器不一定知道如何处理。
      • @elusive 也许吧。我不是解码器专家。我只记得几年前我经常这样做,而且效果很好。我刚刚在我的桌面上做了​​一个快速测试,现在它也可以工作了。
      【解决方案5】:

      这是不可能的。 PHP 中没有 MP3 编解码器的实现。您将需要使用外部命令行工具来执行此操作。 (根据您的服务器配置,您可以像@ceejayoz 所说的那样在 PHP 中执行。)

      请参阅以下问题以获得解决方案:

      【讨论】:

      • 不过,您可以让 PHP 执行外部命令行工具。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-07
      • 1970-01-01
      • 2011-12-06
      • 2023-04-09
      相关资源
      最近更新 更多