您的位置:首页 > 移动开发 > IOS开发

iOS个人整理41-多媒体-音视频播放

2016-04-15 20:12 344 查看

如果要音乐支持后台播放

在AppDelegate.m的didFinishLaunch方法里面写下面

//支持后台播放
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
//激活
[session setActive:YES error:nil];


在info.plist里面修改



一、System Sound Service

它是最底层也是最简单的声音播放服务,通过调用AudioServicesPlaySystemSound这个函数就可以播放一些简单的音频文件

适用场景:很小的提示或者警告音

局限性

1.声音长度小于30秒

2.格式 IMA4

3.不能控制播放的进度

4.调用方法后立即播放声音

5.没有循环播放和立体声音播放

//先从bundle中获取音频文件
NSString *musicPath = [[NSBundle mainBundle]pathForResource:@"news" ofType:@"wav"];

//播放音频时,需要的路径为url
NSURL *musicUrl = [NSURL fileURLWithPath:musicPath];
//创建soundID 播放系统提示音或者指定的音频文件,都是根据soundID来找音频文件,大小范围为1000~2000
SystemSoundID mySoundID;
//创建
AudioServicesCreateSystemSoundID((__bridge CFURLRef)musicUrl, &mySoundID);
//播放纯音乐
AudioServicesPlaySystemSound(mySoundID);

//提示音和震动
AudioServicesPlayAlertSound(mySoundID);


二、AVAudioPlayer

我们可以把AVAudioPlayer看作一个高级的播放器,它支持广泛的音频格式

优势

1.支持更多格式

2.可播放任意长度

3.支持循环

4.可以同步播放多个

5.控制播放进度以及从音频的任意一点开始

//AVAudioPlayer
- (IBAction)avAudioPlayer:(UIButton *)sender {

//得到音频资源
NSString *musicPath = [[NSBundle mainBundle]pathForResource:@"小猪歌" ofType:@"mp3"];
//转换为URL
NSURL *musicUrl = [NSURL fileURLWithPath:musicPath];
//创建player对象
_audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:musicUrl error:nil];
//设置声音0~1
_audioPlayer.volume = 0.5;
//准备播放
[_audioPlayer prepareToPlay];

//播放进度
//    _audioPlayer.currentTime = 0;
//循环播放次数 负数无限循环
//    _audioPlayer.numberOfLoops = -1;

//播放
[_audioPlayer play];
//暂停
//[_audioPlayer pause];
//停止
//[_audioPlayer stop];
}


三、视频AVPlayer

iOS里视频播放使用AVPlayer,比AVAudioPlayer更强大,可以直接播放网络音视频

AVPlayerItem,资源管理对象,作用:切换视频播放,

1.状态 status

AVPlayerItemStatusUnknown,未知

AVPlayerItemStatusReadyToPlay,准备好播放,可以paly

AVPlayerItemStatusFailed,失败

2.loadedTimeRange

代表缓存的进度,监听此属性可以在UI中更新缓存进度

播放完成的通知,可以注册通知,做出响应

AVPlayerItemDidPlayToEndTimeNotification

AVPlayerLayer

单纯使用AVPlayer无法显示视频,因为这个类并没有真正的视图,需要将视频层添加到AVPlayerLayer中

@property (nonatomic,retain)AVPlayer *player;//播放器
@property (nonatomic,retain)AVPlayerItem *playerItem;//播放对象
@property (nonatomic,retain)AVPlayerLayer *playerLayer;//显示视频的层
@property (weak, nonatomic) IBOutlet UISlider *videoSlider;//视频播放进度
@property (nonatomic,assign)BOOL isReayToPlay;//判断是否已经开始播放O
@property (weak, nonatomic) IBOutlet UILabel *timeLabel; //显示事件的label
@property (nonatomic,retain)NSTimer *timer;

- (void)viewDidLoad {
[super viewDidLoad];
//还没有准备好播放视频
_isReayToPlay = NO;
//启动视频准备
[self netVideoPlay];
//计时器
_timer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(progressAction) userInfo:nil repeats:YES];
}

//得到视频
-(void)netVideoPlay
{
NSString *urlStr =  @"http://static.tripbe.com/videofiles/20121214/9533522808.f4v.mp4";
NSString *urlStr2 = [[NSBundle mainBundle]pathForResource:@"test" ofType:@"mp4"];

//播放下一个视频
//    [_player replaceCurrentItemWithPlayerItem: nextPlayerItem];

//得到视频资源的URL
NSURL *videoURL = [NSURL fileURLWithPath:urlStr2];

//初始化item
_playerItem = [[AVPlayerItem alloc]initWithURL:videoURL];
//初始化播放器
_player = [AVPlayer playerWithPlayerItem:_playerItem];

//显示图像的layer
_playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
//将视频层添加到当前解密的layer上
[self.view.layer addSublayer:_playerLayer];
_playerLayer.frame = CGRectMake(100, 100, 200, 200);
//让视频层适应当前界面
_playerLayer.videoGravity = AVLayerVideoGravityResizeAspect;

//为item添加观察者,当视频已经准备好播放的时候再播放
[_playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
}

#pragma mark -- KVO回调方法

//keyPath:变化的属性的名称  如果属性是声明在.m中就监测不到?
//object:被观察的对象
//change:存放属性变化前后的值
//context:添加观察者时候context的值
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
AVPlayerItem *item = (AVPlayerItem*)object;
NSLog(@"item -- %@",item);
//取出变化之后的属性值
NSLog(@"new -- %@ ",change[NSKeyValueChangeNewKey]);
//取出变化之前的
NSLog(@"old -- %@",change[NSKeyValueChangeOldKey]);

//得到改变后的status
AVPlayerItemStatus status = [change[NSKeyValueChangeNewKey]intValue];
//对比,看目前播放单元的状态
switch (status) {
case AVPlayerItemStatusUnknown:
NSLog(@"未知状态");
break;
case AVPlayerItemStatusFailed:
NSLog(@"失败");
break;
case AVPlayerItemStatusReadyToPlay:
{
NSLog(@"准备好播放");
[self.player play];
_isReayToPlay = YES;
}
break;
default:
break;
}
//视频的总长度
float second = _playerItem.duration.value/_playerItem.duration.timescale;
NSLog(@"视频长度 %f",second);
//设置滑竿的最大值
_videoSlider.maximumValue = second;
_videoSlider.minimumValue = 0;

//移除观察者
[item removeObserver:self forKeyPath:@"status"];


这里略去了很多东西,我们应该添加一个sliderView,通过NSTimer的方法,来实时显示视频的播放进度,同时移动sliderView时可以控制视频的播放进度。

//进度条的回调方法
-(void)changeProgress:(UISlider*)sender
{
//每次调整之前,暂停播放
[_player pause];
if (_isReayToPlay) {
//说明已经有时长了,可以进行操作
//设置播放的区间
//参数1.CMTime从哪个时刻开始播放
//参数2.回调,设置完成后要进行的动作
[self.player seekToTime:CMTimeMakeWithSeconds(sender.value, self.playerItem.currentTime.timescale) completionHandler:^(BOOL finished) {
if (finished) {
//调整已经结束,可以播放了
[_player play];
}
}];
}
}

//进度条根据播放进度变动
-(void)progressAction
{
//label显示当前时间
NSDate *currentTime =[NSDate dateWithTimeIntervalSinceReferenceDate:round(_playerItem.currentTime.value/_playerItem.currentTime.timescale)];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"mm:ss"];
_timeLabel.text=[formatter stringFromDate:currentTime];

//进度条变动
_videoSlider.value = _playerItem.currentTime.value/_playerItem.currentTime.timescale;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: