【原】iOS学习45之多媒体操作

1. 音频

 1> 音频实现简述

  iOS 里面共有四种专门实现播放音频的方式:

  •  System Sound Services(系统声音服务)

  •  OpenAL(跨平台的开源的音频处理接口)

  •  Audio Queue Services(播放和录制音频服务)

  •  AVAudioPlayer(高级音频播放器)

 2> System Sound Services(系统声音服务)

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

  ② 局限性:

   1.  声音长度要小于30秒

   2.  格式:IMA4

   3.  不能控制播放的进度

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

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

  ③ 实例代码

    CFBundleRef mainBundle;

    SystemSoundID soundFileObject;

    mainBundle = CFBundleGetMainBundle ();

    CFURLRef soundFileURLRef  = CFBundleCopyResourceURL (mainBundle, CFSTR ("蔡琴 - 爱断情伤"), CFSTR ("wav"), NULL);

    AudioServicesCreateSystemSoundID (soundFileURLRef, &soundFileObject);

    AudioServicesPlaySystemSound(soundFileObject);

 3> OpenAL

  ① 简介

   OpenAL 是一套跨平台开源音频处理接口

   最适合开发游戏的音频

   OpenAL 包含三个 实体:Listener(听者)Source(音源)、 Buffer(缓存)

   Audio Queue Services 主要用来实现录制音频,为了简化音频文件的处理,通常还需要使用到 AudioFileServices

  ② 开发步骤

   1.获取device

   2.将context关联到device

   3.将数据放入buffer

   4.将buffer链接到一个source

   5.播放source

  OpenAL资料网址: http://www.devdiv.com/thread-19636-1-1.html
            http://www.cocoachina.com/bbs/read.php?tid-112679-page-1.html

  相对底层的 API参考:http://blog.csdn.net/midfar/article/details/7233454

 4> AVAudioPlayer简介

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

  • AAC

  • AMR(AdaptiveMulti-Rate, aformatforspeech)

  • ALAC(AppleLossless)

  • iLBC(internetLowBitrateCodec, anotherformatforspeech)

  • IMA4(IMA/ADPCM)

  • linearPCM(uncompressed)

  • MP3(MPEG-1audiolayer3)

 5> AVAudioPlayer优势

  • 支持更多的格式

  • 可以播放任意长度的音频文件

  • 支持循环播放

  • 可以同步播放多个音频文件

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

 6> AVAudioPlayer开发步骤

  • 步骤一:AVAudioPlayer 包含在 AVFoundation 框架中,所以开发的时候首先导入音频的框架 AVFoundation.framework

  引入头文件

#import <AVFoundation/AVFoundation.h>
  • 步骤二: AVAudioPlayer 的初始化的时候需要给一个播放文件

  AVAudioPlayer  *avAudioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:文件路径 error:nil];

  • 步骤三:重要属性

  设置初始音量大小 audioPlayer.volume = 1;(0.0 ~ 1.0)

  设置音乐播放次数  audioPlayer.numberOfLoops = -1;(只要是负数都是循环播放)

  播放进度 audioPlayer.currentTime = 0;

  • 步骤四:重要方法

  预播放

[audioPlayer prepareToPlay];

  播放

[audioPlayer play];

  暂停

[audioPlayer pause];

  停止

[audioPlayer stop];
  • 步骤五:代理方法

  协议:AVAudioPlayerDelegate

   播放完成会调用的代理方法

    - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;

   播放解码失败

    - (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error;

  7> 简单代码实例:

// 懒加载
- (AVAudioPlayer *)player
{
    if (_player == nil) {
        
        NSString *urlString = [[NSBundle mainBundle] pathForResource:@"南征北战 - 骄傲的少年" ofType:@"mp3"];
        
        NSURL *url = [NSURL fileURLWithPath:urlString];
        
        _player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
        
        _player.delegate = self;
        
        // 设置默认的音量
        _player.volume = 0.5;
    }
    return _player;
}

// 播放按钮响应事件
- (IBAction)play:(id)sender
{
    [self.player play];
}

// 暂停按钮响应事件
- (IBAction)pause:(id)sender
{
    [self.player pause];
}

// 停止按钮响应事件
- (IBAction)stop:(id)sender
{
    [self.player stop];
}

// 音量滑竿响应事件
- (IBAction)changeVolume:(UISlider *)sender
{
    self.player.volume = sender.value;
}

   在我的github上有一个较完善的练习代码,有兴趣的小伙伴可以看看!

 8> 音频的后台播放

  • 首先要修改配置文件,在 Info.plist 文件中,添加 UIBackGroundModes ,可以添加包括 Audio 在后台播放音频和视频里的声音,location 保持当前用户的位置信息, voip 使用网络电话。添加以上字段是为了通知系统框架,在应用程序进入后台时候请求在后台继续播放一段时间,具体播放多久,根据 UIBackGroundTask 去申请一段时间。还可以使用本地通知,预先设定 local notification 来让应用程序在后台运行。

  • 后台播放音频设置   
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setActive:YES error:nil];
    [session setCategory:AVAudioSessionCategoryPlayback error:nil];
  • 让app支持接受远程控制事件  
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; 

2. 视频

 1> AVPlayer

  iOS 里面视频播放用到的是 AVPlayer(包含在AVFoundation框架内)与 AVAudioPlayer 有点类似,但是 AVPlayer 的功能更加强大,它可以用来播放音频也可以用来播放视频。而且在播放音频方面 AVPlayer 可以直接播放网络音频

 2> 视频播放实现步骤

  • 步骤一:导入支持视频播放的框架AVFoundation.framework

  引入头文件代码

#import <AVFoundation/AVFoundation.h>
  • 步骤二:获取播放的地址
 NSString *playString = @"http://static.tripbe.com/videofiles/20121214/9533522808.f4v.mp4";

 // 播放地址
 NSURL *playURL = [NSURL URLWithString:playString];
  • 步骤三:根据播放的 URL 创建 AVPlayerItem 对象

   AVPlayerItem 可以获取视频的信息,当前播放时间,总时间等

AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:playURL];

  AVPlayerItem重要属性

   状态 status

    AVPlayerStatusUnknown,(代表视频播放出现了未知的问题)

    AVPlayerStatusReadyToPlay,(代表视频可以播放,可以调用 play方法)

    AVPlayerStatusFailed(代表视频无法进行播放了)

   loadedTimeRange:代表已经缓存的进度,监听此属性可以在 UI 中更新缓存进度,也是很有用的一个属性

  • 步骤四:根据 AVPlayerItem 初始化 AVPlayer 对象
@interface ViewController ()
    @property(nonatomic, strong)AVPlayer *player;
@end 

self.player = [[AVPlayer alloc] initWithPlayerItem:item];
  • 步骤五:把 AVPlayerLayer 添加到需要播放页面的 Layer
    // 设置播放页面
    AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:_player];
    // 设置播放页面的大小
    layer.frame = CGRectMake(0, 100, [UIScreen mainScreen].bounds.size.width, 300);
    // 设置背景颜色
    layer.backgroundColor = [UIColor cyanColor].CGColor;
    // 设置播放窗口和当前视图之间的比例显示内容
    layer.videoGravity = AVLayerVideoGravityResizeAspect;
    // 添加播放视图到view上
    [self.view.layer addSublayer:layer];
  • 步骤六:AVPlayerLayer 播放
// 播放 
[self.player play];
  • 步骤七:在指定的时间播放
[self.player seekToTime:CMTimeMakeWithSeconds(progress,
//设置每秒钟多少帧
self.player.currentTime.timescale) completionHandler:^(BOOL finished) {

       }];

 // 设置音量
 self.player.volume = 1.0f;
    // 当前播放时间
 self.player.currentTime
  • 步骤八:播放完成的通知
//当播放完成时,可以注册通知,根据需求,做出不同的响应
AVPlayerItemDidPlayToEndTimeNotification

   可以通过设置观察者来完成添加播放完成通知

-(void)addNotification{
    //给AVPlayerItem添加播放完成通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:)name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
}

-(void)playbackFinished:(NSNotification *)notification{
    NSLog(@"视频播放完成.");
}

 通过以上的六个步骤已经可以实现视频在 iOS 客户端的播放;

 AVPlayerltem 资源管理对象,作用是:切换视频播放,使用时切换不同的 Item 即可. 而非创建新的 AVPlayer.

 AVPlayerItem 的一些重要属性可以使我们定制视频的开发

实例代码:

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSString *playString = @"http://static.tripbe.com/videofiles/20121214/9533522808.f4v.mp4";
    NSURL *url = [NSURL URLWithString:playString];
    // 本地视频
//    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"1457622279563.mp4" ofType:nil]];
    
    // 设置播放的项目
    AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:url];
    
    // 初始化player对象
    self.player = [[AVPlayer alloc] initWithPlayerItem:item];
    
    // 设置播放页面
    AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:_player];
    // 设置播放页面的大小
    layer.frame = CGRectMake(0, 100, [UIScreen mainScreen].bounds.size.width, 300);
    // 设置背景颜色
    layer.backgroundColor = [UIColor cyanColor].CGColor;
    // 设置播放窗口和当前视图之间的比例显示内容
    layer.videoGravity = AVLayerVideoGravityResizeAspect;
    // 添加播放视图到view上
    [self.view.layer addSublayer:layer];
    
    // 设置播放进度的默认值
    self.progressSlider.value = 0;
    // 设置播放音量的默认值
    self.player.volume = 1.0f;
    
    [self addNotification];
}

#pragma mark - 开始播放按钮的响应方法
- (IBAction)startPlayer:(UIButton *)sender
{
    [self.player play];
}
#pragma mark - 暂停播放按钮的响应方法
- (IBAction)puasePlayer:(UIButton *)sender
{
    [self.player pause];
}
#pragma mark - 改变进度按钮的响应方法
- (IBAction)changeProgress:(UISlider *)sender
{
    self.sumPlayOperation = _player.currentItem.duration.value / _player.currentItem.duration.timescale;

// CMTimeMake(a, b) a表示当前时间,b表示每秒钟有多少帧
    [_player seekToTime:CMTimeMakeWithSeconds(sender.value * self.sumPlayOperation, _player.currentTime.timescale) completionHandler:^(BOOL finished) {
        [self.player play];
    }];
}

- (void)addNotification{
    //给AVPlayerItem添加播放完成通知
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:)name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
}

- (void)playbackFinished:(NSNotification *)notification{
    NSLog(@"视频播放完成.");
}

 

posted @ 2016-05-27 18:59  墨隐于非  阅读(376)  评论(0编辑  收藏  举报