iOS开发之多媒体API (转载)

视频格式可以分为适合本地播放的本地影像视频和适合在网络中播放的网络流媒体影像视频两大类。尽管后者在播放的稳定性和播放画面质量上可能没有前者 优秀,但网络流媒体影像视频的广泛传播性使之正被广泛应用于视频点播、网络演示、远程教育、网络视频广告等等互联网信息服务领域。

AD:WOT2015 互联网运维与开发者大会 热销抢票

播放视频

视频文件介绍

视频格式可以分为适合本地播放的本地影像视频和适合在网络中播放的网络流媒体影像视频两大类。尽管后者在播放的稳定性和播放画面质量上可能没有前者 优秀,但网络流媒体影像视频的广泛传播性使之正被广泛应用于视频点播、网络演示、远程教育、网络视频广告等等互联网信息服务领域。

适合移动设备的视频文件

3GP,3GP是一种3G流媒体的视频编码格式,主要是为了配合3G网络的高传输速度而开发的,也是目前手机中最为常见的一种视频格式。 视频MP4格式,除了支持MP3所具有的音乐播放功能外,还具备强大的MPEG-4视频播放能力。

iPhone中还支持mov格式文件。

iOS播放视频 

iOS sdk为播放视频提供了非常简便方法,提供的MPMoviePlayerViewController类作为开发使用,在iOS4以前的版本是MPMoviePlayerController。

在iPhone开发规范中禁止使用私有API播放视频,因此播放画面的控制的控件都是有iPhone提供好的,我们没有别的选择。我们能做的:

加载URL中视频

播放、暂停视频

用户控制行为和缩放模式

产生通知

视频播放案例

添加 MediaPlayer.framework 

MoviePlayerViewController.h

#import <MediaPlayer/MediaPlayer.h> 
 
@interface MoviePlayerViewController : UIViewController { 
 
    MPMoviePlayerViewController * moviePlayerView; 
} 
 
@property (nonatomic, retain) MPMoviePlayerViewController * moviePlayerView; 
 
 
-(IBAction) playMovie: (id) sender; 
- (void) playingDone; 
 
@end 

m文件的加载和卸载方法

- (void) viewDidLoad {  
    [[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(playingDone) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];  
}  
- (void)dealloc {  
    [[NSNotificationCenter defaultCenter] removeObserver:self];  
    [moviePlayerView release];  
    [super dealloc];  
}  

MPMoviePlayerViewController提供了在播放过程中的状态改变和其它事件的通知。在viewDidLoad注册了一个播放完成的通知,常用的通知有:

MPMoviePlayerPlaybackDidFinishNotification通知接收者播放结束。

MPMoviePlayerScalingModeDidChangeNotification改变影片的尺寸。

MPMoviePlayerContentPreloadDidFinishNotification表示预处理以及完成,准备开始播放影片。

dealloc方法中的[[NSNotificationCenter defaultCenter]

removeObserver:self];影片播放完成要注销通知。

播放事件

- (IBAction) playMovie: (id) sender { 
 
    moviePlayerView = [[MPMoviePlayerViewController alloc]  
                   initWithContentURL:[NSURL fileURLWithPath:[[NSBundle mainBundle]  
                                pathForResource:@"short" ofType:@"3gp"]]]; 
 
    moviePlayerView.moviePlayer.controlStyle = MPMovieControlStyleFullscreen; 
    moviePlayerView.moviePlayer.scalingMode = MPMovieScalingModeAspectFit; 
 // MPMovieControlStyleNone 
 //MPMovieControlStyleEmbedded  
 //MPMovieControlStyleDefault 
 
 //[movieplayer play]; 
 //在当前view上添加视频的视图 
    [[[UIApplication sharedApplication] keyWindow] addSubview:moviePlayerView.view];     
 
} 

视频文件可以播放资源目录、沙箱目录和网络播放。本例中我们采用资源目录。

moviePlayerView.moviePlayer属性是MPMoviePlayerController类型,它有的controlStyle属性

可以控制播放行为,它的取值有:

MPMovieControlStyleFullscreen MPMovieControlStyleNone没有播放控件 MPMovieControlStyleEmbedded  MPMovieControlStyleDefault MPMoviePlayerController类还有scalingMode属性用于控制影片的尺寸,它的取值有: MPMovieScalingModeNone原始尺寸 MPMovieScalingModeAspectFit缩放到一个填充方向 MPMovieScalingModeAspectFill填充两边可能会切除一部分 MPMovieScalingModeFill填充两边可能会改变比例

播放完成

  1. - (void) playingDone { 
  2.     NSLog(@"播放完成"); 
  3.     [moviePlayerView.view removeFromSuperview]; 
  4.     [moviePlayerView release]; 
  5.     moviePlayerView = nil;     

playingDone 方法是在影片播放完成时候调用,这是因为我们在通知中心注册的方法。

播放完成需要把播放视图remove这样才可以获得上一个屏幕。

12.2 播放音频

12.2.1 音频文件介绍

有两类主要的音频文件格式: 

无损格式,例如WAV,PCM,TTA,FLAC,AU,APE,TAK,WavPack(WV) ,CAF

有损格式,例如MP3,Windows Media Audio(WMA),Ogg Vorbis(OGG),AAC 

移动音频文件

作为移动设备音频文件应该原则上比较小,一般的格式:

WAV、由于无损压缩效果最好。

MP3、有损压缩,文件比较小,由于去除的是人类无法感应到的声音,效果也很好。这是目前常用格式。

AAC、压缩比例更大,比MP3文件还要小。

CAF(Core Audio Format)是Apple专用的无损压缩格式。

12.2.2 Core Audio

高级API,易用

System Sound API –播放短声音、警告音等。

AVFoundation 可以播放长时间声音,简单易用。

低级API,能够对音频有更多的控制

Audio Toolbox – 录制、播放、音频流有全面的控制。

OpenAL – 播放立体声,常用于游戏。

12.2.3 System Sound API

System Sound 可以播放“短的”声音,所谓短声音就是5秒以内。 不循环、没有声音控制、立即播放。

播放格式限制:

线性PCM 和 IMA4

.caf .aif 或 .wav

播放“短声音”

播放“短声音”主要就是两个步骤:

注册声音

  1. AudioServicesCreateSystemSoundID ((CFURLRef)fileURL, &myID); 

播放声音

  1. AudioServicesPlaySystemSound (myID); 

监听完成事件方法

  1. AudioServicesAddSystemSoundCompletion 

清除播放sound ID

  1. SystemSoundID myID;  
  2.    AudioServicesDisposeSystemSoundID (myID);   

震动

也可以通过System Sound API让iPhone震动,但是iPod touch不能震动。

震动可以通过指定一个特殊的system sound ID—— kSystemSoundID_Vibrate实现。

AudioServicesPlaySystemSound (kSystemSoundID_Vibrate);

实例

SystemSoundServices

添加AudioToolbox.framework框架

SystemSoundServicesViewController.h文件

#import <UIKit/UIKit.h> 
#include <AudioToolbox/AudioToolbox.h> 
 
@interface SystemSoundServicesViewController : UIViewController; 
 
- (IBAction) playSystemSound; 
- (IBAction) vibrate; 
 
@end 

播放事件

- (IBAction) playSystemSound{ 
 
    NSURL* system_sound_url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"BeepGMC500" ofType:@"wav"]]; 
    SystemSoundID system_sound_id; 
 
    AudioServicesCreateSystemSoundID( 
        (CFURLRef)system_sound_url, 
        &system_sound_id 
    ); 
 
 // Register the sound completion callback. 
    AudioServicesAddSystemSoundCompletion( 
        system_sound_id, 
        NULL, // uses the main run loop 
        NULL, // uses kCFRunLoopDefaultMode 
        MySoundFinishedPlayingCallback, // the name of our custom callback function 
        NULL // for user data, but we don't need to do that in this case, so we just pass NULL 
    ); 
 
 // Play the System Sound 
    AudioServicesPlaySystemSound(system_sound_id); 
} 

AudioServicesAddSystemSoundCompletion方法5个参数,第一参数SystemSoundID,第二参数是是否使用循环,第三个参数是循环模式,第四个参数是回调函数,就是当播放完成时候回调的方法,第五个参数是为回调函数提供参数。

这里回调的方法是C语言风格的函数:MySoundFinishedPlayingCallback。

回调函数

void MySoundFinishedPlayingCallback(SystemSoundID sound_id, void* user_data){ 
    AudioServicesDisposeSystemSoundID(sound_id); 
} 

震动方法调用

// Vibrate on action 
- (IBAction) vibrate{ 
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate); 
} 

12.3 播放和录制音频

AVFoundation控件可以实现一般音频播放和录制。

AVAudioPlayer音频播放类,用于播放大于5秒钟声音,可以播放本地声音,但是不能播放网络媒体文件。能够播放、 暂停、循环和跳过等操作。

AVAudioRecorder音频录制类。

实例AVAudioPlayer

添加AVFoundation.framework框架

AvplayerViewController.h文件

#import <UIKit/UIKit.h> 
#import <AVFoundation/AVFoundation.h> 
 
@interface AvplayerViewController : UIViewController <AVAudioPlayerDelegate> { 
    AVAudioPlayer * player; 
 
} 
 
- (IBAction) stopSong: (id) sender; 
- (IBAction) playSong: (id) sender; 
 
 
@end 

AvplayerViewController.m

#import "AvplayerViewController.h" 
 
@implementation AvplayerViewController 
 
- (IBAction) playSong: (id) sender { 
    NSError *error = nil; 
    player = [[AVAudioPlayer alloc] initWithContentsOfURL:  
                 [NSURL fileURLWithPath:[[NSBundle mainBundle]  
                    pathForResource:@"charleston1925_64kb" ofType:@"mp3"]] error:&error]; 
    player.delegate = self; 
 if(error) { 
        NSLog(@"%@",[error description]);  
        [error release]; 
    } 
    [player play]; 
} 
 
- (IBAction) stopSong: (id) sender { 
    [player stop]; 
} 
 
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag { 
    NSLog(@"播放完成。");     
} 
 
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError *)error { 
    NSLog(@"播放错误发生: %@", [error localizedDescription]);     
} 
 
 
- (void)dealloc { 
    [player release]; 
    [super dealloc]; 
} 
 
@end 

AVAudioPlayer委托

AVAudioPlayerDelegate委托对象提供了两个主要方法:

audioPlayerDidFinishPlaying:successfully:

audioPlayerDecodeErrorDidOccur:error:

AVAudioRecorder

新建实例:Recorder

RecorderViewController.h文件

#import <UIKit/UIKit.h> 
#import <AVFoundation/AVFoundation.h> 
 
@interface RecorderViewController : UIViewController 
{ 
    AVAudioRecorder *recorder; 
    AVAudioPlayer *player; 
    UILabel *label; 
} 
@property (retain, nonatomic) AVAudioRecorder * recorder; 
@property (retain, nonatomic) AVAudioPlayer * player; 
@property (retain, nonatomic) IBOutlet UILabel *label; 
-(IBAction)recordPushed:(id)sender; 
-(IBAction)playPushed:(id)sender; 
-(IBAction)stopPushed:(id)sender; 
@end 

音频录制方法

-(IBAction)recordPushed:(id)sender  
{ 
    label.text = @"recode..."; 
 if([recorder isRecording]) 
 return; 
 
 if([player isPlaying]) 
        [player stop]; 
    NSError *error = nil; 
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord 
                                           error:&error]; 
    [[AVAudioSession sharedInstance] setActive:YES error:&error]; 

AVAudioSession 是iOS提供音频会话类,音频会话是指定应用程序与音频系统如何交互。AVAudioSession 通过指定一个音频类别(Category)实现的,音频类别(Category)描述了应用程序使用音频的方式。下面是语句是设定音频会话类别:

[[AVAudioSession sharedInstance]setCategory:AVAudioSessionCategoryRecord error:&error];

AVAudioSessionCategoryRecord代表只能输入音频,即录制音频了。其效果是停止其它音频播放。

使用类别后,音频会话要设置为“活跃的”Active,这会把后台的任何系统声音关闭。

[[AVAudioSession sharedInstance]  setActive:YES error:&error];   

音频录制方法

NSMutableDictionary *settings = [NSMutableDictionary dictionary]; 
    [settings setValue:[NSNumber numberWithInt:kAudioFormatLinearPCM]  
                forKey:AVFormatIDKey]; 
    [settings setValue:[NSNumber numberWithFloat:44100.0]  
                forKey:AVSampleRateKey]; //采样率 
    [settings setValue:[NSNumber numberWithInt:1]  
                forKey:AVNumberOfChannelsKey];//通道的数目 
    [settings setValue:[NSNumber numberWithInt:16]  
                forKey:AVLinearPCMBitDepthKey];//采样位数  默认 16 
    [settings setValue:[NSNumber numberWithBool:NO]  
                forKey:AVLinearPCMIsBigEndianKey];//大端还是小端 是内存的组织方式 
    [settings setValue:[NSNumber numberWithBool:NO]  
                forKey:AVLinearPCMIsFloatKey];//采样信号是整数还是浮点数 
 
    NSString *filePath =  
    [NSString stringWithFormat:@"%@/rec_audio.caf", [self documentsDirectory]]; 
    NSURL *fileUrl = [NSURL fileURLWithPath:filePath]; 
 
 //[self setRecorder:nil]; 
    recorder = [[AVAudioRecorder alloc]  
                                    initWithURL:fileUrl  
                                    settings:settings  
                                    error:&error]; 
 
 // [recorder setMeteringEnabled:YES]; 
    [recorder record]; 
} 
-(NSString *)documentsDirectory{     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,                                                           NSUserDomainMask, YES);      return [paths objectAtIndex:0]; }

音频播放方法

-(IBAction)playPushed:(id)sender{ 
    label.text = @"play..."; 
 
 if([recorder isRecording]) 
        [recorder stop]; 
 if([player isPlaying]) 
        [player stop]; 
 
    NSString *filePath =  
    [NSString stringWithFormat:@"%@/rec_audio.caf", [self documentsDirectory]]; 
    NSURL *fileUrl = [NSURL fileURLWithPath:filePath]; 
    NSError *error = nil; 
 // [self setPlayer:nil]; 
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback 
                                           error:&error]; 
    [[AVAudioSession sharedInstance] setActive:YES error:&error]; 
    player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileUrl error:&error]; 
 // [player setMeteringEnabled:YES]; 
    [player play]; 
} 

音频停止方法

-(IBAction)stopPushed:(id)sender{ 
    label.text = @"stop..."; 
 if([recorder isRecording]) 
        [recorder stop]; 
 if([player isPlaying]) 
        [player stop]; 
} 

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏腾讯Bugly的专栏

优化安卓应用内存的神秘方法以及背后的原理,一般人我不告诉他

安卓应用一般都害怕自己被杀,内存占用高是被杀的重要原因之一,所以大家都想尽各种招数应对,但效果都一般。 但有一招: WindowManagerGlobal.ge...

8416
来自专栏葡萄城控件技术团队

【.NET开发之美】使用ComponentOne提高.NET DataMap中的加载速度

所有内置网格编辑器都实现IC1EmbeddedEditor接口,ComponentOne Input库中的控件也是如此。 如果我们想要使用带有C1FlexGri...

1063
来自专栏Coding迪斯尼

使用物理引擎Box2D设计类愤怒小鸟的击球游戏--基本架构设置

2025
来自专栏iOS开发随笔

SCNView

在渲染过程过中,视图模型常常会出现锯齿边缘。这是因为模型是由多边形组成的,当显卡运算频率不够高,或者显存不够大的时候,“多边形”绘制速度比较慢,就会出现锯齿。此...

33613
来自专栏移动开发之家

Android 拍摄(横\竖屏)视频的懒人之路

请捂着你的良心说话,对于贫穷的作者(我)不是应该打赏么 ̄へ ̄!,接下来工作又要忙起来了,更新应该是放缓了呢╮(╯_╰)╭,好伤心。

3673
来自专栏Guangdong Qi

iOS开发常用之 图表

1401
来自专栏iOS122-移动混合开发研究院

如何把设计图自动转换为iOS代码? 在线等,挺急的!

这是一篇可能略显枯燥的技术深度讨论与实践文章.如何把设计图自动转换为对应的iOS代码?作为一个 iOS开发爱好者,这是我很感兴趣的一个话题.最近也确实有了些许灵...

2696
来自专栏Jerry的SAP技术分享

SAP成都研究院非典型程序猿,菜园子小哥:当我用UI5诊断工具时我用些什么

身边有些年轻同事曾经向我表达过这种困扰:尽管完成日常工作没有任何问题,但是还想更进一步,把代码写得更好些,做到精益求精。现在写的代码能实现功能,但是不知道可以怎...

1683
来自专栏编程

前端开发者常用的 9个JavaScript 图表库

英文: Anton Shaleynikov 译文:葡萄城控件 www.cnblogs.com/powertoolsteam/p/top-9-javascri...

3665
来自专栏老司机的简书

老司机带你走进Core Animation 之粒子发射、TileLayer与异步绘制

老司机带你走进Core Animation 之粒子发射、TileLayer与异步绘制

1142

扫码关注云+社区

领取腾讯云代金券