2012-10-22 146 views
33

我正在從事在線電視服務。其中一個目標是在沒有任何其他瀏覽器插件的情況下播放視頻(Flash除外)。通過MP4實時流式傳輸

我決定使用MP4,因爲它受到大多數HTML5瀏覽器和Flash(用於回退)的支持。視頻由FFMpeg從服務器上的ASF轉碼。

但是,我發現MP4無法實時流式傳輸,因爲它具有用於指定長度的元數據的moov原子。 FFMpeg不能直接將mp4傳輸到標準輸出,因爲它將moov放在文件末尾。 (Live transcoding and streaming of MP4 works in Android but fails in Flash player with NetStream.Play.FileStructureInvalid error

當然,MPEG-TS存在,但它不被HTML5 <video>支持。

我想到的是一種將流實時轉碼爲MP4的方法,並且在每個新的HTTP請求上,首先發送一個moov,指定視頻長度的非常長的數字,然後開始發送MP4文件的其餘部分。

是否有可能使用MP4流式傳輸?

經過一番研究和av501的回答,我明白幀的大小必須是已知的,以便它可以工作。

mp4文件可以被分割成更小的部分,以便它可以流式傳輸?

當然,切換到另一個容器/格式是一種選擇,但與Flash和HTML5兼容的唯一格式是mp4/h264,所以如果我必須同時支持這兩種格式,我必須進行兩次轉碼。

回答

5

這裏是我的想法,大家可能會在其他方式的一些方式。我懇求無知,因爲沒有人真正記錄了這個過程,其全部都是有教養的猜測。

AvAssetWriter只對一個文件進行編碼,似乎沒有辦法將編碼的視頻存儲到內存中。在從後臺線程寫入文件的時候讀取文件來表示一個套接字導致基本流,這基本上是一個m4v,它是一個帶有h264/acc mdata但沒有moov原子的容器。 (換句話說,沒有標題) 沒有蘋果提供的播放器可以播放此流,但基於ffplay的經過修改的播放器應該能夠解碼和播放流。這應該是有效的,因爲ffplay使用可以解碼基本流的libavformat,因爲沒有文件長度信息,有些事情必須由播放,DTS和PTS以及播放器無法在文件內搜索來確定。

或者,可以使用來自m4v流的原始naul來構造rtmp流。

如果您想進一步討論,可以直接與我聯繫。

如何獲取數據。

因爲無論如何你都必須在接收端重建文件,我猜你可能會對它進行細分,Steve Mcfarin在他的github頁面上寫了一個小小的appleSegmentedEcorder,這可以解決一些問題moov原子,因爲你擁有所有的文件信息。

+1

這裏有一個很好的解釋,開始聽起來像rtmp或一些自定義協議的路要走http://fabiensanglard.net/mobile_progressive_playback/index.php –

+0

你的答案有告誡,它已經寫在上面。時間就是流媒體和播放的問題。所以-1 – agfe2

2

不,它不僅僅是很長的長度..你需要知道每個幀的確切大小才能在mp4中創建標題。 [這就是爲什麼它最終由各種編碼器創建的原因]。

+0

不能將該信息留空嗎?經過一些調整後,我設法創建了一個沒有moov原子的m4v文件(基本上是MP4),它在Totem中播放,沒有顯示關於視頻長度的任何信息。 – Ivo

+0

你的m4v是一個包含基本文件還是基本文件的mp4(容器)?沒有標題,它不再符合標準。所以無論玩還是不玩取決於玩家的智慧。有些玩家可能會努力工作並嘗試修復該文件。但大多數人不會玩它。 – av501

+0

是的,似乎m4v可以只是一個mp4文件或原始h264流。在瀏覽器中工作的是mp4,而ffmpeg生成的是原始流。 所以看來,它畢竟不能完成。 – Ivo

0

只是看你的問題的第二段(「視頻是由ffmpeg在服務器上從ASF轉碼的。」),你提到你使用ffmpeg在服務器上轉碼視頻。

使用qt-faststart或MP4Box將MOOV原子放置在文件的開頭。 (也請確保使用H264 Video & AAC Audio編解碼器進行通用支持)

希望這對您有所幫助。

+2

它沒有。經過多次谷歌搜索之後,我發現qt-faststart被提及了很多 - 但它不適用於直播,因爲流是連續的 - 從開始就無法知道幀/長度,因此無法創建MOOV原子。 qt-faststart將幫助如果我需要僞流(連續下載)。 – Ivo

17

您可以使用分段MP4。支離破碎的MP4文件是建立在如下:然後

moov [moof mdat]+ 

影片包只包含了軌道的基本信息(多少,它們的類型,編解碼器的初始化等),但沒有對在軌道的樣本信息。有關樣本位置和樣本大小的信息位於moof框中,每個moof框後跟一個包含上述moof框中所述樣本的mdat。通常情況下,人們會選擇(moof,mdat)對的長度大約爲2,4或8秒(沒有關於此的規範,但對於大多數使用情況,這些值似乎是合理的)。

這是一種構建一個永無止境的MP4流的方法。

+0

看看這裏:https://groups.google.com/forum/?fromgroups=#!topic/mp4parser-discussion/e7yg6clATHc這傢伙似乎有一個非常類似的問題。 –

+3

最終碎片化的mp4就像蘋果HTTP實時流媒體並且做得很好。我一開始就忽視了這一點,因爲我認爲碎片似乎是一個不必要的複雜因素,但現在我發現它是唯一的選擇。 – Ivo

+0

@SebastianAnnies然而,這似乎起作用,但(至少)Safari似乎要求每個片段都有一個單獨的Range GET請求(從片段開始到EOF,但過早終止),使整個流處理更加麻煩。你有相同的經歷嗎? –