進式下載下傳(僞流媒體)
介于下載下傳本地播放與實時流媒體之間的一種播放形式,下載下傳本地播放必須全部将檔案下載下傳完成後才能播放,而漸進式下載下傳不必等到全部下載下傳完成後再播放,它可以一邊下載下傳一邊播放,在完成播放内容之後,整個檔案會儲存在手機上。
實時流媒體
實時流媒體是一邊接收資料包一邊播放,本地不保留檔案副本,實時流式傳輸總是實時傳送,可以實時實況轉播,支援随機通路,使用者可以快進或者快退以觀看前面或後面的内容。實時流媒體傳輸必須保證資料包的傳輸速度大于檔案的播放速度,否則使用者看到的視訊會出現暫停。當網絡堵塞情況下視訊品質會下降,是以要想保證視訊的品質漸進式下載下傳會更好一些。
實時流媒體協定:
rtsp(real time streaming protocol)
mms(microsoft media server protocol)
hls(http live streaming)
這裡主要介紹hls,
hls(http live streaming)是蘋果公司針對iphone、ipod、itouch和ipad等移動裝置而開發的基于http協定的流媒體解決方案
https://developer.apple.com/streaming/
技術關鍵點
1.采集視訊源和音頻源的資料
2.對原始資料進行h264編碼和aac編碼
3.視訊和音頻資料封裝為mpeg-ts包
4.hls分段生成政策及m3u8索引檔案
5.http傳輸協定
搭建hls流媒體伺服器
apache http server (蘋果自帶)
tomcat web server
iis(internet information services)
這裡隻推薦apache http server
打開終端,vi /etc/apache2/httpd.conf
在<ifmodule mime_module>下
添加兩行
addtype application/x-mpegurl.m3u8
addtype video/mp2t.ts
可能你的權限不夠,那就用 sudo chmod 777 /etc/apache2/httpd.conf
然後 vi /etc/apache2/httpd.conf
重新開機伺服器
sudo apachectl restart
==============================================
或者搭建xmpp伺服器 或者不搭建,從優酷擷取m3u8
建立一個工程
從git中下載下傳庫:http://git.oschina.net/1213125967/hls
将庫導入工程
需要引入第三方開源架構:asihttprequest,cocoahttpserver,m3u8
需要導入系統架構:libsqlite3.dylib、libz.dylib、libxml2.dylib、coretelephony.framework、systemconfiguration.framework、mobilecoreservices.framework、security.framework、cfnetwork.framework、mediaplayer.framework
在library search path 中添加 /usr/include/libxml2
添加頭檔案
?
1
2
3
4
<code>#import <mediaplayer/mediaplayer.h></code>
<code>#import "m3u8handler.h"</code>
<code>#import "videodownloader.h"</code>
<code>#import "httpserver.h"</code>
聲明屬性:
<code>@property (nonatomic, strong)httpserver * httpserver;</code>
<code>@property (nonatomic, strong)videodownloader *downloader;</code>
預先播放,畢先設定伺服器
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<code>#pragma mark - 打開本地伺服器</code>
<code>- (</code><code>void</code><code>)openhttpserver</code>
<code>{</code>
<code> </code><code>self.httpserver = [[httpserver alloc] init];</code>
<code> </code><code>[self.httpserver settype:@</code><code>"_http._tcp."</code><code>]; </code><code>// 設定服務類型</code>
<code> </code><code>[self.httpserver setport:12345]; </code><code>// 設定伺服器端口</code>
<code> </code>
<code> </code><code>// 擷取本地documents路徑</code>
<code> </code><code>nsstring *pathprefix = [nssearchpathfordirectoriesindomains(nsdocumentdirectory,nsuserdomainmask,yes) objectatindex:0];</code>
<code> </code><code>// 擷取本地documents路徑下downloads路徑</code>
<code> </code><code>nsstring *webpath = [pathprefix stringbyappendingpathcomponent:kpathdownload];</code>
<code> </code><code>nslog(@</code><code>"-------------\nsetting document root: %@\n"</code><code>, webpath);</code>
<code> </code><code>// 設定伺服器路徑</code>
<code> </code><code>[self.httpserver setdocumentroot:webpath];</code>
<code> </code><code>nserror *error;</code>
<code> </code><code>if</code><code>(![self.httpserver start:&error])</code>
<code> </code><code>{</code>
<code> </code><code>nslog(@</code><code>"-------------\nerror starting http server: %@\n"</code><code>, error);</code>
<code> </code><code>}</code>
<code>}</code>
搭建完成後,播放什麼的,都是取決于需求
線上流媒體播放
<code> </code><code>// 優酷視訊m3u8新位址格式如下:http://pl.youku.com/playlist/m3u8?vid=xnziwmde5nzi4&type=mp4</code>
<code> </code><code>// 如果上面的連結不可用,那麼使用這個連結http://v.youku.com/player/getm3u8/vid/xnziwmde5nzi4/type/flv</code>
<code> </code><code>nsurl *url = [[nsurl alloc] initwithstring:@</code><code>"http://v.youku.com/player/getm3u8/vid/xnziwmde5nzi4/type/mp4"</code><code>];</code>
<code> </code><code>mpmovieplayerviewcontroller *player = [[mpmovieplayerviewcontroller alloc] initwithcontenturl:url];</code>
<code> </code><code>[self presentmovieplayerviewcontrolleranimated:player];</code>
視訊下載下傳
<code> </code><code>m3u8handler *handler = [[m3u8handler alloc] init];</code>
<code> </code><code>handler.delegate = self;</code>
<code> </code><code>// 解析m3u8視訊位址</code>
<code> </code><code>[handler praseurl:[nsstring stringwithformat:@</code><code>"http://pl.youku.com/playlist/m3u8?vid=xnziwmde5nzi4&type=mp4"</code><code>]];</code>
<code> </code><code>// 開啟網絡訓示器</code>
<code> </code><code>[[uiapplication sharedapplication] setnetworkactivityindicatorvisible:yes];</code>
播放本地視訊
<code> </code><code>nsstring * playurl = [nsstring stringwithformat:@</code><code>"http://127.0.0.1:12345/xnziwmde5nzi4/movie.m3u8"</code><code>];</code>
<code> </code><code>nslog(@</code><code>"本地視訊位址-----%@"</code><code>, playurl);</code>
<code> </code><code>nsstring *localdownloadspath = [pathprefix stringbyappendingpathcomponent:kpathdownload];</code>
<code> </code><code>// 擷取視訊本地路徑</code>
<code> </code><code>nsstring *filepath = [localdownloadspath stringbyappendingpathcomponent:@</code><code>"xnziwmde5nzi4/movie.m3u8"</code><code>];</code>
<code> </code><code>nsfilemanager *filemanager = [nsfilemanager defaultmanager];</code>
<code> </code><code>// 判斷視訊是否緩存完成,如果完成則播放本地緩存</code>
<code> </code><code>if</code> <code>([filemanager fileexistsatpath:filepath]) {</code>
<code> </code><code>mpmovieplayerviewcontroller *playerviewcontroller =[[mpmovieplayerviewcontroller alloc]initwithcontenturl:[nsurl urlwithstring: playurl]];</code>
<code> </code><code>[self presentmovieplayerviewcontrolleranimated:playerviewcontroller];</code>
<code> </code><code>else</code><code>{</code>
<code> </code><code>uialertview *alertview = [[uialertview alloc] initwithtitle:@</code><code>"sorry"</code> <code>message:@</code><code>"目前視訊未緩存"</code> <code>delegate:self cancelbuttontitle:@</code><code>"确定"</code> <code>otherbuttontitles:nil, nil];</code>
<code> </code><code>[alertview show];</code>
添加代理 <m3u8handlerdelegate,videodownloaddelegate>
24
25
26
27
28
29
30
31
32
33
34
<code>#pragma mark --------------視訊解析完成----------------</code>
<code>-(</code><code>void</code><code>)prasem3u8finished:(m3u8handler*)handler</code>
<code> </code><code>handler.playlist.</code><code>uuid</code> <code>= @</code><code>"xnziwmde5nzi4"</code><code>;</code>
<code> </code><code>self.downloader = [[videodownloader alloc]initwithm3u8list:handler.playlist];</code>
<code> </code><code>[self.downloader addobserver:self forkeypath:@</code><code>"totalprogress"</code> <code>options:nskeyvalueobservingoptionnew | nskeyvalueobservingoptionold context:nil];</code>
<code> </code><code>self.downloader.delegate = self;</code>
<code> </code><code>[self.downloader startdownloadvideo];</code>
<code>-(</code><code>void</code><code>)observevalueforkeypath:(nsstring *)keypath ofobject:(id)object change:(nsdictionary *)change context:(</code><code>void</code> <code>*)context</code>
<code> </code><code>nslog(@</code><code>"下載下傳進度 - %f"</code><code>, self.downloader.totalprogress);</code>
<code>#pragma mark --------------視訊解析失敗----------------</code>
<code>-(</code><code>void</code><code>)prasem3u8failed:(m3u8handler*)handler</code>
<code> </code><code>nslog(@</code><code>"視訊解析失敗-failed -- %@"</code><code>,handler);</code>
<code>#pragma mark --------------視訊下載下傳完成----------------</code>
<code>-(</code><code>void</code><code>)videodownloaderfinished:(videodownloader*)request</code>
<code> </code><code>[[uiapplication sharedapplication] setnetworkactivityindicatorvisible:no];</code>
<code> </code><code>[request createlocalm3u8file];</code>
<code> </code><code>nslog(@</code><code>"----------視訊下載下傳完成-------------"</code><code>);</code>
<code>#pragma mark --------------視訊下載下傳失敗----------------</code>
<code>-(</code><code>void</code><code>)videodownloaderfailed:(videodownloader*)request</code>
<code> </code><code>nslog(@</code><code>"----------視訊下載下傳失敗-----------"</code><code>);</code>
原文出自:http://my.oschina.net/cgshare/blog/302303