时间:2021-04-17 09:52:38 | 栏目:iOS代码 | 点击:次
需求:最近公司需要做一个楼宇对讲的功能:门口机(连接WIFI)拨号对室内机(对应的WIFI)的设备进行呼叫,室内机收到呼叫之后将对收到的数据进行UDP广播的转发,手机(连接对应的WIFI)收到视频流之后,实时的展示视频数据(手机可以接听,挂断,手机接听之后,室内机不展示视频,只是进行转发。)
简单点说就是手机客户端需要做一个类似于直播平台的软件,可以实时的展示视频,实时的播放接收到的声音数据,并且实时将手机麦克风收到的声音回传给室内机,室内机负责转发给门口机。
之前从来做过视频播放都是本地文件的直接播放,从来没有做过网络视频流的播放,百度了很多都是介绍框架怎么使用的,按着它的流程是行不通的,没有一个详细的使用流程!!!想哭呀!!!
这篇文章说一下本地视频文件播放和网络视频播放以及三方框架的使用,有不对的地方欢迎指正!!!
#pragma mark -- 本地视频文件播放
使用AVFoundation.framework
第一步:导入框架AVFoundation.framework
//经过测试:不导入这个框架也能播放,在第三步使用的时候导入就行了,为了不出现未知的BUG还是乖乖的导入吧!!!
第二步: 拖入一个视频文件到你的项目中
第三步: 代码实现
#import "ViewController.h" #import <AVFoundation/AVFoundation.h> //需要导入框架 #define EYScreenWidth [[UIScreen mainScreen] bounds].size.width #define EYScreenHeight [[UIScreen mainScreen] bounds].size.height @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //1.从mainBundle获取test.mp4的具体路径 NSString * path = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"mp4"]; //2.文件的url NSURL * url = [NSURL fileURLWithPath:path]; //3.根据url创建播放器(player本身不能显示视频) AVPlayer * player = [AVPlayer playerWithURL:url]; //4.根据播放器创建一个视图播放的图层 AVPlayerLayer * layer = [AVPlayerLayer playerLayerWithPlayer:player]; //5.设置图层的大小 layer.frame = CGRectMake(0, 0, EYScreenWidth, EYScreenHeight); //6.添加到控制器的view的图层上面 [self.view.layer addSublayer:layer]; //7.开始播放 [player play]; } @end
#pragma mark -- 网络视频流播放
方式一:MobileVLCKit.framework
第一步: 下载MobileVLCKit.framework
1. 可以去百度官网地址,上面有详细的编译步骤,GitHub上面也有详细的教程!!!--->之后直接进行第六步!!!
2. 我已经编译好了 真机和模拟器都可以使用的: MobileVLCKit.framework
链接: https://pan.baidu.com/s/1pLz7DTx密码: te5p
第二步: 将下载下来的zip解压,MobileVLCKit文件夹中的MobileVLCKit.framework 拖入到你的工程中
第四步: 选择finish
第五步:添加依赖库
1: AudioToolbox.framework
2: VideoToolbox.framework
3: CoreMedia.framework
4: CoreVideo.framework
5: CoreAudio.framework
6: AVFoundation.framework
7: MediaPlayer.framework
8: libstdc++.6.0.9.tbd
9: libiconv.2.tbd
10: libc++.1.tbd
11: libz.1.tbd
12: libbz2.1.0.tbd
共12个
完成之后如图所示:
第六步: 使用框架
ViewController.h
#import <UIKit/UIKit.h> @interface ViewController : UIViewController //视频流的路径,外界传过来的视频流的地址 @property (nonatomic, copy) NSString * rtspPath; @end
ViewController.m
#import "ViewController.h" #import <MobileVLCKit/MobileVLCKit.h> //屏幕宽高的宏 #define EYScreenWidth [[UIScreen mainScreen] bounds].size.width #define EYScreenHeight [[UIScreen mainScreen] bounds].size.height @interface ViewController () //视频播放 @property (nonatomic, strong) VLCMediaPlayer *player; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //1.创建播放视图,模拟器测试会有问题!!!真机可以正常播放 UIView *videoView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, EYScreenWidth, EYScreenHeight)]; [self.view addSubview:videoView]; //2.创建播放器 self.player = [[VLCMediaPlayer alloc] initWithOptions:nil]; //3.设置播放图层 self.player.drawable = videoView; //4.设置播放的路径 self.player.media = [VLCMedia mediaWithURL:[NSURL URLWithString:self.rtspPath]]; //5.开始播放 [self.player play]; } - (void)dealloc { if (self.player.isPlaying) { [self.player stop]; } } @end
第七步: 真机测试
Command + R 运行报错
在工程设置中,Setting搜索bitcode,将Yes修改为No
如果出现下图错误,将对应文件的第38行代码注释掉就行了!
再次运行就是OK了!!!
如果不好使尝试将ViewController.m----->ViewController.mm
如果上面的路径是本地路径的话,是可以播放本地视频的!!!
方式二: IJKMediaFramework
第一步: 下载IJKMediaFramework
1. 可以去百度官网地址,上面有详细的编译步骤,GitHub上面也有详细的教程!!! -->之后直接进行第三步!!!
2. 我已经编译好了 真机和模拟器都可以使用的:IJKMediaFramework
链接: https://pan.baidu.com/s/1o8G4ETG密码: 3cbr
第二步: 将下载下来的IJK.zip解压,IJK文件夹中的
1、IJKMediaFramework.framework
2、libcrypto.a
3、librtmp.a
4、libssl.a
总共4个拖入到你的工程中
第三步: 编写代码
ViewController.h
#import <UIKit/UIKit.h> @interface ViewController : UIViewController //视频流的路径 @property (nonatomic, copy) NSString * rtspPath; @end
ViewController.m
#import "ViewController.h" #import <IJKMediaFramework/IJKMediaFramework.h> // 宏定义 #define EYScreenBounds [UIScreen mainScreen].bounds @interface ViewController () @property (nonatomic, strong) IJKFFMoviePlayerController * ijkPlayer; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; //初始化播放控制器 self.ijkPlayer = [[IJKFFMoviePlayerController alloc] initWithContentURLString:self.rtspPath withOptions:nil]; //设置打印级别, 测试发现没有什么效果 [IJKFFMoviePlayerController setLogLevel:k_IJK_LOG_DEBUG]; //设置控制器的view大小 self.ijkPlayer.view.frame = EYScreenBounds; //控制器的view添加到自身的view上面 [self.view addSubview:self.ijkPlayer.view]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; if (!self.ijkPlayer.isPlaying) { //播放 [self.ijkPlayer prepareToPlay]; } } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; if (self.ijkPlayer.isPlaying) { //关闭 [self.ijkPlayer shutdown]; } } @end
注意点:方式一和方式二只能使用一个,因为他们两个会有冲突,暂时没有找到解决方案!!!(个人感觉应该是方式二中的.a与系统的.tbd有冲突)