07亭螟、多媒體

一碾褂、音頻

iOS里面共有四種專門實(shí)現(xiàn)播放音頻的方式
1.System Sound Services (系統(tǒng)聲音服務(wù)) 它是最底層也是最簡單的聲音服務(wù) 一般用來播放一些很小的提示音或者警告音泣港,還有很大的局限性:聲音長度要小于30s;格式為IMA4价匠;不能控制播放進(jìn)度当纱;調(diào)用方法后立即播放聲音;沒有循環(huán)播放和立體聲音播放霞怀;
具體代碼如下:

//system sounds services  系統(tǒng)聲音服務(wù)
-(void)systemSoundsServices{
  //得到要播放的資源
    NSString* wavPath=[[NSBundle mainBundle] pathForResource:@"1" ofType:@"wav"];
    //聲明聲音的ID  要給我們的歌曲添加系統(tǒng)的ID惫东,讓系統(tǒng)可以根據(jù)該ID找到該音頻資源
    SystemSoundID soundsID;
    //創(chuàng)建ID
    //第一個(gè)參數(shù):音頻資源的路徑
    //第二個(gè)參數(shù):對(duì)soundsID取地址
    //把文件路徑轉(zhuǎn)換成URL
    NSURL* url=[NSURL fileURLWithPath:wavPath];
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &soundsID);
    //播放帶震動(dòng)
    AudioServicesPlayAlertSound(soundsID);
    //只播放聲音,不帶震動(dòng)效果
    AudioServicesPlaySystemSound(soundsID);
    
}

另一種寫法也可以實(shí)現(xiàn)

-(void)cfsystemSoundsServices{
    CFBundleRef mainBun;
    SystemSoundID soundsID;
    mainBun=CFBundleGetMainBundle();
    CFURLRef soundRef=CFBundleCopyResourceURL(mainBun, CFSTR("1"), CFSTR("wav"), NULL);
     AudioServicesCreateSystemSoundID(soundRef, &soundsID);
     AudioServicesPlaySystemSound(soundsID);
    
}

2.OpenAL (跨平臺(tái)的開源的音頻處理接口) 一般用來做開發(fā)游戲的音頻毙石;詳細(xì)資料請(qǐng)參考以下兩個(gè)網(wǎng)址
http://www.devdiv.com/thread-19636-1-1.html
http://www.cocoachina.com/bbs/read.php?tid-112679-page-1.html
3.Audio Queue Services (播放和錄制音頻服務(wù)) 主要用來實(shí)現(xiàn)錄制音頻廉沮,為了簡化音頻文件的處理,通常還需要使用到AudioFileServices徐矩,可以參考http://blog.csdn.net/midfar/article/details/7233454
4.AVAudioPlayer (高級(jí)音頻播放器) 可以支持多種格式的音頻播放滞时;可以播放任一長度的音頻文件;支持循環(huán)播放滤灯;可以同步播放多個(gè)音頻文件坪稽;控制播放進(jìn)度以及從音頻的任意一點(diǎn)開始播放。
在這里我們做一個(gè)簡單的音樂播放器鳞骤,從上往下窒百,第一個(gè)進(jìn)度條是控制進(jìn)度的,第二個(gè)slider是控制音量的

音樂播放器.png

先在storyBoard中搭建界面豫尽,并將要用的控件拖成屬性或方法

屏幕快照 2016-12-28 下午8.25.39.png

先導(dǎo)入<AVFoundation/AVFoundation.h> <AudioToolbox/AudioToolbox.h>

#import "ViewController.h"
#import <AudioToolbox/AudioToolbox.h>
#import <AVFoundation/AVFoundation.h>
#import "customSlider.h"
@interface ViewController ()<customSliderDelegate,AVAudioPlayerDelegate>{
    AVAudioPlayer* player;
}

@property (weak, nonatomic) IBOutlet customSlider *progressSlider;//自定義的進(jìn)度條
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;//音頻的時(shí)長
@property(nonatomic,retain)NSTimer* timer;//定時(shí)器

@property (weak, nonatomic) IBOutlet UIImageView *albumImg;//專輯圖片
@property (weak, nonatomic) IBOutlet UIImageView *bigImg;//高斯模糊的背景圖
@property (weak, nonatomic) IBOutlet UILabel *musicNamaLabel;//音樂的名字
@property (weak, nonatomic) IBOutlet UIButton *pauseOrplayBtn;//暫透萆遥或者播放的按鈕
@property(nonatomic,retain)NSMutableArray* allMusicArray;//存放所有的歌曲
@property(nonatomic,assign)NSInteger currentIndex;//當(dāng)前播放的歌曲是第幾首

- (IBAction)lastBtn:(UIButton *)sender;//上一曲的點(diǎn)擊按鈕
- (IBAction)nextBtn:(UIButton *)sender;//下一曲的點(diǎn)擊按鈕

- (IBAction)playOrPause:(UIButton *)sender;//暫停或者播放的按鈕
- (IBAction)volumAction:(UISlider *)sender;//控制聲音的slider
@end

@implementation ViewController

//判斷當(dāng)前音樂是否播放完畢
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag{
    [self nextBtn:nil];
    
}

//存放所有的歌曲
-(NSMutableArray*)allMusicArray{
    if (!_allMusicArray) {
        _allMusicArray=[[NSMutableArray alloc] init];
    }
    return _allMusicArray;
}

//創(chuàng)建本地歌曲資源
-(void)creatSourceOfMusic{
    
    NSDictionary* music_Dic1=@{@"name":@"楊承熹-IF YOU.mp3",@"img":@"111.png"};
     NSDictionary* music_Dic2=@{@"name":@"薛之謙 - 你還要我怎樣.mp3",@"img":@"xzq11.png"};
     NSDictionary* music_Dic3=@{@"name":@"Maroon 5-Sugar.mp3",@"img":@"sugar.png"};
     NSDictionary* music_Dic4=@{@"name":@"Justin Bieber-Eenie Meenie.mp3",@"img":@"justin.png"};
     NSDictionary* music_Dic5=@{@"name":@"香香-戀歌.mp3",@"img":@"lg.png"};
    NSDictionary* music_Dic6=@{@"name":@"薛之謙-紳士.mp3",@"img":@"xzq22.png"};
    // 添加
    [self.allMusicArray addObjectsFromArray:@[music_Dic1,music_Dic2,music_Dic3,music_Dic4,music_Dic5,music_Dic6]];
}

//上一首
- (IBAction)lastBtn:(UIButton *)sender {
   //判斷當(dāng)前播放的歌曲是否為第一首歌美旧,如果是渤滞,就播放最后一首,如果不是榴嗅,就-1
    if (self.currentIndex==0) {
        //是第一首歌,播放最后一首
        NSDictionary* dic=self.allMusicArray.lastObject;
        [self avAudioPlayerWithName:dic[@"name"]];
        self.albumImg.image=[UIImage imageNamed:dic[@"img"]];
        self.bigImg.image=[UIImage imageNamed:dic[@"img"]];
         self.musicNamaLabel.text=dic[@"name"];
        [self playPlayer];
        self.currentIndex=self.allMusicArray.count-1;
       
    }else{
        self.currentIndex--;
        NSDictionary* dic=self.allMusicArray[self.currentIndex];
         [self avAudioPlayerWithName:dic[@"name"]];
        self.albumImg.image=[UIImage imageNamed:dic[@"img"]];
        self.bigImg.image=[UIImage imageNamed:dic[@"img"]];
         self.musicNamaLabel.text=dic[@"name"];
        [self playPlayer];
    }
    
    [self.pauseOrplayBtn setTitle:@"暫停" forState:(UIControlStateNormal)];
    
}

//下一首
- (IBAction)nextBtn:(UIButton *)sender {
    //判斷當(dāng)前播放的歌曲是否為最后一首歌妄呕,如果是,就播放第一首
    if (self.currentIndex==self.allMusicArray.count-1) {
        NSDictionary* dic=self.allMusicArray.firstObject;
        [self avAudioPlayerWithName:dic[@"name"]];
        self.albumImg.image=[UIImage imageNamed:dic[@"img"]];
        self.bigImg.image=[UIImage imageNamed:dic[@"img"]];
        self.musicNamaLabel.text=dic[@"name"];
        [self playPlayer];
        self.currentIndex=0;
    }else{
        self.currentIndex++;
        NSDictionary* dic=self.allMusicArray[self.currentIndex];
        [self avAudioPlayerWithName:dic[@"name"]];
        self.albumImg.image=[UIImage imageNamed:dic[@"img"]];
        self.bigImg.image=[UIImage imageNamed:dic[@"img"]];
         self.musicNamaLabel.text=dic[@"name"];
        [self playPlayer];
    }

    [self.pauseOrplayBtn setTitle:@"暫停" forState:(UIControlStateNormal)];
    
    
}

//毛玻璃效果
-(void)effectMethod{
    UIBlurEffect* blureffect=[UIBlurEffect effectWithStyle:(UIBlurEffectStyleLight)];
     UIVisualEffectView* effectView=[[UIVisualEffectView alloc] initWithEffect:blureffect];
    effectView.frame=self.view.bounds;
    [self.bigImg addSubview:effectView];
}
-(NSTimer*)timer{
    if (!_timer) {
        //初始化的定時(shí)器會(huì)自動(dòng)開啟嗽测,不需要手動(dòng)開啟
        //第一個(gè)參數(shù):每隔幾秒執(zhí)行一次定時(shí)器回調(diào)方法
        //第二個(gè)參數(shù):定時(shí)器的回調(diào)方法在哪個(gè)類中實(shí)現(xiàn)就寫哪個(gè)類的對(duì)象绪励,一般寫self
        //第三個(gè)參數(shù):定時(shí)器的回調(diào)方法 如果帶參數(shù),參數(shù)就是定時(shí)器對(duì)象本身唠粥,類似于按鈕
        //第四個(gè)參數(shù):向定時(shí)器回調(diào)方法中傳值优炬,通過_timer.userInfo得到此處所寫的值,如果不需要傳值厅贪,此處直接填nil
        //第五個(gè)參數(shù):是否重復(fù)執(zhí)行回調(diào)方法  YES:重復(fù)執(zhí)行  NO:只執(zhí)行一次
        _timer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
        
        //暫停timer  在將來的某一時(shí)刻開啟定時(shí)器
        [_timer setFireDate:[NSDate distantFuture]];
    }
    return _timer;
}

//timer的回調(diào)方法
-(void)timerAction{
    //更新進(jìn)度條的進(jìn)度
    self.progressSlider.value=player.currentTime;
    //時(shí)間調(diào)整
    //剩余的秒數(shù)
    NSTimeInterval restDuration=player.duration-player.currentTime;
    self.timeLabel.text=[self transformWithSeconds:(int)restDuration];
    self.albumImg.layer.transform=CATransform3DRotate(self.albumImg.layer.transform, M_PI/60, 0, 0, 1);
    
}

//暫停
-(void)pausePlayer{
    [player pause];
    //暫停定時(shí)器
    [self.timer setFireDate:[NSDate distantFuture]];
    
}

//播放
-(void)playPlayer{
    [player play];
    //開啟定時(shí)器
    [self.timer setFireDate:[NSDate distantPast]];
    
}

//AVAudioPlayer 只能播放本地音樂
-(void)avAudioPlayerWithName:(NSString*)musicName{
    //獲取資源路徑
  NSString* musicPath=[[NSBundle mainBundle] pathForResource:musicName ofType:nil];
     NSURL* url=[NSURL fileURLWithPath:musicPath];
     player=[[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
    //指定代理
    player.delegate=self;
    //設(shè)置音量
    player.volume=0.5;
    //準(zhǔn)備播放
    [player prepareToPlay];
    //獲取歌曲的總時(shí)長
    NSLog(@"111--%f",player.duration);
    //將slider的最大值設(shè)置為歌曲的總時(shí)長
    self.progressSlider.maximumValue=(int)player.duration;
    //顯示總時(shí)長
    self.timeLabel.text=[self transformWithSeconds:(int)player.duration];
    
    
    //播放
//    [player play];
    
}

//播放或者暫停
- (IBAction)playOrPause:(UIButton *)sender {
    //判斷當(dāng)前是否正在播放歌曲
    if (player.isPlaying) {
        //說明音樂正在播放,暫停
//        [player pause];
        [self pausePlayer];
        [sender setTitle:@"播放" forState:(UIControlStateNormal)];
    }else{
        //說明音樂在暫停狀態(tài)雅宾,開始播放
//        [player play];
        [self playPlayer];
        [sender setTitle:@"暫停" forState:(UIControlStateNormal)];
    }
    
        
}

//調(diào)整音量
- (IBAction)volumAction:(UISlider *)sender {
    
    //通過滑竿調(diào)整音量
    player.volume=sender.value;
    
}

//調(diào)整播放進(jìn)度
- (IBAction)progressAction:(customSlider *)sender {
    if (player.isPlaying) {
        //先暫停掉
//        [player pause];
        [self pausePlayer];
        
    }

    //讓播放器的當(dāng)前播放時(shí)間設(shè)置為和進(jìn)度條一致
//    player.currentTime = sender.value;
    
}

//手指離開slider的時(shí)候會(huì)執(zhí)行的代理方法
-(void)endDraggingWithSlider:(customSlider *)slider{
    player.currentTime = slider.value;
//    [player play];
    [self playPlayer];
    [self.pauseOrplayBtn setTitle:@"暫停" forState:(UIControlStateNormal)];
    
    
}

//將秒轉(zhuǎn)換為00:00:00的格式
-(NSString*)transformWithSeconds:(int)seconds{
    
    //獲取小時(shí)
    int hours=seconds/3600;
    //獲取分鐘
    //除去小時(shí)养涮,看剩下多少秒葵硕,總秒數(shù)對(duì)3600取余就是剩余的秒數(shù)
    int minutes=seconds%3600/60;
    //獲取秒數(shù)
    int second=seconds%60;
    NSString* hourStr=@"";
    NSString* minuteStr=@"";
    NSString* secondStr=@"";
    if (hours<10) {
        hourStr=[NSString stringWithFormat:@"0%d",hours];
        
    }else{
        hourStr=[NSString stringWithFormat:@"%d",hours];
    }
    
    if (minutes<10) {
        minuteStr=[NSString stringWithFormat:@"0%d",minutes];
    }else{
        minuteStr=[NSString stringWithFormat:@"%d",minutes];
    }
    
    if (second<10) {
        secondStr=[NSString stringWithFormat:@"0%d",second];
    }else{
        secondStr=[NSString stringWithFormat:@"%d",second];
    }
    NSArray* array=@[hourStr,minuteStr,secondStr];
    return [array componentsJoinedByString:@":"];
    
}

- (void)viewDidLoad {
    [super viewDidLoad];
    //創(chuàng)建資源的方法
    [self creatSourceOfMusic];
    NSDictionary* dic=self.allMusicArray[0];
    [self avAudioPlayerWithName:dic[@"name"]];
    self.musicNamaLabel.text=dic[@"name"];
    self.albumImg.layer.masksToBounds=YES;
    self.albumImg.layer.cornerRadius=75;
    self.progressSlider.delegate=self;
    [self effectMethod];
    
}

在這里還需要我們自定義一個(gè)slider用來控制音頻的播放進(jìn)度customSlider繼承于UISlider
customSlider.h中

#import <UIKit/UIKit.h>
@class customSlider;

@protocol  customSliderDelegate<NSObject>

-(void)endDraggingWithSlider:(customSlider*)slider;

@end

@interface customSlider : UISlider

@property(nonatomic,assign)id<customSliderDelegate>delegate;

@end

customSlider.m中

#import "customSlider.h"
@implementation customSlider

//當(dāng)手指離開滑動(dòng)條的時(shí)候
-(void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event{
    if (self.delegate && [self.delegate respondsToSelector:@selector(endDraggingWithSlider:)]) {
        
        [self.delegate endDraggingWithSlider:self];
        
    }else{
        NSLog(@"customSlider的代理未指定或者代理方法未實(shí)現(xiàn)");
    }
    
}

這樣一個(gè)簡單的音樂播放器就完成了,但這里只能播放本地的音樂哦??????????????

二贯吓、視頻

iOS里面的視頻用到的是AVPlayer(包含在AVFoundation)內(nèi)懈凹,與AVAudioPlayer有點(diǎn)類似,但是AVPlayer的功能更加強(qiáng)大悄谐,它既可以播放音頻也可以播放視頻介评,而且可以直接播放網(wǎng)絡(luò)音頻。
在這里做一個(gè)簡單的視頻播放器爬舰,從上往下们陆,第一個(gè)進(jìn)度條是控制進(jìn)度的,第二個(gè)slider是控制音量的


視頻播放器.png

先在storyBoard中搭建界面情屹,并將要用的控件拖成屬性或方法


storyBoard.png

先導(dǎo)入<AVFoundation/AVFoundation.h>

#import "AVPlayerViewController.h"
#import <AVFoundation/AVFoundation.h>
@interface AVPlayerViewController ()
@property(nonatomic,retain)AVPlayer* player;//播放器對(duì)象
@property(nonatomic,retain)AVPlayerItem* playerItem;//播放單元
@property(nonatomic,retain)AVPlayerLayer* layer;
@property (weak, nonatomic) IBOutlet UIButton *playOrpause;//播放或暫停
@property (weak, nonatomic) IBOutlet UISlider *progressSlider;//進(jìn)度條
@property (weak, nonatomic) IBOutlet UIButton *nextAction;//下一個(gè)
@property(nonatomic,assign)BOOL isPlaying;//標(biāo)志當(dāng)前是否為播放狀態(tài)
@property(nonatomic,retain)NSMutableArray* allSourcesMArray;//存放所有的視頻連接
@property(nonatomic,assign)NSInteger currentIndex;//當(dāng)前視頻播放的是第幾個(gè)
- (IBAction)volumAction:(UISlider *)sender;//控制音量的slider
- (IBAction)preAction:(UIButton *)sender;//上一個(gè)
- (IBAction)playAction:(UIButton *)sender;//播放按鈕
@end

@implementation AVPlayerViewController
-(NSMutableArray*)allSourcesMArray{
    if (!_allSourcesMArray) {
        _allSourcesMArray=[[NSMutableArray alloc] init];
        [_allSourcesMArray addObject:@"http://huya-w2.dwstatic.com/56/12/1642/3412476-100-1477091884.mp4"];
        [_allSourcesMArray addObject:@"http://www.xiaobuqi.com//d/file/joke/2016-01/1452962161.mp4"];
        [_allSourcesMArray addObject:@"http://www.xiaobuqi.com//d/file/joke/2016-01/1452184059.mp4"];
           }
    return _allSourcesMArray;
}

-(AVPlayerLayer*)layer{
    if (!_layer) {
        _layer=[[AVPlayerLayer alloc] init];
        //射中playerLayer的大小
        _layer.frame=self.view.bounds;
        //設(shè)置視頻縮放模式
        _layer.videoGravity=AVLayerVideoGravityResizeAspect;
        //添加
        [self.view.layer addSublayer:_layer];
    }
    return _layer;
}

-(void)playerMethodWithSourcePath:(NSString*)sourcePath{
    //資源URL
   
    if (!sourcePath ||sourcePath.length==0) {
        NSLog(@"資源路徑不能為空");
        return;
       
    }
     NSURL* url=nil;
    if ([sourcePath hasPrefix:@"http"]) {
        //網(wǎng)絡(luò)資源
        url=[NSURL URLWithString:sourcePath];
    }else{
        //本地資源
        url=[NSURL fileURLWithPath:sourcePath];
    }
    //創(chuàng)建播放單元
    self.playerItem=[AVPlayerItem playerItemWithURL:url];
    //創(chuàng)建播放器
    if (self.player && self.player.currentItem) {
        //說明播放器對(duì)象已經(jīng)存在
    [self.player.currentItem removeObserver:self forKeyPath:@"status"];
        [self.player replaceCurrentItemWithPlayerItem:self.playerItem];
    }else{
       //說明播放器對(duì)象不存在
        self.player=[AVPlayer playerWithPlayerItem:self.playerItem];
    }
    //創(chuàng)建顯示的layer對(duì)象
    if (!self.layer.player) {
        //如果layer沒有綁定播放器坪仇,就給他綁定一個(gè)播放器
        self.layer.player=self.player;
    }
    //通過KVO監(jiān)聽item的status的屬性的變化
    //表示多媒體資源是否準(zhǔn)備可以播放
    ////   self.playerItem.status;
    //    //KVO key-value-observer  檢測對(duì)象屬性是否發(fā)生變化
    //    //1.只有通過KVC或者屬性的setter方法進(jìn)行賦值,KVO才能監(jiān)測到
    //    //2.如果觀察同一個(gè)對(duì)象的同一個(gè)屬性垃你,在沒有移除舊的觀察者又添加新的同一個(gè)觀察者椅文,直接崩潰
    //    //3.如果沒有添加觀察者,但又移除觀察者惜颇,崩潰
    //    //4.如果觀察者被銷毀皆刺,但是沒有移除該觀察者,崩潰
    //5.如果被觀察者被銷毀凌摄,但是沒有移除觀察者羡蛾,崩潰
    //    //為被觀察者的對(duì)象添加觀察者
    //    // 第一個(gè)參數(shù):觀察者對(duì)象,KVO的回調(diào)方法在哪個(gè)類中實(shí)現(xiàn)望伦,觀察者就是哪個(gè)類對(duì)象
    //    //第二個(gè)參數(shù):要監(jiān)測被觀察對(duì)象的哪個(gè)屬性林说,此處就寫對(duì)應(yīng)的屬性名
    //    //第三個(gè)參數(shù):要觀察屬性的哪種狀態(tài)
    //    //第四個(gè)參數(shù):上下文,一般用來為KVO的回調(diào)方法傳值屯伞,如果不需要腿箩,直接寫nil
     [self.playerItem addObserver:self forKeyPath:@"status" options:(NSKeyValueObservingOptionNew) context:nil];
    // 調(diào)整音量
    self.player.volume=0.5;
    //監(jiān)測播放進(jìn)度
    //第一個(gè)參數(shù):從什么地方開始監(jiān)測
    //    //第二個(gè)參數(shù):將監(jiān)測過程在哪個(gè)隊(duì)列中進(jìn)行
    //    //第三個(gè)參數(shù):block   視頻播放過程中該block會(huì)多次執(zhí)行,block中的CMTime是當(dāng)前視頻播放的位置
    //    //防止block中造成循環(huán)引用造成內(nèi)存泄漏
    __weak AVPlayerViewController *vc=self;
    [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, self.playerItem.currentTime.timescale) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
     //更改進(jìn)度條的進(jìn)度
     vc.progressSlider.value= time.value/time.timescale;
        }];
     //通過廣播中心監(jiān)測視頻播放完成的狀態(tài)
    //第一個(gè)參數(shù):觀察者劣摇,用來監(jiān)聽廣播中心的消息
    //    //第二個(gè)參數(shù):回調(diào)方法珠移,當(dāng)我們監(jiān)聽的消息過來就會(huì)執(zhí)行該回調(diào)方法,如果帶參數(shù),參數(shù)類型是廣播
    //    //第三個(gè)參數(shù):具體廣播的名稱
    //    //第四個(gè)參數(shù):廣播內(nèi)容的標(biāo)記,如果賦值為nil末融,就是監(jiān)聽該廣播下所有的消息钧惧,如果是具體的值,那就只監(jiān)聽對(duì)應(yīng)標(biāo)記的消息
    NSNotificationCenter* notification=[NSNotificationCenter defaultCenter];
    [notification addObserver:self selector:@selector(palyerFinish:) name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
}

//實(shí)現(xiàn)廣播通知中心的回調(diào)方法
-(void)palyerFinish:(NSNotification*)notification{
    //廣播中可能帶的值  userInfo和object都是發(fā)廣播時(shí)賦的值
    NSLog(@"%@",notification.userInfo);
    NSLog(@"%@",notification.object);
    NSLog(@"視頻播放完成");
    
}

//KVO的回調(diào)方法
//第一個(gè)參數(shù):被觀察的屬性名
//第二個(gè)參數(shù):被觀察的對(duì)象
//第三個(gè)參數(shù):被觀察的屬性值的新值勾习、舊值都存在該字典中
//第四個(gè)參數(shù):上下文浓瞪,用來接收添加觀察者的時(shí)候context傳遞過來的值
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
    
    //從字典中獲取最新狀態(tài)下的值
    AVPlayerItemStatus newStatus=[change[NSKeyValueChangeNewKey] intValue];
    switch (newStatus) {
        case AVPlayerItemStatusFailed:
            NSLog(@"資源有誤,無法播放");
            break;
        case AVPlayerItemStatusUnknown:
            NSLog(@"資源未知錯(cuò)誤");
            break;
        case AVPlayerItemStatusReadyToPlay:
            [self.player play];
             self.isPlaying=YES;
            //播放單元獲取的duration是一個(gè)CMTime類型的結(jié)構(gòu)體  CMTime是一個(gè)表示視頻的時(shí)間單位
            //value:視頻的總幀數(shù)
            //timescale:幀/秒  該視頻的播放速率  每秒多少幀
            if (self.playerItem.duration.timescale) {
               self.progressSlider.maximumValue= self.playerItem.duration.value *1.0/self.playerItem.duration.timescale;
            }
           
            NSLog(@"資源已準(zhǔn)備完成,可以播放");
            break;
        default:
            break;
    }
    
    
}
//調(diào)整音量
- (IBAction)volumAction:(UISlider *)sender {
    self.player.volume=sender.value;
}

//調(diào)整進(jìn)度
- (IBAction)progressAction:(UISlider *)sender {
    [self.player pause];
    //將視頻從指定位置開始播放
    //第一個(gè)參數(shù):從哪個(gè)位置開始播放
    //第二個(gè)參數(shù):調(diào)整完成之后要進(jìn)行的操作
    [self.player seekToTime:CMTimeMakeWithSeconds(sender.value, self.playerItem.currentTime.timescale) completionHandler:^(BOOL finished) {
        if (finished) {
             NSLog(@"視頻已播放完成巧婶,請(qǐng)結(jié)束觀看");
            [self.player play];
        }
       
    }];
    
}

//上一個(gè)
- (IBAction)preAction:(UIButton *)sender {
    NSInteger index=self.currentIndex-1;
    [self changeSourceWithIndex:index];
    [self.playOrpause setTitle:@"暫停" forState:UIControlStateNormal];
}

//播放暫停
- (IBAction)playAction:(UIButton *)sender {
    if (self.isPlaying) {
        [self.player pause];
        self.isPlaying=NO;
        [sender setTitle:@"播放" forState:(UIControlStateNormal)];
    }else{
        [self.player play];
        self.isPlaying=YES;
        [sender setTitle:@"暫停" forState:(UIControlStateNormal)];
    }
    
}

//下一個(gè)
- (IBAction)nextAction:(UIButton *)sender {
    NSInteger index=self.currentIndex+1;
    [self changeSourceWithIndex:index];
    [self.playOrpause setTitle:@"暫停" forState:UIControlStateNormal];
}

//切換資源的方法
-(void)changeSourceWithIndex:(NSInteger)index{
    [self.player pause];
    if (index<0) {
        //在播放最后一首的時(shí)候點(diǎn)擊了上一曲
        [self playerMethodWithSourcePath:self.allSourcesMArray.lastObject];
        self.currentIndex=self.allSourcesMArray.count-1;
    }else if (index==self.allSourcesMArray.count){
        //在播放最后一首的時(shí)候乾颁,點(diǎn)擊了下一曲
        [self playerMethodWithSourcePath:self.allSourcesMArray[0]];
        self.currentIndex=0;
    }else{
        //在中間涂乌,既不是第一,也不是最后
        [self playerMethodWithSourcePath:self.allSourcesMArray[index]];
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];
    self.isPlaying=NO;
    self.currentIndex=0;
//    [self avPlayer];
    [self playerMethodWithSourcePath:self.allSourcesMArray[0]];
    //通知中心發(fā)送廣播
    [[NSNotificationCenter defaultCenter] postNotificationName:@"test" object:@"這里是FM99.9,我是余菲英岭,我在陜西等您" userInfo:@{@"name":@"余菲"}];
    
  }

這樣一個(gè)簡單的視頻播放器就完成了湾盒,????????
其實(shí)思路和音樂播放器差不多

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市诅妹,隨后出現(xiàn)的幾起案子罚勾,更是在濱河造成了極大的恐慌,老刑警劉巖吭狡,帶你破解...
    沈念sama閱讀 212,080評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件尖殃,死亡現(xiàn)場離奇詭異,居然都是意外死亡赵刑,警方通過查閱死者的電腦和手機(jī)分衫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來般此,“玉大人蚪战,你說我怎么就攤上這事☆戆茫” “怎么了邀桑?”我有些...
    開封第一講書人閱讀 157,630評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長科乎。 經(jīng)常有香客問我壁畸,道長,這世上最難降的妖魔是什么茅茂? 我笑而不...
    開封第一講書人閱讀 56,554評(píng)論 1 284
  • 正文 為了忘掉前任捏萍,我火速辦了婚禮,結(jié)果婚禮上空闲,老公的妹妹穿的比我還像新娘令杈。我一直安慰自己,他們只是感情好碴倾,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評(píng)論 6 386
  • 文/花漫 我一把揭開白布逗噩。 她就那樣靜靜地躺著,像睡著了一般跌榔。 火紅的嫁衣襯著肌膚如雪异雁。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,856評(píng)論 1 290
  • 那天僧须,我揣著相機(jī)與錄音纲刀,去河邊找鬼。 笑死担平,一個(gè)胖子當(dāng)著我的面吹牛示绊,可吹牛的內(nèi)容都是我干的芥挣。 我是一名探鬼主播,決...
    沈念sama閱讀 39,014評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼耻台,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了空另?” 一聲冷哼從身側(cè)響起盆耽,我...
    開封第一講書人閱讀 37,752評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎扼菠,沒想到半個(gè)月后摄杂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,212評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡循榆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評(píng)論 2 327
  • 正文 我和宋清朗相戀三年析恢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秧饮。...
    茶點(diǎn)故事閱讀 38,687評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡映挂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出盗尸,到底是詐尸還是另有隱情柑船,我是刑警寧澤,帶...
    沈念sama閱讀 34,347評(píng)論 4 331
  • 正文 年R本政府宣布泼各,位于F島的核電站鞍时,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏扣蜻。R本人自食惡果不足惜逆巍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評(píng)論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望莽使。 院中可真熱鬧锐极,春花似錦、人聲如沸吮旅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽庇勃。三九已至檬嘀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間责嚷,已是汗流浹背鸳兽。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評(píng)論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留罕拂,地道東北人揍异。 一個(gè)月前我還...
    沈念sama閱讀 46,406評(píng)論 2 360
  • 正文 我出身青樓全陨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親衷掷。 傳聞我的和親對(duì)象是個(gè)殘疾皇子辱姨,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容