// // MusiclistViewControllers.m // Lookfit // // Created by ecell on 2023/3/13. // Copyright © 2023 Sheldon. All rights reserved. // #import "MusiclistViewControllers.h" #import #import "MusicListTableViewCell.h" #import "MusicModel.h" #import "JL_RunSDK.h" #import #import "transferPopViews.h" #import "BLEConst.h" @interface MusiclistViewControllers () @property (nonatomic ,strong) UITableView *listTable; @property (nonatomic ,strong) NSMutableArray *songArr; @property (nonatomic ,strong) NSMutableArray *selectArr; @property (nonatomic ,strong) NSMutableArray *updataArr; @property (nonatomic ,weak) UIButton *selectbtn; @property (nonatomic ,assign) BOOL isSelect; @property (nonatomic ,weak) UIButton *addBtn; @property (nonatomic ,assign) NSInteger coutn; @property (nonatomic ,weak) transferPopViews *popview; @property (nonatomic ,assign) NSInteger jisuan; @end @implementation MusiclistViewControllers - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. self.isSelect = NO; [self getItunesMusic]; [self.view addSubview:self.listTable]; self.listTable.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - 180 - 50); UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.backgroundColor = [UIColor colorWithRed:230.0/255.0 green:230.0/255.0 blue:230.0/255.0 alpha:1]; button.frame = CGRectMake(30, self.view.frame.size.height-180, self.view.frame.size.width-60, 50); [button setTitle:NSLocalizedString(@"添加音乐", nil) forState:UIControlStateNormal]; button.titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size: 20]; [button setTitleColor:[UIColor colorWithRed:245.0/255.0 green:124.0/255.0 blue:5.0/255.0 alpha:1] forState:0]; button.layer.cornerRadius = 25; button.layer.masksToBounds = YES; self.addBtn = button; [button addTarget:self action:@selector(addmu) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button]; [[JL_RunSDK sharedInstance] loadRootFiles]; } - (void)addmu { if (self.selectArr.count <= 0) { [SVProgressHUD showErrorWithStatus:NSLocalizedString(@"请选择需要同步的音乐", nil)]; return; } [self.updataArr removeAllObjects]; transferPopViews *popview = [transferPopViews new]; self.popview = popview; [popview subPopView]; self.coutn = 0; [self chuanshu]; } - (void)chuanshu { if (self.coutn < self.selectArr.count) { self.popview.numberLabel.text = [NSString stringWithFormat:@"(%ld/%ld)",self.coutn+1,self.selectArr.count]; MusicModel *model = self.selectArr[self.coutn]; NSString *fileName = [model.fileURL lastPathComponent]; [JL_RunSDK.sharedInstance transportFile:model.fileURL fileName:fileName Result:^(JL_BigFileResult result, float progress) { if (result == JL_BigFileTransferStart) { NSLog(@"---> 开始传输。"); } if (result == JL_BigFileTransferEnd) { NSLog(@"---> 传输完成"); NSMutableDictionary *dic = [NSMutableDictionary new]; [dic setValue:model.name forKey:@"name"]; [dic setValue:model.fileURL forKey:@"fileURL"]; [dic setValue:model.singer forKey:@"singer"]; [dic setValue:model.time forKey:@"time"]; [dic setValue:model.musicSize forKey:@"musicSize"]; NSString *reconnectionUUIDSrting = [[NSUserDefaults standardUserDefaults] objectForKey:AutomaticReconnectionDevice]; NSArray *arr = [[NSUserDefaults standardUserDefaults] objectForKey:reconnectionUUIDSrting]; for (NSDictionary *ddic in arr) { if (![ddic[@"name"] isEqualToString:model.name]) [self.updataArr addObject:ddic]; } [self.updataArr addObject:dic]; [[NSUserDefaults standardUserDefaults] setObject:self.updataArr forKey:reconnectionUUIDSrting]; NSLog(@"%@",[[NSUserDefaults standardUserDefaults] objectForKey:reconnectionUUIDSrting]); self.coutn++; if (self.coutn == self.selectArr.count) { [self.popview dismiss]; [SVProgressHUD showInfoWithStatus:NSLocalizedString(@"同步完成", nil)]; self.updataOK(); [self selectMusic]; } else { [self chuanshu]; } } if (result == JL_BigFileTransferDownload) { NSLog(@"---> 传输进度: %.2f",progress); NSString *txt = [NSString stringWithFormat:@"传输进度:%.1f%%",progress*100.0f]; NSString *size = [NSString stringWithFormat:@"文件大小:%@",model.musicSize]; NSString *name = [NSString stringWithFormat:@"文件名称:%@.MP3",model.name]; self.popview.msgLabel.attributedText = [self labelFontSize:[NSString stringWithFormat:@"%@\n%@\n%@",txt,size,name]]; } if (result == JL_BigFileTransferOutOfRange) { NSLog(@"---> 传输数据超范围"); [self.popview dismiss]; [self selectMusic]; [SVProgressHUD showErrorWithStatus:NSLocalizedString(@"传输数据超范围", nil)]; } if (result == JL_BigFileTransferFail) { NSLog(@"---> 文件传输失败"); [self.popview dismiss]; [self selectMusic]; [SVProgressHUD showErrorWithStatus:NSLocalizedString(@"文件传输失败", nil)]; } if (result == JL_BigFileCrcError) { NSLog(@"---> 文件校验失败"); [self.popview dismiss]; [self selectMusic]; [SVProgressHUD showErrorWithStatus:NSLocalizedString(@"文件校验失败", nil)]; } if (result == JL_BigFileOutOfMemory) { NSLog(@"---> 空间不足"); [self.popview dismiss]; [self selectMusic]; [SVProgressHUD showErrorWithStatus:NSLocalizedString(@"空间不足", nil)]; } if (result == JL_BigFileTransferNoResponse) { NSLog(@"---> 设备没有响应"); [self.popview dismiss]; [self selectMusic]; [SVProgressHUD showErrorWithStatus:NSLocalizedString(@"设备没有响应", nil)]; } if (result == JL_BigFileTransferCancel) { NSLog(@"---> 传输取消"); [self.popview dismiss]; [self selectMusic]; [SVProgressHUD showErrorWithStatus:NSLocalizedString(@"同步取消", nil)]; } }]; } } - (UITableView *)listTable { if (!_listTable) { _listTable = [[UITableView alloc] init]; _listTable.backgroundColor = [UIColor clearColor]; _listTable.dataSource = self; _listTable.delegate = self; [_listTable setRowHeight:70]; // _listTable.separatorStyle = UITableViewCellSeparatorStyleNone; [_listTable registerClass:MusicListTableViewCell.class forCellReuseIdentifier:NSStringFromClass(MusicListTableViewCell.class)]; //__weak typeof(self) weakSelf = self; } return _listTable; } -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { MusicListTableViewCell *cell = [MusicListTableViewCell cellWithTableView:tableView indexPath:indexPath]; cell.isSelect = self.isSelect; cell.msgModel = self.songArr[indexPath.row]; cell.coutn = indexPath.row+1; return cell; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.songArr.count; } -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { MusicModel *model = self.songArr[indexPath.row]; if (self.isSelect) { BOOL select = [model.isSelect boolValue]; select = !select; if (select) { model.isSelect = @"1"; [self.selectArr addObject:model]; } else { model.isSelect = @"0"; [self.selectArr removeObject:model]; } [self.addBtn setTitle:self.selectArr.count > 0 ? [NSString stringWithFormat:@"%@ %ld/%ld",NSLocalizedString(@"同步音乐至手表", nil),self.selectArr.count,self.songArr.count] : NSLocalizedString(@"添加音乐", nil) forState:UIControlStateNormal]; } [self.listTable reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone]; } // MARK:- 获取 iTunes 中的音乐 - (void)getItunesMusic { // 创建媒体选择队列 MPMediaQuery *query = [[MPMediaQuery alloc] init]; // 创建读取条件 MPMediaPropertyPredicate *albumNamePredicate = [MPMediaPropertyPredicate predicateWithValue:[NSNumber numberWithInt:MPMediaTypeMusic] forProperty:MPMediaItemPropertyMediaType]; // 给队列添加读取条件 [query addFilterPredicate:albumNamePredicate]; // 从队列中获取条件的数组集合 NSArray *itemsFromGenericQuery = [query items]; // 遍历解析数据 self.jisuan = itemsFromGenericQuery.count; for (MPMediaItem *music in itemsFromGenericQuery) { [self resolverMediaItem:music]; } } - (void)resolverMediaItem:(MPMediaItem *)song { [SVProgressHUD showWithStatus:NSLocalizedString(@"加载中", nil)]; // 歌名 NSString *name = [song valueForProperty:MPMediaItemPropertyTitle]; // 歌手名字 NSString *singer = [song valueForProperty:MPMediaItemPropertyArtist]; if(singer == nil) { singer = @"未知歌手"; } // 歌曲时长(单位:秒) NSTimeInterval duration = [[song valueForProperty:MPMediaItemPropertyPlaybackDuration] doubleValue]; NSString *time = @""; if((int)duration % 60 < 10) { time = [NSString stringWithFormat:@"%d:0%d",(int)duration / 60,(int)duration % 60]; }else { time = [NSString stringWithFormat:@"%d:%d",(int)duration / 60,(int)duration % 60]; } // 歌曲插图(没有就返回 nil) MPMediaItemArtwork *artwork = [song valueForProperty:MPMediaItemPropertyArtwork]; UIImage *image; if (artwork) { image = [artwork imageWithSize:CGSizeMake(72, 72)]; }else { image = [UIImage imageNamed:@"duanshipin"]; } NSURL *url = [song valueForProperty:MPMediaItemPropertyAssetURL]; NSArray *DocumentPath= NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *filepath = [[NSString alloc] initWithString:[NSString stringWithFormat:@"%@/%@.MP3",DocumentPath[0],name]]; NSFileManager *fileManager = [NSFileManager defaultManager]; if ([fileManager fileExistsAtPath:filepath]) { MusicModel *model = [MusicModel new]; model.name = name; model.fileURL = filepath; model.singer = singer; model.time = time; //model.image = image; model.isSelect = @"0"; model.musicSize = [self jisuan:[self fileSizeForPath:filepath]]; [self.songArr addObject:model]; dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ dispatch_async(dispatch_get_main_queue(), ^{ [self.listTable reloadData]; [SVProgressHUD dismiss]; }); }); } else { AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:url options:nil]; NSFileManager *fileManager = [NSFileManager defaultManager]; NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentsDirectoryPath = [dirs objectAtIndex:0]; // NSLog (@"compatible presets for songAsset: %@",[AVAssetExportSession exportPresetsCompatibleWithAsset:songAsset]); //NSArray *ar = [AVAssetExportSession exportPresetsCompatibleWithAsset: songAsset]; // NSLog(@"%@", ar); AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset: songAsset presetName:AVAssetExportPresetPassthrough]; //NSLog (@"created exporter. supportedFileTypes: %@", exporter.supportedFileTypes); exporter.shouldOptimizeForNetworkUse = YES; exporter.outputFileType = AVFileTypeQuickTimeMovie; NSString *exportFile = [documentsDirectoryPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.MP3",[song valueForProperty:MPMediaItemPropertyTitle]]]; NSError *error1; if([fileManager fileExistsAtPath:exportFile]) { [fileManager removeItemAtPath:exportFile error:&error1]; } NSURL* exportURL = [NSURL fileURLWithPath:exportFile]; exporter.outputURL = exportURL; // do the export [exporter exportAsynchronouslyWithCompletionHandler:^ { //NSData *data1 = [NSData dataWithContentsOfFile:exportFile]; //NSLog(@"==================data1:%@",data1); int exportStatus = exporter.status; switch (exportStatus) { case AVAssetExportSessionStatusFailed: { // log error to text view NSError *exportError = exporter.error; NSLog (@"AVAssetExportSessionStatusFailed: %@", exportError); break; } case AVAssetExportSessionStatusCompleted: { NSLog (@"AVAssetExportSessionStatusCompleted"); MusicModel *model = [MusicModel new]; model.name = name; model.fileURL = exportFile; model.singer = singer; model.time = time; //model.image = image; model.musicSize = [self jisuan:[self fileSizeForPath:exportFile]]; model.isSelect = @"0"; [self.songArr addObject:model]; dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ dispatch_async(dispatch_get_main_queue(), ^{ [self.listTable reloadData]; if (self.jisuan == self.songArr.count) [SVProgressHUD dismiss]; }); }); break; } case AVAssetExportSessionStatusUnknown: { NSLog (@"AVAssetExportSessionStatusUnknown"); break; } case AVAssetExportSessionStatusExporting: { NSLog (@"AVAssetExportSessionStatusExporting"); break; } case AVAssetExportSessionStatusCancelled: { NSLog (@"AVAssetExportSessionStatusCancelled"); break; } case AVAssetExportSessionStatusWaiting: { NSLog (@"AVAssetExportSessionStatusWaiting"); break; } default: { NSLog (@"didn't get export status"); break; } } }]; } } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; UIButton * button = [UIButton buttonWithType:UIButtonTypeCustom]; button.frame = CGRectMake(0, 0, 80, 49); [button setTitle:NSLocalizedString(@"本地音乐", nil) forState:UIControlStateNormal]; button.titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size: 20]; [button setTitleColor:[UIColor colorWithRed:45.0/255.0 green:45.0/255.0 blue:45.0/255.0 alpha:1] forState:0]; [button setImage:[UIImage imageNamed:@"nav_back"] forState:0]; [button addTarget:self action:@selector(buttonClick) forControlEvents:UIControlEventTouchUpInside]; UIBarButtonItem * backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button]; self.navigationItem.leftBarButtonItem = backButtonItem; UIButton *selectbtn = [UIButton buttonWithType:UIButtonTypeCustom]; selectbtn.frame = CGRectMake(0, 0, 50, 49); [selectbtn setImage:[UIImage imageNamed:@"nav_select_No"] forState:UIControlStateNormal]; [selectbtn setImage:[UIImage imageNamed:@"nav_select_Yes"] forState:UIControlStateSelected]; [selectbtn addTarget:self action:@selector(selectMusic) forControlEvents:UIControlEventTouchUpInside]; self.selectbtn.selected = NO; self.selectbtn = selectbtn; UIBarButtonItem *rightButtonItem = [[UIBarButtonItem alloc] initWithCustomView:selectbtn]; self.navigationItem.rightBarButtonItem = rightButtonItem; } - (void)selectMusic { self.selectbtn.selected = !self.selectbtn.isSelected; [self.addBtn setTitle:NSLocalizedString(@"添加音乐", nil) forState:UIControlStateNormal]; self.isSelect = self.selectbtn.selected; [self.selectArr removeAllObjects]; for (MusicModel *model in self.songArr) { model.isSelect = @"0"; } [self.listTable reloadData]; } - (void)buttonClick { [self.navigationController popViewControllerAnimated:YES]; } - (NSMutableArray *)songArr { if (!_songArr) _songArr = [NSMutableArray new]; return _songArr; } - (NSMutableArray *)selectArr { if (!_selectArr) _selectArr = [NSMutableArray new]; return _selectArr; } - (NSMutableArray *)updataArr { if (!_updataArr) _updataArr = [NSMutableArray new]; return _updataArr; } //获取某个路径下所有文件大小 - (CGFloat)fileSizeForPath:(NSString*)path { CGFloat size = 0; if (!path.length) { return size; } NSFileManager *fileManager = [NSFileManager defaultManager]; NSArray* subPaths = [fileManager contentsOfDirectoryAtPath:path error:nil]; if (subPaths.count) { for (NSString *childPath in subPaths) { NSString *c_path = [path stringByAppendingPathComponent:childPath]; if ([fileManager fileExistsAtPath:c_path]) { size += [self fileSizeForPath:c_path]; } } } else { NSDictionary *fileAttributeDic = [fileManager attributesOfItemAtPath:path error:nil]; size = fileAttributeDic.fileSize; } return size; } - (NSString *)jisuan:(CGFloat)size { NSString *sizeText; if (size >= pow(10, 9)) { // size >= 1GB sizeText = [NSString stringWithFormat:@"%.2fGB", size / pow(10, 9)]; } else if (size >= pow(10, 6)) { // 1GB > size >= 1MB sizeText = [NSString stringWithFormat:@"%.2fMB", size / pow(10, 6)]; } else if (size >= pow(10, 3)) { // 1MB > size >= 1KB sizeText = [NSString stringWithFormat:@"%.2fKB", size / pow(10, 3)]; } else { // 1KB > size sizeText = [NSString stringWithFormat:@"%.fB", size]; } return sizeText; } /// 指定字符大小 /// @param text 内容 - (NSAttributedString *)labelFontSize:(NSString *)text { NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:text]; NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; paragraphStyle.lineSpacing = 6; paragraphStyle.alignment = NSTextAlignmentLeft; [string addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, string.length)]; return string; } /* #pragma mark - Navigation // In a storyboard-based application, you will often want to do a little preparation before navigation - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // Get the new view controller using [segue destinationViewController]. // Pass the selected object to the new view controller. } */ @end