我之前有篇文章介紹過如果實作一個C/S模式的Flv點播系統,Flv格式簡單,處理起來也比較輕松,不過,實際工作中,需要點播的影片,豈會隻有Flv這一種格式。我們常見的幾種視訊格式,随便哪一個都要比Flv複雜的多,尤其是本身設計的時候就沒有考慮到要通過網絡觀看的格式,要實作點播,自然要比Flv難的多。當然,你可以把所有影片都轉成Flv格式來處理,可是,當你擁有成千上萬部影片的時候,不但得一個個轉換,還要一個個檢查是否轉換成功、轉換品質如何等,那工作量可不是一點半點。從這點考慮出發,做一個支援多種視訊格式的點播系統,就顯得很有必要了。
可是,視訊格式有很多,千差萬别,有的格式裡面,描述視訊資訊的字段一大堆,而有的格式裡卻幾乎沒什麼描述的字段,這麼個情況下,怎麼能把它們揉合到一個系統中去呢?本人不才,做了這個嘗試,目前已經支援AVI、TS、FLV、F4V格式在同一個點播系統中的播放和拖動,而且不存在拖動後花屏的現象。下面我介紹一下這個點播系統的設計方案和架構。
點播系統,最重要的考慮因素就是“拖動”的處理,關鍵點就是要在用戶端播放器“拖動”進度條的時候,伺服器給用戶端傳回以關鍵幀起始的視訊流,否則,播放器很有可能會出現花屏,甚至無法播放的情況。使用者不是神仙,看影片的人才不會去關注一個片子裡哪些時間點是關鍵幀的位置,使用者拖動進度條的位置,是非常随意的,而視訊并非每一秒都是關鍵幀,是以,播放器必須要把拖動後進度條的位置,重新定位到離它關鍵幀之處(想想看,大家平時看片,都是這種體驗吧)。
在點播系統中,播放器想要實作上面所說的定位關鍵幀的技術,就要知道影片的關鍵幀清單,可是“點播”嘛,視訊在伺服器上,是邊下邊看的,沒法自己解析,隻能讓伺服器告訴它。具體的獲知方式,我覺得,可以設計成以下3種方案,這3中方案,針對AVI, TS, FLV等很多格式,都可以适用:
1. 每次拖動之後時,先發起一個請求,将拖動位置告訴伺服器,由伺服器傳回最近關鍵幀對應的位置,然後播放器再以這個位置發起請求,伺服器傳回資料,播放。
2. 将方案1的兩個請求合并為1個,伺服器傳回關鍵幀位置+資料,播放器播放。
3. 在開始點播一個視訊之前,先發起一個請求,伺服器傳回所有關鍵幀的位置,拖動時,播放器先定位到關鍵幀位置,然後直接請求資料,播放。
這個系統中,我選擇了方案三,原因就是處理簡單~~
這裡,以f4v檔案為例。(其中,XVideoKFrame是視訊格式解析程式,作用是讀取AVI TS等視訊,并生成關鍵幀清單。)
1. Client端
相對比較簡單,當然,原因是我采用了libvlc作為播放器核心,vlc對于播放網絡流的支援,恐怕是最好的,這省去了你自己寫播放器的工作。libvlc的接口比較簡單,我就直接上代碼,大家一看就明白了。
私有成員變量:
操作libvlc進行播放的方法:
2. Server端
點播Server端,就是一個比較特殊的HttpServer,“特殊”主要是指在處理拖動的請求上。
XVideoKFrame,負責讀取并分析輸入的視訊格式,然後Video.kframe檔案,這裡面包含了關鍵幀清單和其他媒體資訊,是一個非常重要的程式/子產品,點播系統的工作基礎。在上面的處理邏輯圖裡面,我把視訊解析這部分放在了單獨的程式當中,主要是友善平時調試和增加格式解析的代碼。當然也可以放到Server中,在視訊檔案第一次被通路時,生成.kframe檔案。
目前,該解析器已經支援AVI格式解析、TS格式解析、FLV格式解析和F4V格式解析,正在寫ASF格式解析,往後也還會增加。視訊格式解析,是點播系統中工作量最大的部分之一,除了要讀取數不清的字段,還要針對不同的編碼,做不同的處理。例如TS格式,是不是H264編碼,對于關鍵幀的查找方法是完全不一樣的。我就不把所有格式的解析方法寫出來了,将來有機會再寫文章介紹這些格式。
最後,讓大家看一下效果圖,這個是點播ts檔案的效果