播放沙盒里的m3u8流,大致流程為:
1换怖、在沙盒里搭建本地虛擬服務(wù)器
2苔严、下載m3u8文件到沙盒(本文采取把已下載好的流拷貝到沙盒里)
3定枷、以虛擬host+port的方式,播放m3u8流
一届氢、搭建沙盒虛擬服務(wù)器
我們借助開源項目GCDWebServer欠窒,附上github鏈接GCDWebServer
1、創(chuàng)建工程退子,導(dǎo)入GCDWebServer
pod 'GCDWebServer/WebDAV', '~> 3.3.3'
2贱迟、搭建虛擬服務(wù)器姐扮,并啟動
#import "AppDelegate.h"
#import "GCDWebDAVServer.h"
@interface AppDelegate ()
@property (nonatomic, strong) GCDWebDAVServer* davServer;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
_davServer = [[GCDWebDAVServer alloc] initWithUploadDirectory:documentsPath];
[_davServer start];
NSLog(@"serverURL:%@", _davServer.serverURL);
return YES;
}
二、拷貝m3u8流到沙盒里
拷貝m3u8索引文件及其ts切片到沙盒document目錄里
#import "ViewController.h"
#import "GCDWebDAVServer.h"
#import "PlayerViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.backgroundColor = [UIColor redColor];
btn.frame = CGRectMake(100, 100, 50, 50);
[btn setTitle:@"click" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(bntClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
[self copyFileToDocument:@"testVideo" type:@"m3u8"];
[self copyFileToDocument:@"testVideo-0" type:@"ts"];
[self copyFileToDocument:@"testVideo-1" type:@"ts"];
}
- (void)bntClick{
PlayerViewController *player = [[PlayerViewController alloc] init];
[self presentViewController:player animated:YES completion:nil];
}
- (void)copyFileToDocument:(NSString*)fileName type:(NSString *)fileType{
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@",fileName, fileType]];
NSFileManager *fm = [NSFileManager defaultManager];
//判斷沙盒下是否存在衣吠,把工程的文件復(fù)制document目錄下
BOOL isExist = [fm fileExistsAtPath:filePath];
if (!isExist){
//獲取工程中文件
NSString *fileBundlePath = [[NSBundle mainBundle] pathForResource:fileName ofType:fileType];
if ([fm copyItemAtPath:fileBundlePath toPath:filePath error:nil]) {
NSLog(@"%@.%@成功復(fù)制到沙盒", fileName, fileType);
}else {
NSLog(@"%@.%@復(fù)制到沙盒失敗", fileName, fileType);
}
} else {
NSLog(@"%@.%@已存在沙盒里", fileName, fileType);
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
三茶敏、開始播放
采取最簡單的AVPlayer來播放
#import "PlayerViewController.h"
@interface PlayerViewController ()
@property (nonatomic, strong) AVPlayerLayer *playerLayer;
@property (nonatomic, strong) AVPlayer *player;
@property (nonatomic, strong) AVPlayerItem *playerItem;
@end
@implementation PlayerViewController
- (void)viewDidLoad
{
[super viewDidLoad];
NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documentsPath stringByAppendingPathComponent:@"testVideo.m3u8"];
NSFileManager *fm = [NSFileManager defaultManager];
if ([fm fileExistsAtPath:filePath]) {
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://localhost:8080/testVideo.m3u8"]];
self.playerItem = [AVPlayerItem playerItemWithURL:url];
self.player = [AVPlayer playerWithPlayerItem:self.playerItem];
self.playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
self.playerLayer.frame = self.view.bounds;
self.playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;
[self.view.layer addSublayer:self.playerLayer];
[self.player play];
}else {
NSLog(@"文件不存在");
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
四、運行效果
五缚俏、最后附上網(wǎng)盤源碼鏈接
經(jīng)小伙伴指出惊搏,在真機(jī)上無法播放,查了下原因是忧换,代碼里webServer的端口寫的默認(rèn)的恬惯,應(yīng)該是被占用了,因此就換了個端口亚茬,更新了下demo