獲取音量
通過MPVolumeView的子視圖,私有方法獲取MPVolumeSlider,獲取音量。有風險,不推薦使用。
#import <MediaPlayer/MediaPlayer.h>
MPVolumeView *volumeView = [MPVolumeView new];
volumeView.showsRouteButton = NO;
volumeView.showsVolumeSlider = NO;
[self.view addSubview:volumeView];
__block UISlider *volumeViewSlider = nil;
[[volumeView subviews] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[UISlider class]]) {// 私有的方法 ,不推薦
volumeViewSlider = obj;
*stop = YES;
}
}];
CGFloat volume = volumeViewSlider.value;// 0, 不是當前音量
通過私用方法獲取到控制音量的slider,只需要監(jiān)聽它值的改變(valueChange)便可以監(jiān)聽到系統(tǒng)音量的改變,但是在MPVolumeView被創(chuàng)建的時候,其中的slider的值還是為0,需要過一會時間系統(tǒng)才會給slider賦值(不止會賦值一次),此時會調(diào)用valueChange,但是并不意味這系統(tǒng)音量的改變。同理,如果想獲取系統(tǒng)音量,用AVAudioSession.sharedInstance().outputVolume這個方法,直接讀slider的值可能會讀不準
監(jiān)聽方式 如下
KVO方式 待續(xù)、、、
#import <AVFoundation/AVFoundation.h>
- (void) someWhere {
// part 1.0 與 part 2.0 執(zhí)行順序無關(guān),可以寫在其他位置
// part 1.0
//監(jiān)聽系統(tǒng)聲音
AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory:AVAudioSessionCategoryAmbient error:nil];//重點方法
[session setActive:YES error:nil];
NSError *error;
[[AVAudioSession sharedInstance] setActive:YES error:&error];
//注,ios9上不加這一句會無效
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
// part 2.0
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(volumeChanged:) name:@"AVSystemController_SystemVolumeDidChangeNotification" object:nil];
}
- (void) volumeChanged:(NSNotification *)notification {
float volume = [[[notification userInfo] objectForKey:@"AVSystemController_AudioVolumeNotificationParameter"] floatValue];
ZHNSLog(@"自定義 音量 = %.5f", volume);
}
swift代碼如下
let volumeV = MPVolumeView(frame: CGRect(x: -3, y: -3, width: 1, height: 1))
for view in volumeV.subviews{
if view is UISlider{
self.volumeSlider = (view as! UISlider)
}
}
self.view.addSubview(volumeV)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.volumeChange(_:)) , name:Notification.Name(rawValue: "AVSystemController_SystemVolumeDidChangeNotification") , object: nil)
@objc func volumeChange(_ notification:NSNotification) {
let userInfo = notification.userInfo!
let volume = userInfo["AVSystemController_AudioVolumeNotificationParameter"] as! Double
}
}
設(shè)置音量
1-通過MPMusicPlayerController的volume可以設(shè)置音量,查看文檔該屬性ios(3.0, 7.0),使用時有??。在ios12.0+,13.0+測試可以使用,代碼設(shè)置音量有效
2-通過MPVolumeView的子視圖,私有方法獲取MPVolumeSlider,有風險,不推薦使用。在ios12.0+,13.0+測試無效。
#import <MediaPlayer/MediaPlayer.h>
- (void) settingDeviceVolume {
MPMusicPlayerController *musicPlayer = [MPMusicPlayerController applicationMusicPlayer];
// ios12.0+,13.0+測試可以使用,代碼設(shè)置音量有效
if ( [musicPlayer respondsToSelector:@selector(setVolume:)] ) {
//消除警告
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
[musicPlayer setVolume:0.34512];//MP_DEPRECATED("Use MPVolumeView for volume control.", ios(3.0, 7.0));
#pragma clang diagnostic pop
}
else {
MPVolumeView *volumeView = [MPVolumeView new];
volumeView.frame=CGRectMake(10,200, 200, 30);
volumeView.backgroundColor = [UIColor redColor];
volumeView.showsRouteButton = YES;
volumeView.showsVolumeSlider = YES;
[self.view addSubview:volumeView];
__block UISlider *volumeViewSlider = nil;
[[volumeView subviews] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[UISlider class]]) {// 私有的方法 ,不推薦
volumeViewSlider = obj;
*stop = YES;
}
// 或
if ([((UIView *)obj).class.description isEqualToString:@"MPVolumeSlider"]){
volumeViewSlider = (UISlider*)obj;
*stop = YES;
}
}];
volumeViewSlider.backgroundColor = [UIColor blueColor];
[volumeViewSlider setValue:0.27896 animated:YES];// ios12.0+,13.0+測試無效
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];
}
}