12.1 播放視頻
12.2 播放音頻
12.3 播放和錄制音頻
12.1 播放視頻
視頻文件介紹
視頻格式可以分為適合本地播放的本地影像視頻和適合在網絡中播放的網絡流媒體影像視頻兩大類。盡管后者在播放的穩定性和播放畫面質量上可能沒有前者優秀,但網絡流媒體影像視頻的廣泛傳播性使之正被廣泛應用於視頻點播、網絡演示、遠程教育、網絡視頻廣告等等互聯網信息服務領域。
適合移動設備的視頻文件
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填充兩邊可能會改變比例
播放完成
- (void) playingDone { NSLog(@"播放完成"); [moviePlayerView.view removeFromSuperview]; [moviePlayerView release]; 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
播放“短聲音”
播放“短聲音”主要就是兩個步驟:
注冊聲音
AudioServicesCreateSystemSoundID ((CFURLRef)fileURL, &myID);
播放聲音
AudioServicesPlaySystemSound (myID);
監聽完成事件方法
AudioServicesAddSystemSoundCompletion
清除播放sound ID
SystemSoundID myID;
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]; }
注:
1 本教程是基於關東升老師的教程
2 基於黑蘋果10.6.8和xcode4.2
3 本人初學,有什么不對的望指教
4 教程會隨着本人學習,持續更新
5 教程是本人從word筆記中拷貝出來了,所以格式請見諒