PHP を使用して 2 つの MP3 ファイルをマージするクラスを知っていますか?
Google で何も見つかりませんでした。
マージによって、あるオーディオを別のオーディオの上に配置することを意味する場合は、この回答を無視してください。
MP3 を再エンコードしたくない場合は、おそらくそれらを追加できます。これは MPEG ムービーで機能することを知っているので、MP3 でも機能すると思います。もう 1 つのオプションは、オーディオ ファイルを圧縮せずに Zip アーカイブに追加し、拡張子を .mp3 に変更することです。
私は簡単なテストをしました、そしてこれは
file_put_contents('combined.mp3',
file_get_contents('file1.mp3') .
file_get_contents('file2.mp3'));
うまくいきました。ID3 タグは間違っていますが、結果のファイルには両方のオーディオ ファイルが含まれています。その他の考えられる落とし穴については、Pekka's answer のリンクを参照してください。
また、いくつかの簡単なグーグルの結果、
そしていくつかの議論
今同じことをすることに興味がある人は、私が書いた (リファクタリングされた?) 次のライブラリを使用できます: https://github.com/falahati/PHP-MP3
composer require falahati/php-mp3
2 つの 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 タグがない場合、ファイル全体を読み取り、フレームごとに長さを計算する必要があります。これは、特に大きなファイルの場合、計算とメモリの両方を集中的に使用します。
したがって、多くのツールは最初のフレームを読み取ろうとし、ファイルの合計サイズに基づいて合計フレーム数を推測し、この情報と最初のフレームのプロパティに基づいてファイルの可能な期間を単純に計算します。これはそれ自体で問題なく、実際のファイルの長さとほとんど変わらずに機能するはずです。
2 つの非常に異なる MP3 ファイルを一緒にマージしようとすると、実際の問題が発生します。このライブラリはファイルを再エンコードしないため、フレームを変更せず、プレーヤーが他のフレームとは無関係に各フレームの MP3 フレーム ヘッダーを読み取ることを信頼して、それらを隣り合わせに追加するだけです。これは、一部のプレーヤーやツールには当てはまりません。最初のフレームのプロパティのみを読み取り、他のすべてのフレームが同様であると期待することで、パフォーマンスを優先して各フレーム プロパティを無視する傾向があるためです。
これは、このライブラリのバグや機能の欠如からではなく、期間に関する問題が発生する場所です。プロパティ(ビットレートなど)に関して同様のファイルをライブラリに提供するだけで済みます。そうしないと、プレーヤーの MP3 デコーダーの実装にファイルの運命を委ねることになります。
このライブラリを介して縫い合わされた非常に異なるファイルと悪いプレーヤーの実装に関するその他の問題には、再生のペースが速いまたは遅い、再生中にエラーが発生する、再生が歪むなどがあります。あなたが気にするものです(おそらくダウンロードのためにファイルを共有する)か、そうでない場合は互換性のあるプレーヤーを使用します(私のテストでは、Chrome、Firefox、およびTelegram wareと互換性があります。他のものについては知りませんし、覚えていません)。
これは不可能です。PHP には MP3 コーデックの実装はありません。これを行うには、外部のコマンドライン ツールを使用する必要があります。(サーバーの構成によっては、@ceejayoz が言うように、PHP 内から実行できます。)
解決策については、次の質問を参照してください。
.mp3ファイルがMPEG-1またはMPEG-2レイヤーIIIオーディオだけの場合は、ファイルを連結するだけです。ファイル全体のヘッダーの実際の概念はありません。各フレームにはヘッダーとそれに続くデータがあり、ファイルはビットストリームと呼ばれる一連のフレームで構成されています。ビットレート、ステレオモードなどは、ビットストリーム内で必ずしも同じである必要はないため、異なるファイルを連結できます。ウィキペディアの記事でこれについて説明されていますが、実際には仕様の方が理解しやすいと思います。
ファイル内のID3タグまたはその他のデータ(技術的には非準拠のビットストリームになります)は、デコーダー側で問題を引き起こす可能性があります。
MPEG-1およびMPEG-2オーディオの仕様は実際には非常に単純です。ファイルをフレームにチャンクするパーサーを作成してから、ヘッダーを解釈するのはそれほど手間がかかりません。私が最後にこれをしたとき、それはたった1時間か2時間しかかかりませんでした。
ID3の仕様もそれほど複雑ではないので、連結が簡単になる前にタグを取り除くためのコードを書くのではないかと思いますが、私はこれを行ったことがありません。
getID3()ライブラリ(http://getid3.sourceforge.net/)もいくつかのガイダンスを提供する場合があります。使用してからしばらく経ちますが、MP3を開いたりID3タグを削除したりすることもできます。
HTH
覚えておくべき重要事項:
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;