MEDIA-SYSSERVICES媒体播放

1 简单的音乐播放器

1.1 问题

本案例结合之前所学的网络和数据解析等知识完成一个网络音乐播放器,如图-1所示:

图-1

1.2 方案

首先创建一个SingleViewApplication应用,在Storyboard文件中搭建音乐播放器界面,该应用有三个场景组成,第一个场景用于搜索,第二场景显示歌曲列表,第三个场景是播放歌曲界面,有一个播放进度条。这三个场景由一个导航视图控制器管理,如图-2所示:

图-2

本案例使用一个百度的音乐开放接口http://mp3.baidu.com,首先创建一个模型类TRMusicInfo存放音乐的相关信息。

其次将网络请求和解析的代码封装在两个类中TRWebUtils和TRParser。TRWebUtils类中有两个方法,一个是requestMusicsByWord:andCallBack:,该方法根据用户输入的歌手姓名获取到网络请求的路径,然后采用NSURLConnection类发送异步请求,返回的数据是Json格式的,然后采用NSJSONSerialization类进行Json解析,得到音乐的相关信息。

TRWebUtils类中的另一个方法requestMusicDetailByMusic:andCallBack,该方法是通过音乐信息中的音乐ID发送网络请求,然后通过数据解析获取到音乐的下载的地址和歌词地址。对应的在TRParser类有两个解析数据的方法parseMusicInfoByArray:和parseMusicDetailByDic:andMusic:。

然后完成音乐列表视图控制器TRMusicListViewController的代码,该视图控制器继承至UITableViewController,有一个NSMutableArray类型的属性musics,用于存放需要展示的音乐信息。在viewDidLoad方法中通过TRWebUtils类调用requestMusicsByWord:andCallBack:方法,根据用户输入的歌手姓名发送网络请求,解析歌曲数据得到属性self.music数据,刷新界面。

由于表视图的每个Cell需要展示歌曲的信息,所以这里需要自定义一个Cell,因此创建一个TRMusicCell类,继承至UITableViewCell类,需要显示专辑封面,歌曲名、歌手名以及专辑名,如图-3所示:

图-3

然后实现音乐播放视图控制器TRPlayViewController的代码,该视图控制器有一个TRMusicInfo类型的公开属性music,用于记录用户从上一个界面选择的音乐信息。

该视图控制器还有如下几个私有属性:

AVAudioPlayer类型的player,用于播放音乐;

NSURLConnection类型的conn,用于发送下载请求;

NSMutableData类型的allData,用于存放下载的音乐数据;

NSUInteger类型的fileLength,用于记录下载音乐的大小;

在TRPlayViewController的viewDidLoad方法中通过TRWebUtils类调用requestMusicDetailByMusic:andCallBack:方法,根据音乐信息获取到音乐的下载地址和歌词地址,然后通过音乐下载地址发送下载请求,将发送下载请求的代码封装在downloadMusic方法中。

接下来实现NSURLConnectionDelegate的协议方法,在connection:didReceiveResponse:方法中解析头文件,获取到文件的大小并初始化self.allData属性。

在connection:didReceiveData:方法中将下载到的音乐数据保存在self.allData中,并且创建音乐播放器并播放歌曲,实现边下载边播放的功能。

在connectionDidFinishLoading:方法中将音乐的数据存入本地。

最后开启一个计时器,更新进度条的显示,即音乐的播放进度。

1.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:创建模型类

首先创建一个SingleViewApplication应用,在Storyboard文件中搭建音乐播放器界面,该应用有三个场景组成,第一个场景用于搜索,第二场景显示歌曲列表,第三个场景是播放歌曲界面,有一个播放进度条。

本案例使用一个百度的音乐开放接口http://mp3.baidu.com,首先创建一个模型类TRMusicInfo存放音乐的相关信息,代码如下所示:

  1. @interface TRMusicInfo : NSObject
  2. @property (nonatomic, copy)NSString *name;
  3. @property (nonatomic, copy)NSString *singerName;
  4. @property (nonatomic, copy)NSString *albumName;
  5. @property (nonatomic, copy)NSString *songID;
  6. @property (nonatomic, copy)NSString *albumImagePath;
  7. @property (nonatomic, copy)NSString *musicPath;
  8. @property (nonatomic, copy)NSString *lrcPath;
  9. @end

其次将网络请求和解析的代码封装在两个类中TRWebUtils和TRParser。TRWebUtils类中有两个方法,一个是requestMusicsByWord:andCallBack:,该方法根据用户输入的歌手姓名获取到网络请求的路径,然后采用NSURLConnection类发送异步请求,返回的数据是Json格式的,然后采用NSJSONSerialization类进行Json解析,得到音乐的相关信息,代码如下所示:

  1. + (void)requestMusicsByWord:(NSString *)word andCallBack:(MyCallback)callback{
  2. NSString *path = [NSString stringWithFormat:@"http://mp3.baidu.com/dev/api/?tn=getinfo&ct=0&word=%@&ie=utf-8&format=json",word];
  3. path = [path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  4. NSURL *url = [NSURL URLWithString:path];
  5. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  6. [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
  7. NSArray *arr = [NSJSONSerialization JSONObjectWithData:data options:0 error:Nil];
  8. if (arr.count==0) {
  9. [TRWebUtils requestMusicsByWord:word andCallBack:callback];
  10. }
  11. NSMutableArray *musics = [TRParser parseMusicInfoByArray:arr];
  12. callback(musics);
  13. }];
  14. }

TRWebUtils类中的另一个方法requestMusicDetailByMusic:andCallBack,该方法是通过音乐信息中的音乐ID发送网络请求,然后通过数据解析获取到音乐的下载的地址和歌词地址,代码如下所示:

  1. + (void)requestMusicDetailByMusic:(TRMusicInfo *)music andCallBack:(MyCallback)callback{
  2. NSString *path = [NSString stringWithFormat:@"http://ting.baidu.com/data/music/links?songIds=%@",music.songID];
  3. NSLog(@"%@",path);
  4. NSURL *url = [NSURL URLWithString:path];
  5. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  6. [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
  7. NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:0 error:Nil];
  8. [TRParser parseMusicDetailByDic:dic andMusic:music];
  9. callback(music);
  10. }];
  11. }

对应的在TRParser类有两个解析数据的方法parseMusicInfoByArray:和parseMusicDetailByDic:andMusic:,代码如下所示:

  1. +(NSMutableArray *)parseMusicInfoByArray:(NSArray *)arr{
  2. NSMutableArray *musics = [NSMutableArray array];
  3. for (NSDictionary *musicDic in arr) {
  4. TRMusicInfo *mi = [[TRMusicInfo alloc]init];
  5. mi.name = [musicDic objectForKey:@"song"];
  6. mi.singerName = [musicDic objectForKey:@"singer"];
  7. mi.albumName = [musicDic objectForKey:@"album"];
  8. mi.songID = [musicDic objectForKey:@"song_id"];
  9. mi.albumImagePath = [musicDic objectForKey:@"albumPicSmall"];
  10. [musics addObject:mi];
  11. }
  12. return musics;
  13. }
  14. +(void)parseMusicDetailByDic:(NSDictionary *)dic andMusic:(TRMusicInfo *)music{
  15. NSDictionary *dataDic = [dic objectForKey:@"data"];
  16. NSArray *songListArr = [dataDic objectForKey:@"songList"];
  17. NSDictionary *musicDic = [songListArr lastObject];
  18. NSString *musicPath = [musicDic objectForKey:@"showLink"];
  19. music.musicPath = musicPath;
  20. music.lrcPath = [NSString stringWithFormat:@"http://ting.baidu.com%@",[musicDic objectForKey:@"lrcLink"]];
  21. }

步骤二:实现TRMusicListViewController展示音乐列表功能

音乐列表视图控制器TRMusicListViewController继承至UITableViewController,它有一个NSMutableArray类型的属性musics,用于存放需要展示的音乐信息。

在viewDidLoad方法中通过TRWebUtils类调用requestMusicsByWord:andCallBack:方法,根据用户输入的歌手姓名发送网络请求,解析歌曲数据得到属性self.music数据,刷新界面,代码如下所示:

  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. [TRWebUtils requestMusicsByWord:self.word andCallBack:^(id obj) {
  5. self.musics = obj;
  6. [self.tableView reloadData];
  7. }];
  8. }

用户所挑选的图片将呈现在下方的ScrollView上面,因此需要在弹出ImagePickerController时创建一个ScrollView和一个确定按钮,当点击确定按钮时表示用户完成图片选择,返回之前的界面,该功能需要在navigationController:didShowViewController:animated:方法中实现,代码如下所示:

  1. -(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
  2. //创建确定按钮
  3. UIImageView *iv = [[UIImageView alloc]initWithFrame:CGRectMake(0, 450, 320, 20)];
  4. [iv setBackgroundColor:[UIColor yellowColor]];
  5. UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
  6. btn.frame = CGRectMake(270, 0, 50, 20);
  7. [btn setTitle:@"确定" forState:UIControlStateNormal];
  8. [btn addTarget:self action:@selector(finishPickImage) forControlEvents:UIControlEventTouchUpInside];
  9. btn.tag = 1;
  10. [iv addSubview:btn];
  11. iv.userInteractionEnabled = YES;
  12. [viewController.view addSubview:iv];
  13. //创建呈现挑选图片的ScrollView
  14. self.pickerScrollView = [[UIScrollView alloc]init];
  15. self.pickerScrollView.frame = CGRectMake(0, 470, 320,80);
  16. [self.pickerScrollView setBackgroundColor:[UIColor grayColor]];
  17. [viewController.view addSubview:self.pickerScrollView];
  18. }

于表视图的每个Cell需要展示歌曲的信息,所以这里需要自定义一个Cell,因此创建一个TRMusicCell类,继承至UITableViewCell类,需要显示专辑封面,歌曲名、歌手名以及专辑名,代码如下所示:

  1. //TRMusicCell.h
  2. @interface TRMusicCell : UITableViewCell
  3. @property (weak, nonatomic) IBOutlet UILabel *singerLabel;
  4. @property (weak, nonatomic) IBOutlet UIImageView *albumIV;
  5. @property (weak, nonatomic) IBOutlet UILabel *nameLabel;
  6. @property (weak, nonatomic) IBOutlet UILabel *albumLabel;
  7. @property (nonatomic, strong)TRMusicInfo *music;
  8. @end
  9. //TRMusicCell.m
  10. @implementation TRMusicCell
  11. -(void)layoutSubviews{
  12. [super layoutSubviews];
  13. self.nameLabel.text = self.music.name;
  14. self.singerLabel.text = self.music.singerName;
  15. self.albumLabel.text = self.music.albumName;
  16. NSLog(@"%@",self.music.albumImagePath);
  17. //从网络获取图片比较耗时,将此操作放入一个操作队列异步执行
  18. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  19. NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:self.music.albumImagePath]];
  20. UIImage *image = [UIImage imageWithData:imageData];
  21. dispatch_async(dispatch_get_main_queue(), ^{
  22. self.albumIV.image = image;
  23. });
  24. });
  25. }
  26. @end

最后实现表视图的数据源方法和delegate委托方法,代码如下所示:

  1. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  2. {
  3. return self.musics.count;
  4. }
  5. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  6. {
  7. static NSString *CellIdentifier = @"Cell";
  8. TRMusicCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
  9. TRMusicInfo *music = self.musics[indexPath.row];
  10. cell.music = music;
  11. return cell;
  12. }
  13. //当用户选择某一首歌曲的时候跳转到音乐播放界面
  14. -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
  15. TRMusicInfo *m = self.musics[indexPath.row];
  16. [self performSegueWithIdentifier:@"playvc" sender:m];
  17. }

步骤三:实现TRPlayViewController的音乐下载和播放功能

音乐播放视图控制器TRPlayViewController有一个TRMusicInfo类型的公开属性music,用于记录用户从上一个界面选择的音乐信息,代码如下所示:

  1. @interface TRPlayViewController : UIViewController
  2. @property (nonatomic, strong)TRMusicInfo *music;
  3. @end

该视图控制器的私有属性,代码如下所示:

  1. @interface TRPlayViewController ()
  2. @property (weak, nonatomic) IBOutlet UISlider *mySlider;
  3. @property (nonatomic, strong)NSMutableData *allData;
  4. @property (nonatomic, strong)AVAudioPlayer *player;
  5. @property (nonatomic, strong)NSTimer *myTimer;
  6. @property (nonatomic, strong) NSURLConnection *conn;
  7. @property (nonatomic) NSUInteger fileLength;
  8. @end

其次在TRPlayViewController的viewDidLoad方法中通过TRWebUtils类调用requestMusicDetailByMusic:andCallBack:方法,根据音乐信息获取到音乐的下载地址和歌词地址,代码如下所示:

  1. - (void)viewDidLoad
  2. {
  3. [super viewDidLoad];
  4. [TRWebUtils requestMusicDetailByMusic:self.music andCallBack:^(id obj) {
  5. [self downloadMusic];
  6. }];
  7. }

然后通过音乐下载地址发送下载请求,将发送下载请求的代码封装在downloadMusic方法中,代码如下所示:

  1. -(void)downloadMusic{
  2. NSURL *url = [NSURL URLWithString:self.music.musicPath];
  3. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  4. //对象创建出来时异步请求已经发出
  5. self.conn = [[NSURLConnection alloc]initWithRequest:request delegate:self];
  6. if (!self.conn) {
  7. NSLog(@"链接创建失败");
  8. }
  9. }

接下来实现NSURLConnectionDelegate的协议方法,在connection:didReceiveResponse:方法中解析头文件,获取到文件的大小并初始化self.allData属性,代码如下所示:

  1. //接收到服务器响应
  2. -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
  3. NSHTTPURLResponse *res = (NSHTTPURLResponse*)response;
  4. NSDictionary *headerDic = res.allHeaderFields;
  5. NSLog(@"%@",headerDic);
  6. self.fileLength = [[headerDic objectForKey:@"Content-Length"] intValue];
  7. self.allData = [NSMutableData data];
  8. }

在connection:didReceiveData:方法中将下载到的音乐数据保存在self.allData中,并且创建音乐播放器并播放歌曲,实现边下载边播放的功能,代码如下所示:

  1. //接收到数据
  2. -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
  3. // NSLog(@"%d",data.length);
  4. [self.allData appendData:data];
  5. //初始化player对象
  6. if (self.allData.length>1024*150&&!self.player) {
  7. NSLog(@"开始播放");
  8. self.player = [[AVAudioPlayer alloc]initWithData:self.allData error:Nil];
  9. [self.player play];
  10. float allTime = self.player.duration*self.fileLength/self.allData.length;
  11. self.mySlider.maximumValue = allTime;
  12. }
  13. }

在connectionDidFinishLoading:方法中将音乐的数据存入本地,代码如下所示:

  1. //加载完成
  2. -(void)connectionDidFinishLoading:(NSURLConnection *)connection{
  3. NSLog(@"下载完成");
  4. //下载完成之后更新准确的歌曲时长
  5. self.mySlider.maximumValue = self.player.duration;
  6. NSString *filePath = [NSString stringWithFormat:@"/Users/Vivian/Desktop/%@",self.music.name];
  7. filePath = [filePath stringByAppendingPathExtension:@"mp3"];
  8. [self.allData writeToFile:filePath atomically:YES];
  9. }

最后在downloadMusic方法中开启一个计时器,更新进度条的显示,即音乐的播放进度,代码如下所示:

  1. -(void)downloadMusic{
  2. NSURL *url = [NSURL URLWithString:self.music.musicPath];
  3. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  4. //对象创建出来时异步请求已经发出
  5. self.conn = [[NSURLConnection alloc]initWithRequest:request delegate:self];
  6. if (!self.conn) {
  7. NSLog(@"链接创建失败");
  8. }
  9. //开启一个计时器,更新界面的进度条
  10. self.myTimer = [NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(updateUI) userInfo:Nil repeats:YES];
  11. }
  12. -(void)viewDidDisappear:(BOOL)animated{
  13. [self.myTimer invalidate];
  14. }
  15. -(void)updateUI{
  16. self.mySlider.value = self.player.currentTime;
  17. }

1.4 完整代码

本案例中,TRViewController.m文件中的完整代码如下所示:

  1. #import "TRViewController.h"
  2. #import "TRMusicListViewController.h"
  3. @interface TRViewController ()
  4. @property (weak, nonatomic) IBOutlet UITextField *myTF;
  5. @end
  6. @implementation TRViewController
  7. -(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
  8. TRMusicListViewController *vc = segue.destinationViewController;
  9. vc.word = self.myTF.text;
  10. }
  11. @end

本案例中,TRMusicListViewController.h文件中的完整代码如下所示:

  1. #import <UIKit/UIKit.h>
  2. @interface TRMusicListViewController : UITableViewController
  3. @property (nonatomic, copy)NSString *word;
  4. @end

本案例中,TRMusicListViewController.m文件中的完整代码如下所示:

  1. #import "TRMusicCell.h"
  2. #import "TRMusicListViewController.h"
  3. #import "TRParser.h"
  4. #import "TRMusicInfo.h"
  5. #import "TRWebUtils.h"
  6. #import "TRPlayViewController.h"
  7. @interface TRMusicListViewController ()
  8. @property (nonatomic, strong)NSMutableArray *musics;
  9. @end
  10. @implementation TRMusicListViewController
  11. - (void)viewDidLoad
  12. {
  13. [super viewDidLoad];
  14. [TRWebUtils requestMusicsByWord:self.word andCallBack:^(id obj) {
  15. self.musics = obj;
  16. [self.tableView reloadData];
  17. }];
  18. }
  19. #pragma mark - Table view data source
  20. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  21. {
  22. return self.musics.count;
  23. }
  24. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  25. {
  26. static NSString *CellIdentifier = @"Cell";
  27. TRMusicCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
  28. TRMusicInfo *music = self.musics[indexPath.row];
  29. cell.music = music;
  30. return cell;
  31. }
  32. -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
  33. TRMusicInfo *m = self.musics[indexPath.row];
  34. [self performSegueWithIdentifier:@"playvc" sender:m];
  35. }
  36. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
  37. {
  38. TRPlayViewController *vc = segue.destinationViewController;
  39. vc.music = sender;
  40. }
  41. @end

本案例中,TRPlayViewController.h文件中的完整代码如下所示:

  1. #import <UIKit/UIKit.h>
  2. #import "TRMusicInfo.h"
  3. @interface TRPlayViewController : UIViewController
  4. @property (nonatomic, strong)TRMusicInfo *music;
  5. @end

本案例中,TRPlayViewController.m文件中的完整代码如下所示:

  1. #import "TRPlayViewController.h"
  2. #import "TRWebUtils.h"
  3. #import <AVFoundation/AVFoundation.h>
  4. @interface TRPlayViewController ()
  5. @property (weak, nonatomic) IBOutlet UISlider *mySlider;
  6. @property (nonatomic, strong)NSMutableData *allData;
  7. @property (nonatomic, strong)AVAudioPlayer *player;
  8. @property (nonatomic, strong)NSTimer *myTimer;
  9. @property (nonatomic, strong) NSURLConnection *conn;
  10. @property (nonatomic) NSUInteger fileLength;
  11. @end
  12. @implementation TRPlayViewController
  13. - (void)viewDidLoad
  14. {
  15. [super viewDidLoad];
  16. [TRWebUtils requestMusicDetailByMusic:self.music andCallBack:^(id obj) {
  17. [self downloadMusic];
  18. }];
  19. }
  20. -(void)downloadMusic{
  21. NSURL *url = [NSURL URLWithString:self.music.musicPath];
  22. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  23. //对象创建出来时 异步请求已经发出
  24. self.conn = [[NSURLConnection alloc]initWithRequest:request delegate:self];
  25. if (!self.conn) {
  26. NSLog(@"链接创建失败");
  27. }
  28. //开启一个计时器,更新界面的进度条
  29. self.myTimer = [NSTimer scheduledTimerWithTimeInterval:.1 target:self selector:@selector(updateUI) userInfo:Nil repeats:YES];
  30. }
  31. -(void)viewDidDisappear:(BOOL)animated{
  32. [self.myTimer invalidate];
  33. }
  34. -(void)updateUI{
  35. self.mySlider.value = self.player.currentTime;
  36. }
  37. #pragma mark NSURLConnectionDelegate
  38. //接收到服务器响应
  39. -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
  40. NSHTTPURLResponse *res = (NSHTTPURLResponse*)response;
  41. NSDictionary *headerDic = res.allHeaderFields;
  42. NSLog(@"%@",headerDic);
  43. self.fileLength = [[headerDic objectForKey:@"Content-Length"] intValue];
  44. self.allData = [NSMutableData data];
  45. }
  46. //接收到数据
  47. -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
  48. // NSLog(@"%d",data.length);
  49. [self.allData appendData:data];
  50. //初始化player对象
  51. if (self.allData.length>1024*150&&!self.player) {
  52. NSLog(@"开始播放");
  53. self.player = [[AVAudioPlayer alloc]initWithData:self.allData error:Nil];
  54. [self.player play];
  55. float allTime = self.player.duration*self.fileLength/self.allData.length;
  56. self.mySlider.maximumValue = allTime;
  57. }
  58. }
  59. //加载完成
  60. -(void)connectionDidFinishLoading:(NSURLConnection *)connection{
  61. NSLog(@"下载完成");
  62. //下载完成之后更新准确的歌曲时长
  63. self.mySlider.maximumValue = self.player.duration;
  64. NSString *filePath = [NSString stringWithFormat:@"/Users/Vivian/Desktop/%@",self.music.name];
  65. filePath = [filePath stringByAppendingPathExtension:@"mp3"];
  66. [self.allData writeToFile:filePath atomically:YES];
  67. }
  68. @end

本案例中,TRMusicCell.h文件中的完整代码如下所示:

  1. #import <UIKit/UIKit.h>
  2. #import "TRMusicInfo.h"
  3. @interface TRMusicCell : UITableViewCell
  4. @property (weak, nonatomic) IBOutlet UILabel *singerLabel;
  5. @property (weak, nonatomic) IBOutlet UIImageView *albumIV;
  6. @property (weak, nonatomic) IBOutlet UILabel *nameLabel;
  7. @property (weak, nonatomic) IBOutlet UILabel *albumLabel;
  8. @property (nonatomic, strong)TRMusicInfo *music;
  9. @end

本案例中,TRMusicCell.m文件中的完整代码如下所示:

  1. @implementation TRMusicCell
  2. -(void)layoutSubviews{
  3. [super layoutSubviews];
  4. self.nameLabel.text = self.music.name;
  5. self.singerLabel.text = self.music.singerName;
  6. self.albumLabel.text = self.music.albumName;
  7. NSLog(@"%@",self.music.albumImagePath);
  8. //从网络获取图片比较耗时,将此操作放入一个操作队列异步执行
  9. dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  10. NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:self.music.albumImagePath]];
  11. UIImage *image = [UIImage imageWithData:imageData];
  12. dispatch_async(dispatch_get_main_queue(), ^{
  13. self.albumIV.image = image;
  14. });
  15. });
  16. }
  17. @end

本案例中,TRMusicInfo.h文件中的完整代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. @interface TRMusicInfo : NSObject
  3. @property (nonatomic, copy)NSString *name;
  4. @property (nonatomic, copy)NSString *singerName;
  5. @property (nonatomic, copy)NSString *albumName;
  6. @property (nonatomic, copy)NSString *songID;
  7. @property (nonatomic, copy)NSString *albumImagePath;
  8. @property (nonatomic, copy)NSString *musicPath;
  9. @property (nonatomic, copy)NSString *lrcPath;
  10. @end

本案例中,TRParser.h文件中的完整代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. #import "TRMusicInfo.h"
  3. @interface TRParser : NSObject
  4. + (NSMutableArray *)parseMusicInfoByArray:(NSArray *)arr;
  5. + (void)parseMusicDetailByDic:(NSDictionary *)dic andMusic:(TRMusicInfo *)music;
  6. @end

本案例中,TRParser.m文件中的完整代码如下所示:

  1. #import "TRParser.h"
  2. #import "TRMusicInfo.h"
  3. @implementation TRParser
  4. +(NSMutableArray *)parseMusicInfoByArray:(NSArray *)arr{
  5. NSMutableArray *musics = [NSMutableArray array];
  6. for (NSDictionary *musicDic in arr) {
  7. TRMusicInfo *mi = [[TRMusicInfo alloc]init];
  8. mi.name = [musicDic objectForKey:@"song"];
  9. mi.singerName = [musicDic objectForKey:@"singer"];
  10. mi.albumName = [musicDic objectForKey:@"album"];
  11. mi.songID = [musicDic objectForKey:@"song_id"];
  12. mi.albumImagePath = [musicDic objectForKey:@"albumPicSmall"];
  13. [musics addObject:mi];
  14. }
  15. return musics;
  16. }
  17. +(void)parseMusicDetailByDic:(NSDictionary *)dic andMusic:(TRMusicInfo *)music{
  18. NSDictionary *dataDic = [dic objectForKey:@"data"];
  19. NSArray *songListArr = [dataDic objectForKey:@"songList"];
  20. NSDictionary *musicDic = [songListArr lastObject];
  21. NSString *musicPath = [musicDic objectForKey:@"showLink"];
  22. music.musicPath = musicPath;
  23. music.lrcPath = [NSString stringWithFormat:@"http://ting.baidu.com%@",[musicDic objectForKey:@"lrcLink"]];
  24. }
  25. @end

本案例中,TRWebUtils.h文件中的完整代码如下所示:

  1. #import <Foundation/Foundation.h>
  2. #import "TRMusicInfo.h"
  3. typedef void (^MyCallback)(id obj);
  4. @interface TRWebUtils : NSObject
  5. + (void)requestMusicsByWord:(NSString *)word andCallBack:(MyCallback)callback;
  6. + (void)requestMusicDetailByMusic:(TRMusicInfo *)music andCallBack:(MyCallback)callback;
  7. @end

本案例中,TRWebUtils.m文件中的完整代码如下所示:

  1. #import "TRWebUtils.h"
  2. #import "TRParser.h"
  3. @implementation TRWebUtils
  4. + (void)requestMusicsByWord:(NSString *)word andCallBack:(MyCallback)callback{
  5. NSString *path = [NSString stringWithFormat:@"http://mp3.baidu.com/dev/api/?tn=getinfo&ct=0&word=%@&ie=utf-8&format=json",word];
  6. path = [path stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  7. NSURL *url = [NSURL URLWithString:path];
  8. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  9. [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
  10. NSArray *arr = [NSJSONSerialization JSONObjectWithData:data options:0 error:Nil];
  11. if (arr.count==0) {
  12. [TRWebUtils requestMusicsByWord:word andCallBack:callback];
  13. }
  14. NSMutableArray *musics = [TRParser parseMusicInfoByArray:arr];
  15. callback(musics);
  16. }];
  17. }
  18. + (void)requestMusicDetailByMusic:(TRMusicInfo *)music andCallBack:(MyCallback)callback{
  19. NSString *path = [NSString stringWithFormat:@"http://ting.baidu.com/data/music/links?songIds=%@",music.songID];
  20. NSLog(@"%@",path);
  21. NSURL *url = [NSURL URLWithString:path];
  22. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
  23. [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
  24. NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:0 error:Nil];
  25. [TRParser parseMusicDetailByDic:dic andMusic:music];
  26. callback(music);
  27. }];
  28. }
  29. @end
时间: 2024-10-10 07:50:02

MEDIA-SYSSERVICES媒体播放的相关文章

(原创)jQuery Media Plugin-jQuery的网页媒体播放器插件的使用心得

jQuery Media Plugin是一款基于jQuery的网页媒体播放器插件,它支持大部分的网络多媒体播放器和多媒体格式,比如:Flash, Windows Media Player, Real Player, Quicktime, MP3,Silverlight, PDF.它根据当前的脚本配置,自动将a标签替换成div,并生成object, embed甚至是iframe代码,至于生成object还是embed,jQuery Media会根据当前平台自动判别,因此兼容性方面非常出色下面这段代

Windows Media Foundation学习笔记3——媒体播放

跳过第二章对工具TopoEdit的介绍,直接进行媒体播放的学习. 媒体播放这章,介绍了个文件播放的例子,想起当初学习dshow的时候,一开始也是个文件播放例子,不过那个例子比较简单,没多少代码,nnd,而这个demo彻底瞎了,就一个简单的文件播放就这么多代码,哎. 这章的第一要义是说MF广泛使用COM技术但又不是真正的COM接口,也就是MF混合了COM和正常的对象,使用COM的话很明显得初始化COM. 以下按照播放一个文件的流程,介绍使用到的MF相关概念: 1. 初始化COM,初始化MF.(特别

c#开发的媒体播放器

在Microsoft Visual C# .NET 中使用 DirectShow 控件,来开发一个媒体播放器.按照本文介绍的操作步骤,您可以创建一个简单 Visual C# 应用程序,用来播放数字音频和视频. 介绍 Microsoft Visual C# 是世界上最流行的编程语言,利用 Visual C# 的最新版本 Visual C# .NET,您能够快速.有效地开发基于 Windows 窗体的应用程序,还可以为嵌入了 Microsoft Windows Media? Player 9 Ser

【转】媒体播放器三大底层架构

媒体播放工具,这里主要指视频播放,因为要面临庞大的兼容性和纷繁复杂的算法,从架构上看,能脱颖而出的体系屈指可数.大体来说业界主要有3大架构:MPC.MPlayer和VLC.这3大架构及其衍生品占领了90%的市场,凡是用户能看到的免费媒体播放软件,无一不是源自这3大架构. MPC-HC架构  MPC(Media Player Classic)和它的后续者MPC-HC应该并列而说.MPC基于DirectShow架构,是Windows系统下元祖级别的播放器.包括KMP之流 最早也就是抄来MPC的代码再

媒体播放器三大底层架构

自射手影音推出以来,生活中越来越多的时间开始被代码和各种Bug-Fix淹没.埋头在田里太久,常常会在一时之间忘记身处何方.所以偶尔上来透透气,顺便将一些经验和心得与大家分享. 媒体播放工具,这里主要指视频播放,因为要面临庞大的兼容性和纷繁复杂的算法,从架构上看,能脱颖而出的体系屈指可数.大体来说业界主要有3大架构:MPC.MPlayer和VLC.这3大架构及其衍生品占领了90%的市场,凡是用户能看到的免费媒体播放软件,无一不是源自这3大架构. MPC/HC架构 MPC(Media Player

转:媒体播放器三大底层架构

媒体播放工具,这里主要指视频播放,因为要面临庞大的兼容性和纷繁复杂的算法,从架构上看,能脱颖而出的体系屈指可数.大体来说业界主要有3大架 构:MPC.MPlayer和VLC.这3大架构及其衍生品占领了90%的市场,凡是用户能看到的免费媒体播放软件,无一不是源自这3大架构.? ? MPC-HC架构? MPC(Media Player Classic)和它的后续者MPC-HC应该并列而说.MPC基于DirectShow架构,是Windows系统下元祖级别的播放器.包括KMP之流 最早也就是抄来MPC

媒体播放器之:TCPMP播放器简介

*************************************************************************************************************************** 作者:EasyWave                                                             时间:2014.09.06 类别:Media播放器-TCPMP播放器简介                  

Winform Windows Media Player 简易播放器

新手上路,高手勿进! 窗体设计: 实现效果: 实现代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Data.SqlClient; using Sy

C#编写媒体播放器--Microsoft的Directx提供的DirectShow组件,该组件的程序集QuartzTypeLib.dll.

使用C#编写媒体播放器时,需要用到Microsoft的Directx提供的DirectShow组件.用该组件前需要先注册程序集QuartzTypeLib.dll. 1.用QuartzTypeLib.dll播放视频 1.1Form1.cs using System; using System.Windows.Forms; using QuartzTypeLib; namespace DirectShow {     public partial class Form1 : Form     {  

快速构建Windows 8风格应用21-构建简单媒体播放器

原文:快速构建Windows 8风格应用21-构建简单媒体播放器 本篇博文主要介绍如何构建一个简单的媒体播放器. <快速构建Windows 8风格应用20-MediaElement>博文中提到了如何使用MediaElement对象进行播放视频的简单功能,但是在实际应用中需要更复杂的功能,例如:控制视频播放的控件.全屏模式.进度条等等其他功能. 本篇博文中示例使用应用程序中包含的媒体文件,当然我们也可以通过网络或者本地[使用FileOpenPicker]进行加载某一媒体文件. MSDN中关于媒体