簡體   English   中英

傳輸編碼:分塊和 MP3/Lame

[英]Transfer-encoding: chunked and MP3/Lame

我有一個返回 mp3 HTTP 響應的 PHP 網絡服務。 它有效,但是當我在 DevTools 中打開 Chrome 的網絡節流時,它只返回部分響應:

        $stream_start1 = Psr7\stream_for(fopen('./sounds/ping.mp3', 'r'));
        $stream_start2 = Psr7\stream_for(fopen('./sounds/ping.mp3', 'r'));
        $stream_start3 = Psr7\stream_for(fopen('./sounds/ping.mp3', 'r'));
        $stream_start4 = Psr7\stream_for(fopen('./sounds/ping.mp3', 'r'));
        $stream_start5 = Psr7\stream_for(fopen('./sounds/ping.mp3', 'r'));
        $stream_start6 = Psr7\stream_for(fopen('./sounds/ping.mp3', 'r'));
        $stream_start7 = Psr7\stream_for(fopen('./sounds/ping.mp3', 'r'));
        $stream_start8 = Psr7\stream_for(fopen('./sounds/ping.mp3', 'r'));
        $stream_start9 = Psr7\stream_for(fopen('./sounds/ping.mp3', 'r'));
        $stream_start10 = Psr7\stream_for(fopen('./sounds/ping.mp3', 'r'));
        $stream_start11 = Psr7\stream_for(fopen('./sounds/ping.mp3', 'r'));
        $stream_start12 = Psr7\stream_for(fopen('./sounds/ping.mp3', 'r'));
        $stream_start13 = Psr7\stream_for(fopen('./sounds/ping.mp3', 'r'));

        return new Psr7\AppendStream([$stream_start1 , $stream_start2 , $stream_start3 , $stream_start4 , $stream_start5 , $stream_start6 , $stream_start7 , $stream_start8 , $stream_start9 , $stream_start10, $stream_start11, $stream_start12, $stream_start13]);

使用上面的代碼,在開發節流的情況下,我得到了 7 個 ping 而不是 13 個。

實際上,真正的代碼是從 3rd 方服務獲取流並將其夾在兩個文件之間:

 return new Psr7\AppendStream([file1Stream, 3rdPartyStream, file2Stream])

所以,我不一定知道設置內容長度的長度,所以它使用傳輸編碼:分塊。

當我在開發工具中查看請求的縮短響應時,我始終看到它們以看起來像一些 LAME 元數據或添加的靜音結束:

e¨Deš•†š¹‡ÌC`̹3†'2 CBR9S¨Âöe­i´g¡ÿ–W©^¥ÔzWI}I8¸¶vv,¸¼Ù£J*ÙÙû±W•'X&+X±£@È ·bbÂìýbŸâÿâŸëLAME3.100UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUÿóbÄ”AIÖtUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU

我想知道的是,由於接收塊的延遲,瀏覽器是否有可能在塊序列的末尾混淆了某些 LAME 信息(或其他信息)。 音頻二進制文件中的混合是否有可能類似於指示最后一個塊的“空塊”? 有沒有辦法“轉義”或編碼數據以避免這樣的潛在序列? 通過壓縮,也許?

我的另一個選擇是在轉發之前將第 3 方流(在三明治中間)一直讀入內存。 這樣我就可以計算長度並設置內容長度,所以這就是 B 計划。

更新:我嘗試在我的 13 文件小示例上設置 Content-Length,但我仍然收到 7 個 ping 作為響應。 我計算的長度:

$length = strlen($stream_start0->getContents()) * 13 

這是 122252。但返回的文件內容大約有 65529 字節長(十六進制編輯器說 65536...?)。 總之,太短了。 此外,Transfer-Encoding 標頭消失了,這意味着我猜它不再被分塊了?

UPDATE2: 問題也可能是我正在連接原始的 mp3 文件。 我認為從技術上講,當您這樣做時,事情會變得陰暗,特別是如果音頻包含 ID3 標簽等,盡管在上面使用的 ping 文件中,不應該有任何 ID3 標簽。 然而,在我們的 stg 環境中,我在沒有開發工具的情況下觀察到這個問題,截止並不總是發生在文件之間的中斷處。

所以以上所有都是紅鯡魚。 結果發現問題是我用 JavaScript 代碼復制了一些博客文章,這些代碼只調用了response.getReader().read()一次,因此只獲得了響應的第一塊。

顯然,它應該像大多數流 API 一樣在循環中調用,直到到達流的末尾,但我錯過了它。

解決方案是使用response.blob() ,它讀取到流的末尾並一次性創建我需要的 Blob。

我以為我已經驗證了我復制的所有內容,但我想沒有。 但我學到了一些東西,所以就是這樣。

reader.read() 上的文檔
關於 response.blob() 的文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM