iOS音频播放-后台

ViewController.m
复制代码
//
//  AVPlayerViewController.m
//  AVAudioDemo
//
//  Created by pconline on 2017/8/23.
//  Copyright © 2017年 pconline. All rights reserved.
//

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>
#import "LGFAFNetworkingTool.h"

@interface ViewController ()<UITableViewDelegate,UITableViewDataSource>

@property(nonatomic,strong) AVPlayer *player;
@property(nonatomic,strong) UILabel *starTimeLabel;
@property(nonatomic,strong) UILabel *stateLabel;
@property(nonatomic,strong) UILabel *payCountLabel;
@property(nonatomic,strong) UITableView *payListTB;
@property(nonatomic,strong) NSMutableArray *payDataArr;

@property(nonatomic,strong)NSTimer*weakTimer;
@property(nonatomic,assign) int playCount;
@property(nonatomic,assign) int payCount;

@end

@implementation ViewController

- (void)viewDidLoad {
    
    [super viewDidLoad];
    NSArray* localDataArr = [[NSUserDefaults standardUserDefaults] objectForKey:@"localPayDataDicts"];
     [self.payDataArr removeAllObjects];
     if(localDataArr.count>0){
         [self.payDataArr addObjectsFromArray:localDataArr];
     }
    [self setUpView];
    self.title = @"千店收款";
    self.weakTimer = [NSTimer scheduledTimerWithTimeInterval:4
                                                      target:self
                                                    selector:@selector(onTimer)
                                                    userInfo:nil
                                                     repeats:YES];
    [self.weakTimer fire];
}

-(void)onTimer{
    __weak __typeof__(self) weakSelf = self;
    NSLog(@"onTimer");
    NSString *url = @"https://www.sglituo.com/textToSounds";
    NSDictionary *params = @{@"staffId":@"od0Ld4k0Rto8RKSvf42M4QQCnFL0"};
    [LGFAFNetworkingTool networkWithMethod:PDAHTTPMethodPOST url:url parameters:params headers:nil success:^(id  _Nullable response) {
        int code = [response[@"code"] intValue];
        NSString *data = response[@"data"];
        NSLog(@"response= %@",data);
        if(code==10001){
            weakSelf.playCount++;
            weakSelf.stateLabel.text = [NSString stringWithFormat:@"循环次数: %d ,时间:%@",weakSelf.playCount,[weakSelf getCurrentTimes]];
            if (response[@"data"] != [NSNull null] && response[@"data"] != nil) {
                NSString *payDataStr = response[@"data"];
                [weakSelf reloadTBWith:payDataStr];
                weakSelf.payCount++;
                [weakSelf prepareToPlayWithUrl:response[@"data"]];
//                weakSelf.payCountLabel.text = [NSString stringWithFormat:@"付款次数 - %d - 当前时间=%@",self.payCount,[self getCurrentTimes]];
            }
        }
    } failure:^(NSError * _Nullable error) {
        NSLog(@"error= %@",error);
    }];
}

-(void)reloadTBWith:(NSString *)payDataStr{
    NSRange startRange = [payDataStr rangeOfString:@"/speeksrc/"];
    NSInteger startLocation = startRange.location+startRange.length;
    NSRange endRange = [payDataStr rangeOfString:@".mp3"];
    NSString *moneyStr = [payDataStr substringWithRange:NSMakeRange(startLocation,endRange.location-startLocation)];
    NSDictionary *payDict = @{@"money":[NSString stringWithFormat:@"金额:%@元",moneyStr],@"date":[NSString stringWithFormat:@"时间:%@",[self getCurrentTimes]]};
    [self.payDataArr insertObject:payDict atIndex:0];
    [[NSUserDefaults standardUserDefaults] setObject:self.payDataArr forKey:@"localPayDataDicts"];
    [self.payListTB reloadData];
}


- (void)prepareToPlayWithUrl:(NSString*)url{
    AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:url]];
    self.player = [[AVPlayer alloc] initWithPlayerItem:item];
    [self.player play];
}

-(void)setUpView{
    self.view.backgroundColor = [UIColor whiteColor];
    
    UILabel *starTimeLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 90, self.view.bounds.size.width, 30)];
    starTimeLabel.textAlignment = NSTextAlignmentLeft;
    self.starTimeLabel = starTimeLabel;
    starTimeLabel.font = [UIFont systemFontOfSize:14];
    starTimeLabel.text = [NSString stringWithFormat:@"开始时间:%@",[self getCurrentTimes]];
    [self.view addSubview:starTimeLabel];
    
    //循环次数
    UILabel *stateLabel = [[UILabel alloc] initWithFrame:CGRectMake(15, 120, self.view.bounds.size.width, 30)];
    stateLabel.font = [UIFont systemFontOfSize:14];
    stateLabel.textAlignment = NSTextAlignmentLeft;
    self.stateLabel = stateLabel;
    [self.view addSubview:stateLabel];
    
    
    self.payListTB= [[UITableView alloc] initWithFrame:CGRectMake(0, 150, self.view.bounds.size.width, self.view.bounds.size.height-150) style:UITableViewStylePlain];
    self.payListTB.delegate= self;
    self.payListTB.dataSource= self;
    //属性设置 行高
    self.payListTB.rowHeight= 50;
    [self.view addSubview:self.payListTB];
}

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
    
    static NSString*idetifierCell = @"cell";
    UITableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:idetifierCell];
    if(!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:idetifierCell];
    }
    if(self.payDataArr.count>0){
        NSLog(@"%@",self.payDataArr);
        NSDictionary *dict = self.payDataArr[indexPath.row];
        cell.textLabel.text = dict[@"money"];
        cell.detailTextLabel.text = dict[@"date"];
        cell.detailTextLabel.textColor = [UIColor colorWithRed:52/255.0 green:52/255.0 blue:52/255.0 alpha:1];
    }
    return cell;
}

//返回节数
-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView{
    return 1;
}

//返回某个节中行数
-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section{
    return self.payDataArr.count;
}

//获取当前的时间
-(NSString*)getCurrentTimes{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"];
    NSDate *datenow = [NSDate date];
    NSString *currentTimeString = [formatter stringFromDate:datenow];
    return currentTimeString;
}

-(void)dealloc{
    [self.player pause];
    self.player = nil;
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

-(NSMutableArray *)payDataArr{
    if(!_payDataArr){
        _payDataArr = [NSMutableArray array];
    }
    return _payDataArr;
}

@end
View Code
复制代码

appDelegate.m

复制代码
//
//  AppDelegate.m
//  AVAudioDemo
//
//  Created by pconline on 2017/8/16.
//  Copyright © 2017年 pconline. All rights reserved.
//

#import "AppDelegate.h"
#import <AVFoundation/AVFoundation.h>
#import "BackgroundTaskManager.h"
@interface AppDelegate ()
@property UIBackgroundTaskIdentifier backgroundTask;
@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    //后台播放
    //    AVAudioSession *session = [AVAudioSession sharedInstance];
    //    [session setCategory:AVAudioSessionCategoryPlayback error:nil];
    //    [session setActive:YES error:nil];
    
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
    [session setCategory:AVAudioSessionCategoryPlayback error:nil];
    
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    
    return YES;
}


- (void)applicationWillResignActive:(UIApplication *)application {
    //停止播放
    [[BackgroundTaskManager shareManager] stopPlayAudioSession];
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    //开始播放
    [[BackgroundTaskManager shareManager] startPlayAudioSession];
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}


- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}


@end
View Code
复制代码

LGFAFNetwork.h

复制代码
//
//  LGFAFNetworkingTool.h
//  testOC
//
//  Created by bairui on 2023/2/9.
//

#import <Foundation/Foundation.h>
#import <AFNetworking.h>
 
NS_ASSUME_NONNULL_BEGIN
 
//网络请求枚举
typedef enum : NSUInteger {
    PDAHTTPMethodGET,
    PDAHTTPMethodPOST
} PDAHTTPMethod;
 
@interface LGFAFNetworkingTool : AFHTTPSessionManager
 
+ (void)networkWithMethod:(PDAHTTPMethod)method
                     url:(NSString *)urlString
              parameters:(nullable NSDictionary *)parameters
                 headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                 success:(nullable void(^)(id _Nullable response))success
                  failure:(nullable void(^)(NSError * _Nullable error))failure;
@end
 
NS_ASSUME_NONNULL_END
View Code
复制代码

LGFAFNetwork.m

复制代码
//
//  LGFAFNetworkingTool.m
//  testOC
//
//  Created by bairui on 2023/2/9.
//

#import "LGFAFNetworkingTool.h"
 
@implementation LGFAFNetworkingTool
-(AFHTTPSessionManager *)sharedManager
{
  AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
  //最大请求并发任务数
  manager.operationQueue.maxConcurrentOperationCount = 5;

  // 请求格式
  // AFHTTPRequestSerializer      二进制格式
  // AFJSONRequestSerializer      JSON
  // AFPropertyListRequestSerializer  PList(是一种特殊的XML,解析起来相对容易)
  
  manager.requestSerializer = [AFHTTPRequestSerializer serializer]; // 上传普通格式
  
  // 超时时间
  manager.requestSerializer.timeoutInterval = 30.0f;
  // 设置请求头
  [manager.requestSerializer setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"];
  // 设置接收的Content-Type
  manager.responseSerializer.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml",@"text/html", @"application/json",@"text/plain",nil];
  
  // 返回格式
  // AFHTTPResponseSerializer      二进制格式
  // AFJSONResponseSerializer      JSON
  // AFXMLParserResponseSerializer   XML,只能返回XMLParser,还需要自己通过代理方法解析
  // AFXMLDocumentResponseSerializer (Mac OS X)
  // AFPropertyListResponseSerializer  PList
  // AFImageResponseSerializer     Image
  // AFCompoundResponseSerializer    组合
  
  manager.responseSerializer = [AFJSONResponseSerializer serializer];//返回格式 JSON
  //设置返回C的ontent-type
  manager.responseSerializer.acceptableContentTypes=[[NSSet alloc] initWithObjects:@"application/xml", @"text/xml",@"text/html", @"application/json",@"text/plain",nil];

  return manager;
}


+ (void)networkWithMethod:(PDAHTTPMethod)method
                     url:(NSString *)urlString
              parameters:(nullable NSDictionary *)parameters
                 headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                 success:(nullable void(^)(id _Nullable response))success
                 failure:(nullable void(^)(NSError * _Nullable error))failure {
   
    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
    manager.requestSerializer = [AFJSONRequestSerializer serializerWithWritingOptions:NSJSONWritingPrettyPrinted];
    // 超时时间
    manager.requestSerializer.timeoutInterval = 30.0f;
    // 设置请求头
    [manager.requestSerializer setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"];
    // 设置接收的Content-Type
    manager.responseSerializer.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml",@"text/html", @"application/json",@"text/plain",nil];
    manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingMutableContainers];
    //设置返回C的ontent-type
    manager.responseSerializer.acceptableContentTypes=[[NSSet alloc] initWithObjects:@"application/xml", @"text/xml",@"text/html", @"application/json",@"text/plain",nil];
    
    if (method == PDAHTTPMethodPOST) {
        [manager POST:urlString parameters:parameters headers:headers progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            if (success != nil) {
                success(responseObject);
            }
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            if (failure != nil) {
                failure(error);
            }
        }];
    }
    
    if (method == PDAHTTPMethodGET) {
        [manager GET:urlString parameters:parameters headers:headers progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            if (success != nil) {
                success(responseObject);
            }
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            if (failure != nil) {
                failure(error);
            }
        }];
    }
}

@end
View Code
复制代码

BackgroundTaskManager.h

复制代码
//
//  BackgroundTaskManager.h
//  Teleprompter_iOS
//
//  Created by ileja on 2022/5/17.
//
//  后台保活工具

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface BackgroundTaskManager : NSObject

/// 创建单利
+ (BackgroundTaskManager *)shareManager;

/// 开始播放音乐
- (void)startPlayAudioSession;

/// 停止播放音乐
- (void)stopPlayAudioSession;

@end

NS_ASSUME_NONNULL_END
View Code
复制代码

BackgroundTaskManager.m

复制代码
//
//  BackgroundTaskManager.m
//  Teleprompter_iOS
//
//  Created by ileja on 2022/5/17.
//

#import "BackgroundTaskManager.h"
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>

@interface BackgroundTaskManager()

@property (strong, nonatomic) AVAudioPlayer *audioPlayer;

@end

@implementation BackgroundTaskManager

/// 创建单利
+ (BackgroundTaskManager *)shareManager
{
   static BackgroundTaskManager *manager = nil;
   static dispatch_once_t onceToken;
   dispatch_once(&onceToken, ^{
       manager = [[BackgroundTaskManager alloc]init];
   });
   return manager;
}

/// 开始播放声音
- (void)startPlayAudioSession
{
   [self.audioPlayer play];
}

/// 停止播放声音
- (void)stopPlayAudioSession
{
   [self.audioPlayer stop];
}

- (AVAudioPlayer *)audioPlayer
{
    if (!_audioPlayer) {
        //设置后台模式和锁屏模式下依然能够播放
        [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
        [[AVAudioSession sharedInstance] setActive: YES error: nil];
        //初始化音频播放器
        NSError *playerError;
        NSURL *urlSound = [[NSURL alloc]initWithString:[[NSBundle mainBundle]pathForResource:@"pomodoSound" ofType:@"wav"]];
        _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:urlSound error:&playerError];
        _audioPlayer.numberOfLoops = -1;//无限播放
        _audioPlayer.volume = 0;
    }
    return _audioPlayer;
}

@end
View Code
复制代码

 

posted @   码锋窝  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示