天天看點

iOS 第三方之流媒體

進式下載下傳(僞流媒體)

介于下載下傳本地播放與實時流媒體之間的一種播放形式,下載下傳本地播放必須全部将檔案下載下傳完成後才能播放,而漸進式下載下傳不必等到全部下載下傳完成後再播放,它可以一邊下載下傳一邊播放,在完成播放内容之後,整個檔案會儲存在手機上。

實時流媒體

實時流媒體是一邊接收資料包一邊播放,本地不保留檔案副本,實時流式傳輸總是實時傳送,可以實時實況轉播,支援随機通路,使用者可以快進或者快退以觀看前面或後面的内容。實時流媒體傳輸必須保證資料包的傳輸速度大于檔案的播放速度,否則使用者看到的視訊會出現暫停。當網絡堵塞情況下視訊品質會下降,是以要想保證視訊的品質漸進式下載下傳會更好一些。

實時流媒體協定:

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 &lt;mediaplayer/mediaplayer.h&gt;</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:&amp;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&amp;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&amp;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>

添加代理 &lt;m3u8handlerdelegate,videodownloaddelegate&gt;

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