標籤:
進式下載(偽流媒體)
介於下載本地播放與即時資料流媒體之間的一種播放形式,下載本地播放必須全部將檔案下載完成後才能播放,而漸進式下載不必等到全部下載完成後再播放,它可以一邊下載一邊播放,在完成播放內容之後,整個檔案會儲存在手機上。
即時資料流媒體
即時資料流媒體是一邊接收資料包一邊播放,本地不保留檔案副本,即時資料流式傳輸總是即時傳送,可以即時實況轉播,支援隨機訪問,使用者可以快進或者快退以觀看前面或後面的內容。即時資料流媒體傳輸必須保證資料包的傳輸速度大於檔案的播放速度,否則使用者看到的視頻會出現暫停。當網路堵塞情況下視頻品質會下降,所以要想保證視頻的品質漸進式下載會更好一些。
即時資料流媒體協議:
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
添加標頭檔
?
| 1234 |
#import <MediaPlayer/MediaPlayer.h>#import "M3U8Handler.h"#import "VideoDownloader.h"#import "HTTPServer.h" |
聲明屬性:
?
| 12 |
@property (nonatomic, strong)HTTPServer * httpServer;@property (nonatomic, strong)VideoDownloader *downloader; |
預先播放,畢先設定伺服器
?
| 1234567891011121314151617181920212223 |
#pragma mark - 開啟本機伺服器- (void)openHttpServer{ self.httpServer = [[HTTPServer alloc] init]; [self.httpServer setType:@"_http._tcp."]; // 設定服務類型 [self.httpServer setPort:12345]; // 設定伺服器連接埠 // 擷取本地Documents路徑 NSString *pathPrefix = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) objectAtIndex:0]; // 擷取本地Documents路徑下downloads路徑 NSString *webPath = [pathPrefix stringByAppendingPathComponent:kPathDownload]; NSLog(@"-------------\nSetting document root: %@\n", webPath); // 設定伺服器路徑 [self.httpServer setDocumentRoot:webPath]; NSError *error; if(![self.httpServer start:&error]) { NSLog(@"-------------\nError starting HTTP Server: %@\n", error); }} |
搭建完成後,播放什麼的,都是取決於需求
線上流媒體播放
?
| 123456 |
// 優酷視頻m3u8新地址格式如下:http://pl.youku.com/playlist/m3u8?vid=XNzIwMDE5NzI4&type=mp4 // 如果上面的連結不可用,那麼使用這個連結http://v.youku.com/player/getM3U8/vid/XNzIwMDE5NzI4/type/flv NSURL *url = [[NSURL alloc] initWithString:@"http://v.youku.com/player/getM3U8/vid/XNzIwMDE5NzI4/type/mp4"]; MPMoviePlayerViewController *player = [[MPMoviePlayerViewController alloc] initWithContentURL:url]; [self presentMoviePlayerViewControllerAnimated:player]; |
視頻下載
?
| 1234567 |
M3U8Handler *handler = [[M3U8Handler alloc] init]; handler.delegate = self; // 解析m3u8視頻地址 [handler praseUrl:[NSString stringWithFormat:@"http://pl.youku.com/playlist/m3u8?vid=XNzIwMDE5NzI4&type=mp4"]]; // 開啟網路指標 [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; |
播放本地視頻
?
| 12345678910111213141516171819202122 |
NSString * playurl = [NSString stringWithFormat:@"http://127.0.0.1:12345/XNzIwMDE5NzI4/movie.m3u8"]; NSLog(@"本地視頻地址-----%@", playurl); // 擷取本地Documents路徑 NSString *pathPrefix = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES) objectAtIndex:0]; // 擷取本地Documents路徑下downloads路徑 NSString *localDownloadsPath = [pathPrefix stringByAppendingPathComponent:kPathDownload]; // 擷取視頻本地路徑 NSString *filePath = [localDownloadsPath stringByAppendingPathComponent:@"XNzIwMDE5NzI4/movie.m3u8"]; NSFileManager *fileManager = [NSFileManager defaultManager]; // 判斷視頻是否緩衝完成,如果完成則播放本機快取 if ([fileManager fileExistsAtPath:filePath]) { MPMoviePlayerViewController *playerViewController =[[MPMoviePlayerViewController alloc]initWithContentURL:[NSURL URLWithString: playurl]]; [self presentMoviePlayerViewControllerAnimated:playerViewController]; } else{ UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Sorry" message:@"當前視頻未緩衝" delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil]; [alertView show]; } |
添加代理 <M3U8HandlerDelegate,VideoDownloadDelegate>
?
| 12345678910111213141516171819202122232425262728293031323334 |
#pragma mark --------------視頻解析完成-----------------(void)praseM3U8Finished:(M3U8Handler*)handler{ handler.playlist.uuid = @"XNzIwMDE5NzI4"; self.downloader = [[VideoDownloader alloc]initWithM3U8List:handler.playlist]; [self.downloader addObserver:self forKeyPath:@"totalprogress" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil]; self.downloader.delegate = self; [self.downloader startDownloadVideo];} -(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ NSLog(@"下載進度 - %f", self.downloader.totalprogress);} #pragma mark --------------視頻解析失敗-----------------(void)praseM3U8Failed:(M3U8Handler*)handler{ NSLog(@"視頻解析失敗-failed -- %@",handler);} #pragma mark --------------視頻下載完成-----------------(void)videoDownloaderFinished:(VideoDownloader*)request{ [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; [request createLocalM3U8file]; NSLog(@"----------視頻下載完成-------------");} #pragma mark --------------視頻下載失敗-----------------(void)videoDownloaderFailed:(VideoDownloader*)request{ NSLog(@"----------視頻下載失敗-----------");} |
ios流媒體--播放,下載