BreatheController.m 11.3 KB
//
//  BreatheController.m
//  DreamSleep
//
//  Created by peter on 2022/4/8.
//

#import "BreatheController.h"
#import "Track.h"
#import <Lottie.h>
#import <DOUAudioStreamer.h>
#import <AudioToolbox/AudioToolbox.h>

@interface BreatheController () <UIPickerViewDataSource, UIPickerViewDelegate>
// 旋转lottie
@property (nonatomic, strong) LOTAnimationView *rotateView;
// 缩放lottie
@property (nonatomic, strong) LOTAnimationView *zoomView;
@property (nonatomic, copy) NSString *rotateLottieFile;
@property (nonatomic, copy) NSString *zoomLottieFile;
// 分钟选择控件
@property (nonatomic, strong) UIPickerView *minutePickerView;
@property (nonatomic, strong) NSArray *minuteDatas;
@property (nonatomic, strong) UILabel *timeLb;
@property (nonatomic, strong) UILabel *minuteLb;
@property (nonatomic, strong) UIButton *startRelaxBtn;
@property (nonatomic, strong) UIButton *volumeBtn;
@property (nonatomic, strong) DOUAudioStreamer *audioStreamer;
@property (nonatomic, strong) NSTimer *controlTimer;
@property (nonatomic, assign) NSInteger minuteTime;
@property (nonatomic,assign) NSInteger playDuration;
@end

@implementation BreatheController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = DarkColor;
    
    self.minuteTime = 1;
    self.minuteDatas = @[@"1",@"2",@"3",@"4",@"5"];
    self.rotateLottieFile = self.style == LottieStyleBalance ? @"relax_normal_lottie.json" : @"478normal_lottie.json";
    self.zoomLottieFile = self.style == LottieStyleBalance ? @"relax_lottie.json" : @"478_lottie.json";
    self.audioFileURL = [NSURL URLWithString:@"https://img2.ydniu.com/audio/1641783843905_LhE13l.mp3"];
    
    [self initView];
}

- (void)viewDidDisappear:(BOOL)animated {
    [super viewDidDisappear:animated];
    [self cancelAudioStreamer];
}

- (void)dealloc {
    [[UIApplication sharedApplication] removeObserver:self forKeyPath:@"idleTimerDisabled"];
    [UIApplication sharedApplication].idleTimerDisabled = NO;
}

#pragma mark - 导航栏夜间模式
- (NaviStyle)navigationBarStyle {
    return NaviStyleDark;
}

#pragma mark - 关闭侧滑
- (BOOL)enableInteractivePopGestureRecognizer {
    return NO;
}

- (void)keepIdleTimerDisabled {
    [[UIApplication sharedApplication] setIdleTimerDisabled:YES];
    [[UIApplication sharedApplication] addObserver:self forKeyPath:@"idleTimerDisabled" options:NSKeyValueObservingOptionNew context:nil];
}

- (void)cancelAudioStreamer {
    [self.controlTimer invalidate];
    self.controlTimer = nil;
    
    if (self.audioStreamer) {
        [self.audioStreamer stop];
        [self.audioStreamer removeObserver:self forKeyPath:@"status" context:kStatusKVOKey1];
        self.audioStreamer = nil;
    }
}

- (void)initView {
    [self.view addSubview:self.rotateView];
    [self.view addSubview:self.zoomView];
    [self.view addSubview:self.minutePickerView];
    
    self.timeLb = [UILabel new];
    self.timeLb.text = @"放松时长";
    [self.view addSubview:self.timeLb];
    self.timeLb.textColor = [UIColor whiteColor];
    self.timeLb.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
    [self.timeLb sizeToFit];
    
    self.minuteLb = [UILabel new];
    self.minuteLb.text = @"分钟";
    [self.view addSubview:self.minuteLb];
    self.minuteLb.font = [UIFont systemFontOfSize:16 weight:UIFontWeightMedium];
    self.minuteLb.textColor = [UIColor whiteColor];
    [self.minuteLb sizeToFit];
    
    [self.view addSubview:self.startRelaxBtn];
    
    [self.rotateView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.width.height.equalTo(@162);
        make.centerX.equalTo(self.view);
        make.topMargin.equalTo(self.view).offset(100);
    }];
    [self.zoomView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.center.equalTo(self.view);
        make.leftMargin.equalTo(self.view).offset(90);
        make.rightMargin.equalTo(self.view).offset(-90);
        make.height.equalTo(@300);
    }];
    [self.minutePickerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.rotateView.mas_bottom).offset(30);
        make.left.equalTo(self.timeLb.mas_right);
        make.right.equalTo(self.minuteLb.mas_left);
        make.height.equalTo(@80);
    }];
    [self.timeLb mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.rotateView);
        make.centerY.equalTo(self.minutePickerView.mas_centerY);
    }];
    [self.minuteLb mas_makeConstraints:^(MASConstraintMaker *make) {
        make.right.equalTo(self.rotateView);
        make.centerY.equalTo(self.minutePickerView.mas_centerY);
    }];
    [self.startRelaxBtn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.minutePickerView.mas_bottom).offset(50);
        make.width.equalTo(@160);
        make.centerX.equalTo(self.zoomView.mas_centerX);
        make.height.equalTo(@40);
    }];
    
    // 设置关闭/开启声音按钮
    self.volumeBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44)];
    [self.volumeBtn setImage:[UIImage imageNamed:@"openMusic"] forState:UIControlStateNormal];
    [self.volumeBtn setImage:[UIImage imageNamed:@"closeMusic"] forState:UIControlStateSelected];
    [self.volumeBtn addTarget:self action:@selector(volumeControlAction:) forControlEvents:UIControlEventTouchUpInside];
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:self.volumeBtn];
    
    // 设置屏幕常亮
    [self keepIdleTimerDisabled];
}

#pragma mark - Action
- (void)startRelaxAction:(UIButton *)sender {
    sender.selected = !sender.selected;
    self.rotateView.hidden = YES;
    self.timeLb.hidden = YES;
    self.minuteLb.hidden = YES;
    self.startRelaxBtn.hidden = YES;
    self.minutePickerView.hidden = YES;
    [self.zoomView play];
    self.zoomView.hidden = NO;
    
    self.playDuration = self.minuteTime * 60;
    self.controlTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];
    [self.audioStreamer play];
}

- (void)timerAction:(NSTimer *)timer {
    self.playDuration--;
    DSLog(@"playDuration:%ld", self.playDuration);
    
    if (self.playDuration % 5 == 0 && self.playDuration >= 0) {
        AudioServicesPlaySystemSound(1520);
    }
    if (self.playDuration == 0) {
        self.zoomView.animationProgress = 0;
        self.zoomView.hidden = YES;
        self.rotateView.hidden = NO;
        self.timeLb.hidden = NO;
        self.minuteLb.hidden = NO;
        self.startRelaxBtn.hidden = NO;
        self.minutePickerView.hidden = NO;
        
        [self cancelAudioStreamer];
    }
}

- (void)volumeControlAction:(UIButton *)sender {
    sender.selected = !sender.selected;
    self.audioStreamer.volume = sender.selected ? 0 : 1;
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if (context == kStatusKVOKey1) {
        [self performSelector:@selector(updateStatus)
                     onThread:[NSThread mainThread]
                   withObject:nil
                waitUntilDone:NO];
    } else if (context == @"idleTimerDisabled") {
        if (![UIApplication sharedApplication].idleTimerDisabled) {
            [UIApplication sharedApplication].idleTimerDisabled = YES;
        }
    } else {
        // [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
    }
}

- (void)updateStatus {
    switch ([self.audioStreamer status]) {
        case DOUAudioStreamerPlaying:
            break;
        case DOUAudioStreamerPaused:
            [self.audioStreamer pause];
            // [self pauseTimer];
            break;
        case DOUAudioStreamerIdle:
            break;
        case DOUAudioStreamerFinished:
            DSLog(@"DOUAudioStreamerFinished");
            [self.audioStreamer play];
            break;
        case DOUAudioStreamerBuffering:
            break;
        case DOUAudioStreamerError:
            break;
    }
}

#pragma mark - UIPickerViewDataSource && UIPickerViewDelegate
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView*)pickerView{
    return 1;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
    return self.minuteDatas.count;
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
    self.minuteTime = [[self.minuteDatas objectAtIndex:row] integerValue];
}

- (CGFloat)pickerView:(UIPickerView *)pickerView rowHeightForComponent:(NSInteger)component {
    return 35;
}

- (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component {
    return 70;
}

- (NSAttributedString *)pickerView:(UIPickerView *)pickerView attributedTitleForRow:(NSInteger)row forComponent:(NSInteger)component {
    NSString *titleString = [self.minuteDatas objectAtIndex:row];
    NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:titleString];
    NSRange range = [titleString rangeOfString:titleString];
    [attributedString addAttribute:NSForegroundColorAttributeName value:BrandColor range:range];
    [attributedString addAttribute:NSFontAttributeName value:[UIFont systemFontOfSize:18] range:range];
    if (@available(iOS 14.0, *)) {
        pickerView.subviews[1].backgroundColor = DSClearColor;
    }
    return attributedString;
}

- (LOTAnimationView *)rotateView {
    if(!_rotateView) {
        _rotateView = [LOTAnimationView animationNamed:self.rotateLottieFile];
        _rotateView.contentMode = UIViewContentModeScaleAspectFit;
        _rotateView.loopAnimation = YES;
        [_rotateView playWithCompletion:^(BOOL animationFinished) {
            DSLog(@"rotateView...");
        }];
        _rotateView.hidden = NO;
    }
    return _rotateView;
}

- (LOTAnimationView *)zoomView {
    if(!_zoomView) {
        _zoomView = [LOTAnimationView animationNamed:self.zoomLottieFile];
        _zoomView.contentMode = UIViewContentModeScaleAspectFit;
        _zoomView.loopAnimation = YES;
        _zoomView.hidden = YES;
        [_zoomView playWithCompletion:^(BOOL animationFinished) {
            DSLog(@"zoomView...");
        }];
    }
    return _zoomView;
}

- (UIPickerView *)minutePickerView {
    if (!_minutePickerView) {
        _minutePickerView = [UIPickerView new];
        _minutePickerView.delegate = self;
        _minutePickerView.dataSource = self;
    }
    return _minutePickerView;
}

- (UIButton *)startRelaxBtn {
    if (!_startRelaxBtn) {
        _startRelaxBtn = [UIButton new];
        _startRelaxBtn.layer.cornerRadius = 20;
        _startRelaxBtn.layer.masksToBounds = YES;
        [_startRelaxBtn addTarget:self action:@selector(startRelaxAction:) forControlEvents:UIControlEventTouchUpInside];
        _startRelaxBtn.titleLabel.font = [UIFont systemFontOfSize:16];
        _startRelaxBtn.backgroundColor = BrandColor;
        [_startRelaxBtn setTitle:@"开始放松" forState:UIControlStateNormal];
    }
    return _startRelaxBtn;
}

static void *kStatusKVOKey1 = &kStatusKVOKey1;
- (DOUAudioStreamer *)audioStreamer {
    if (!_audioStreamer) {
        Track *track = [[Track alloc] init];
        track.audioFileURL = self.audioFileURL;
        _audioStreamer = [DOUAudioStreamer streamerWithAudioFile:track];
        _audioStreamer.volume = 1;
        [_audioStreamer addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:kStatusKVOKey1];
    }
    return _audioStreamer;
}

@end