iOS 根据网址URL下载并播放网络音频文件

//  文件下载
//  DownLoadRequest.h
//
//
//  Created by 符之飞 on 16/4/16.
//
//

#import <Foundation/Foundation.h>

#define ZFileDownloadPath  [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] stringByAppendingPathComponent:@"MyDownloadFile.mp3"]

@interface DownLoadRequest : NSObject
/**
 *  URL   下载链接
 *  Path  下载存放路径,如果程序退出,下次传入的路径和上一次一样,可以继续断点下载
 */
- (instancetype)initWithURL:(NSString *)URL Path:(NSString *)path;

/**
 * 下载回调
 */
-(void)BegindownProgress:(void (^)(long long totalReceivedContentLength, long long totalContentLength))progress Succeed:(void(^)(NSString * URL, NSString * path))succeed Failure:(void(^)())failure;

/**
 * 取消下载
 */
-(void)cancelLoad;

/**
 * 开始下载
 */
-(void)startLoad;

//-(void)deleteAllFile;

@end
//
//  DownLoadRequest.m
//  
//
//  Created by 符之飞 on 16/4/16.
//
//

#import "DownLoadRequest.h"

typedef void (^ProgressBlock)();
typedef void (^SucceedBlock)();
typedef void (^FailureBlock)();

@interface DownLoadRequest()
/**
 *  请求
 */
@property (strong , nonatomic)  NSURLConnection * Connection;

/**
 *  用来写数据的文件句柄对象
 */
@property (nonatomic, strong) NSFileHandle  * writeHandle;

/**
 *  下载链接
 */
@property (nonatomic, copy) NSString * URL;

/**
 *  存放路径
 */
@property (nonatomic, copy) NSString * path;

/**
 *  进度回调
 */
@property(nonatomic, copy) ProgressBlock progressBlock;

/**
 *  下载成功回调
 */
@property (nonatomic, copy) SucceedBlock succeedBlock;

/**
 *  下载失败回调
 */
@property (nonatomic, copy) FailureBlock  failureBlock;

/**
 *  总的长度
 */
@property (nonatomic, assign) NSInteger  totalexpectedContentLength;

/**
 *  当前已经写入的长度
 */
@property (nonatomic, assign) NSInteger  totalReceivedContentLength;

@end

@implementation DownLoadRequest

- (instancetype)initWithURL:(NSString *)URL Path:(NSString *)path
{
    self = [super init];
    if (self) {
        _path  = path;
        _URL = URL;
    }
    return self;
}

/**
 * 开始下载
 */
-(void)BegindownProgress:(void (^)(long long totalReceivedContentLength, long long totalContentLength))progress Succeed:(void(^)(NSString * URL, NSString * path))succeed Failure:(void(^)())failure
{
    __weak __typeof (self)weakself = self;
    [self setProgressBlockWithProgress:progress];
    self.succeedBlock=^()
    {
        succeed(weakself.URL, weakself.path);
    };
    self.failureBlock = ^{
        failure();
    };
    [self startLoad];
}

//进度条回调
-(void)setProgressBlockWithProgress:(void (^)(long long totalReceivedContentLength, long long totalContentLength))progress
{
    __weak __typeof (self)weakself = self;
    self.progressBlock = ^{
        if (progress != nil)
        {
            dispatch_async(dispatch_get_main_queue(), ^{
                progress(weakself.totalReceivedContentLength, weakself.totalexpectedContentLength);
            });
        }
    };
}

/**
 * 建立音频下载请求
 */
-(void)HTTPDownLoadReaquest
{
    NSURL *url=[NSURL URLWithString:self.URL];
    //创建一个请求
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    self.Connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
}

/**
 * 断点请求
 */
-(void)HTTPDownLoadPoint
{
    NSURL *url=[NSURL URLWithString:_URL];
    //创建一个请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    NSString *range = [NSString stringWithFormat:@"bytes=%llu-",[self fileSizeForPath:_path]];
    [request setValue:range forHTTPHeaderField:@"Range"];
    //使用代理发送异步请求
    self.Connection = [NSURLConnection connectionWithRequest:request delegate:self];
}

/**
 * 获取文件路径
 */
- (long long)fileSizeForPath:(NSString *)path
{
    long long fileSize = 0;
    NSFileManager *fileManager = [NSFileManager new];
    if ([fileManager fileExistsAtPath:path])
    {
        NSError *error = nil;
        NSDictionary *fileDict = [fileManager attributesOfItemAtPath:path error:&error];
        if (!error && fileDict)
        {
            fileSize = [fileDict fileSize];
        }
    }
    return fileSize;
}

//- (void)deleteAllFile
//{
//    NSFileManager *fileManager = [NSFileManager defaultManager];
//    if ([fileManager fileExistsAtPath:_path]) {
//        
//        // 删除沙盒中所有资源
//        [fileManager removeItemAtPath:_path error:nil];
//    }
//}

/**
 * 取消下载
 */
-(void)cancelLoad
{
    [self.Connection cancel];
}

/**
 * 开始下载
 */
-(void)startLoad
{
    [self.Connection cancel];
    if ([self fileSizeForPath:_path] > 0)
    {
        [self HTTPDownLoadPoint];
    }
    else
    {
        [self HTTPDownLoadReaquest];
    }
    [self.Connection start];
}

/*
 *当接收到服务器的响应(连通了服务器)时会调用
 */
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    self.totalexpectedContentLength = 0;
    self.totalReceivedContentLength = 0;
    if ([self fileSizeForPath:_path] == 0)
    {
        // 创建一个用来写数据的文件句柄对象
        NSFileManager* mgr = [NSFileManager defaultManager];
        [mgr createFileAtPath:_path contents:nil attributes:nil];

    }
    self.totalReceivedContentLength = [self fileSizeForPath:_path];
    self.totalexpectedContentLength = response.expectedContentLength + [self fileSizeForPath:_path];
    self.writeHandle = [NSFileHandle fileHandleForWritingAtPath:_path];
}

/*
 *当接收到服务器的数据时会调用(可能会被调用多次,每次只传递部分数据)
 */
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    // 移动到文件的最后面
    [self.writeHandle seekToEndOfFile];
    // 将数据写入沙盒
    [self.writeHandle writeData:data];
    self.totalReceivedContentLength += data.length;
    self.progressBlock();
}

/*
 *当服务器的数据加载完毕时就会调用
 */
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [self.writeHandle closeFile];
    self.writeHandle = nil;
    self.succeedBlock();
}

/*
 *请求错误(失败)的时候调用(请求超时\断网\没有网\,一般指客户端错误)
 */
-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    self.failureBlock();
}

@end

要导入系统框架AVFoundation.framework
#import <AVFoundation/AVFoundation.h>
加入代理 AVAudioPlayerDelegate
//语音播放
@property (strong, nonatomic) AVAudioPlayer * audio;//播放器
@property (strong, nonatomic) DownLoadRequest * down;//下载器

//下面是使用方法
1.下载之前清一下缓存,并把播放器置为空;

    NSFileManager *fileManager = [NSFileManager defaultManager];
    if ([fileManager fileExistsAtPath:ZFileDownloadPath]) {
        // 删除沙盒中所有资源
        [fileManager removeItemAtPath:ZFileDownloadPath error:nil];
    }

    self.audio = nil;

2.下载文件
[self download:@"http://......"];
//演示2
-(void)download:(NSString *)urlStr
{
    self.down = nil;
    __weak typeof (self)weakself = self;
    self.down = [[DownLoadRequest alloc]initWithURL:urlStr Path:ZFileDownloadPath];
    [self.down BegindownProgress:^(long long totalReceivedContentLength, long long totalContentLength) {} Succeed:^(NSString *URL, NSString *path) {
        NSLog(@"%@",path);
        AVAudioSession *audioSession = [AVAudioSession sharedInstance];
        [audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
        [audioSession setActive:YES error:nil];
        NSURL *url = [NSURL fileURLWithPath:path];

        weakself.audio = nil;
        weakself.audio = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];
        [weakself.audio prepareToPlay];
        weakself.audio.numberOfLoops = 0;
        weakself.audio.delegate = weakself;
        weakself.audio.volume = 1;//
        weakself.audio.currentTime = 0;//可以指定从任意位置开始播放
        [weakself.audio play];
    } Failure:^{

       weakself.audio = nil;

    }];

}

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
    //播放结束时执行的动作
    。。。。。
}

转载于:https://my.oschina.net/wenchengxu123/blog/685064

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值