FOUNDATION_EXPORT and export
26 Dec 2015Jusr for more compatible
in C: FOUNDATION_EXPORT = extern
in C++: FOUNDATION_EXPORT = extern "C"
ref: NSObjCRuntime.h
Jusr for more compatible
in C: FOUNDATION_EXPORT = extern
in C++: FOUNDATION_EXPORT = extern "C"
ref: NSObjCRuntime.h
- (IBAction)recordVideo:(UIButton *)sender {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
self.camera = [[UIImagePickerController alloc] init];
self.camera.sourceType = UIImagePickerControllerSourceTypeCamera;
self.camera.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeMovie, nil];
self.camera.showsCameraControls = YES;
self.camera.delegate = self;
[self presentViewController:self.camera animated:YES completion:nil];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"No camera avaiable" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
}
}
#pragma mark UIImagePickerController delegate
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary<NSString *,id> *)info {
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
[self dismissViewControllerAnimated:YES completion:nil];
if (CFStringCompare((CFStringRef)mediaType, kUTTypeMovie, 0) == kCFCompareEqualTo) {
NSString *moviePath = (NSString *)[[info objectForKey:UIImagePickerControllerMediaURL] path];
if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(moviePath)) {
UISaveVideoAtPathToSavedPhotosAlbum(moviePath, self, @selector(video:didFinishSavingWithError:contextInfo:), nil);
}
}
}
- (void)video: (NSString *)videoPath didFinishSavingWithError: (NSError *)error contextInfo: (void *)contextInfo {
if (error) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Video Saving Failed" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
} else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Video Saved" message:@"Saved to your Photo Alblum" delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
}
}
- (NSURL *)soundFileURL {
NSArray *dirPaths;
NSString *docsDir;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
NSString *soundFilePath = [docsDir stringByAppendingPathComponent:@"record.m4a"];
return [NSURL fileURLWithPath:soundFilePath];
}
- (IBAction)startRecording:(UIButton *)sender {
[self.recordButton setHidden:YES];
[self.stopButton setHidden:NO];
[self.playButton setHidden:YES];
NSError *error = nil;
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryRecord error:nil];
[session setActive:YES error:&error];
if (error) {
NSLog(@"AVAudioSession Error: %@", [error localizedDescription]);
}
NSMutableDictionary *recordSetting = [[NSMutableDictionary alloc] init];
[recordSetting setValue:[NSNumber numberWithInt:kAudioFormatMPEG4AAC] forKey:AVFormatIDKey];
[recordSetting setValue:[NSNumber numberWithFloat:44100.0] forKey:AVSampleRateKey];
[recordSetting setValue:[NSNumber numberWithInt:2] forKey:AVNumberOfChannelsKey];
[recordSetting setValue:[NSNumber numberWithInt:16] forKey:AVLinearPCMBitDepthKey];
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsBigEndianKey];
[recordSetting setValue:[NSNumber numberWithBool:NO] forKey:AVLinearPCMIsFloatKey];
self.audioRecoder = [[AVAudioRecorder alloc] initWithURL:[self soundFileURL] settings:recordSetting error:&error];
self.audioRecoder.delegate = self;
if (error) {
NSLog(@"error: %@", [error localizedDescription]);
} else {
[self.audioRecoder prepareToRecord];
}
if (!self.audioRecoder.recording) {
self.recordButton.enabled = NO;
self.stopButton.enabled = YES;
[self.audioRecoder record];
}
}
- (IBAction)startPlaying:(UIButton *)sender {
NSLog(@"Start playing ... ...");
NSError *error = nil;
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryPlayback error:nil];
[session setActive:YES error:&error];
if (error) {
NSLog(@"AVAudioSession Error: %@", [error localizedDescription]);
}
[self.playButton setUserInteractionEnabled:NO];
NSURL *url = [self soundFileURL];
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:&error];
if (error) {
NSLog(@"Error in audioPlayer: %@", [error localizedDescription]);
} else {
self.audioPlayer.delegate = self;
[self.audioPlayer prepareToPlay];
[self.audioPlayer play];
}
}
这会停止其他应用的声音(比如iPod)并让你的应用也不能初始化音频回放(比如AVAudioPlayer)。在这种模式下,你只能进行录音。使用这个类别,调用AVAudioPlayer的prepareToPlay会返回YES,但是调用play方法将返回NO。主UI界面会照常工作。这时,即使你的设备屏幕被用户锁定了,应用的录音仍会继续。
这个类别会静止其他应用的音频回放(比如iPod应用的音频回放)。你可以使用AVAudioPlayer的prepareToPlay和play方法,在你的应用中播放声音。主UI界面会照常工作。这时,即使屏幕被锁定或者设备为静音模式,音频回放都会继续。
这个类别允许你的应用中同时进行声音的播放和录制。当你的声音录制或播放开始后,其他应用的声音播放将会停止。主UI界面会照常工作。这时,即使屏幕被锁定或者设备为静音模式,音频回放和录制都会继续。
这个类别用于应用中进行音频处理的情形,而不是音频回放或录制。设置了这种模式,你在应用中就不能播放和录制任何声音。调用AVAPlayer的prepareToPlay和play方法都将返回NO。其他应用的音频回放,比如iPod,也会在此模式下停止。
这个类别不会停止其他应用的声音,相反,它允许你的音频播放于其他应用的声音之上,比如iPod。你的应用的主UI线程会工作正常。调用AVAPlayer的prepareToPlay和play方法都将返回YES。当用户锁屏时,你的应用将停止所有正在回放的音频。仅当你的应用是唯一播放该音频文件的应用时,静音模式将停止你程序的音频回放。如果正当iPod播放一手歌时,你开始播放音频,将设备设为静音模式并不能停止你的音频回放。
@interface MusicViewController () <UITableViewDataSource, UITableViewDelegate>
@end
@implementation MusicViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.musicPlayer = [MPMusicPlayerController applicationMusicPlayer];
[self loadMedia];
[self.mTableView setDataSource:self];
[self.mTableView setDelegate:self];
}
- (void)loadMedia {
// query all songs
MPMediaQuery *allSongQuery = [[MPMediaQuery alloc] init];
NSLog(@"All Songs: %@ :", [allSongQuery items]);
self.allItems = [[NSMutableArray alloc] initWithArray:[allSongQuery items]];
[self dumpSongs];
[self.mTableView reloadData];
}
- (void)dumpSongs {
if (self.allItems != nil && [self.allItems count] > 0) {
NSLog(@"There are(is) %lu song(s)", (unsigned long)[self.allItems count]);
for (int i = 0; i < [self.allItems count]; i++) {
MPMediaItem *item = [self.allItems objectAtIndex:i];
NSNumber *persistentID = [item valueForProperty:MPMediaItemPropertyArtistPersistentID];
NSLog(@"PersistentID: %@", persistentID);
}
}
}
#pragma mark TableView Delegate
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.allItems count];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self.musicPlayer stop];
[self.musicPlayer setQueueWithItemCollection:nil];
MPMediaItem *item = [[self.allItems objectAtIndex:[indexPath row]] representativeItem];
MPMediaPropertyPredicate *myPredicate = [MPMediaPropertyPredicate predicateWithValue:[item valueForProperty:MPMediaItemPropertyAlbumPersistentID] forProperty:MPMediaItemPropertyAlbumPersistentID comparisonType:MPMediaPredicateComparisonContains];
MPMediaQuery *songsQuery = [MPMediaQuery songsQuery];
[songsQuery addFilterPredicate:myPredicate];
// setQuery direct to Queue
[self.musicPlayer setQueueWithQuery:songsQuery];
[self.musicPlayer prepareToPlay];
[self.musicPlayer play];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *cellIndentifier = @"MyCellIndentifer";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIndentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIndentifier];
}
MPMediaItem *item = [[self.allItems objectAtIndex:indexPath.row] representativeItem];
MPMediaItemArtwork *artwork = [item valueForProperty:MPMediaItemPropertyArtwork];
if (artwork) {
cell.imageView.image = [artwork imageWithSize:CGSizeMake(30, 30)];
}
cell.textLabel.text = [item valueForProperty:MPMediaItemPropertyTitle];
return cell;
}
@end