播放沙盒里的m3u8流,大致流程为:
1、在沙盒里搭建本地虚拟服务器
2、下载m3u8文件到沙盒(本文采取把已下载好的流拷贝到沙盒里)
3、以虚拟host+port的方式,播放m3u8流
一、搭建沙盒虚拟服务器
我们借助开源项目GCDWebServer,附上github链接GCDWebServer
1、创建工程,导入GCDWebServer
pod 'GCDWebServer/WebDAV', '~> 3.3.3'
2、搭建虚拟服务器,并启动
#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];
//判断沙盒下是否存在,把工程的文件复制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(@"%@.%@成功复制到沙盒", fileName, fileType);
}else {
NSLog(@"%@.%@复制到沙盒失败", 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
四、运行效果
五、最后附上网盘源码链接
经小伙伴指出,在真机上无法播放,查了下原因是,代码里webServer的端口写的默认的,应该是被占用了,因此就换了个端口,更新了下demo
新的demo源码
github-demo链接