2014-04-25 77 views
13

我有一個服務器應用程序,呈現一個30 FPS視頻流,然後編碼並實時複製到WebM Byte Stream如何讓現場MediaSource視頻流保持同步?

在客戶端,一個HTML5頁面打開一個WebSocket到服務器,當連接被接受時它開始生成流。傳遞標頭後,每個後續WebSocket框架由一個WebM SimpleBlock組成。關鍵幀每15幀發生一次,發生這種情況時會啓動一個新的羣集。

客戶端還會創建MediaSource,並且在從WS接收到一個幀時,會將內容附加到其活動緩衝區。附加第一幀後,<video>立即開始播放。

一切正常合理。我唯一的問題是,網絡抖動會導致播放位置在一段時間後偏離實際時間。我當前的解決方案是掛入updateend事件,檢查傳入羣集上video.currentTime與時間碼之間的差異,如果超出可接受範圍,則手動更新currentTime。不幸的是,這會導致明顯的暫停和跳躍,這很不愉快。

該解決方案也有點奇怪:我確切地知道最新的關鍵幀在哪裏,但我必須將其轉換爲整秒(根據W3C規範),然後才能將它傳遞到currentTime,其中瀏覽器可能必須隨後四處尋找最近的關鍵幀。

我的問題是:有沒有辦法告訴媒體元素總是尋求最新的關鍵幀可用,或保持播放時間與系統時鐘時間同步?

+0

您是否找到解決方案? –

+0

我意識到你的解決方案改變currentTime是最好的,它引起的故障是可以接受的,因爲在此之前,網絡故障導致緩衝區增加,所以修復它的另一個小故障是正常的...它只會保留如果在數據流中存在連續的連接問題,則會出現毛刺。 –

回答

3

網絡抖動引起的播放位置漂移

那不是你的問題。如果您在視頻流中遇到中途退出問題,則在開始播放之前您的緩衝區不夠充足,並且播放時只有適當大小的緩衝區,即使實時延遲了幾秒鐘(這是正常情況)。

我目前的解決方案是掛鉤到updateend事件,請檢查輸入的集羣

這已經很接近正確的方法video.currentTime和時間碼之間的差別。我建議你忽略傳入羣集的時間碼,而是檢查你的緩衝時間範圍。您在WebM羣集上收到的內容以及解碼的內容有兩個不同的地方。

不幸的是,這會導致顯着的暫停和跳轉,這是令人不快的回放。

你會怎麼做呢?您可以跳轉到實時,也可以提高播放速度以趕上實時。無論哪種方式,如果你想趕上實時,你必須及時跳過去做到這一點。

該解決方案還感覺有點奇怪:我知道確切位置的最新關鍵幀是

你可以,但直到媒體解碼播放器沒有。在任何情況下,關鍵幀都是不相關的......你可以尋求非關鍵幀的位置。瀏覽器將根據需要在P/B幀之前解碼。

我必須把它轉換成一整秒(根據W3C規範)之前,我可以將它傳遞到currentTime的

這是完全錯誤的。 currentTime被指定爲doublehttps://www.w3.org/TR/2011/WD-html5-20110113/video.html#dom-media-currenttime

我的問題是:有沒有辦法告訴媒體元素總是尋求最新的關鍵幀可用,或者保持與系統時鐘同步時間的播放時間?

它將自動播放最後一個緩衝區。你不需要做任何事情。通過確保媒體數據落入緩衝區並將播放設置爲儘可能接近合理,您正在完成您的工作。如果網絡條件發生變化,您可以隨時向前推進,但坦率地說,聽起來好像您的代碼已損壞並且緩衝策略不全。否則,播放將會非常流暢。

趕上如果落後不會自動發生,也不應該。如果播放器由於緩衝區被耗盡而暫停,則需要在恢復播放之前再次構建緩衝區。這是緩衝區的全部。此外,您對系統時鐘保持任何時間的期望並不是一個好主意,也是不合理的。不同的設備有不同的刷新率,將以不同的速率處理視頻。只需點擊播放,讓它播放。如果您最終關閉幾秒鐘,請繼續並設置currentTime,但要確保您在此之前緩衝的內容非常有信心。

+0

不知道您是否遇到了問題,但是如果您從節點以2.7秒的數據包形式發送一個mp3文件,播放器就會像應該那樣啓動,但如果您手動暫停,緩衝區將開始增加當你再次玩時,它會從你停下來的地方開始。這會導致播放與nodejs流不同步。如果您讓播放幾個小時,會發生這種情況,由於毛刺和緩衝區開始增加,它會自動暫停。 –

+0

nodejs發送2.7秒,等待它播放,然後發送下一個數據包。但隨着緩衝區的增加,您無法再控制流數據是否已播放。我試圖發送一個「確認」,告訴包被播放,以便下一個可以交付,但有其他問題。像播放停止一樣。所以問題在於流式傳輸數據並連續播放數小時。 –

+0

@KeyneViana你爲什麼要等待發送下一個數據塊?只要繼續發送它。此外,你不應該等待2.7秒...... MP3幀可以小到576個樣本。 – Brad