iOS:简易的音视屏播放框架XYQPlayer

一、前缀

一直都想好好学学音视频这方面的知识,抽了几个周末参考一些资料,尝试着写了一个简易的音视频播放框架,支持音视频播放、视频截图、音乐缓存,其实吧,也就是尽可能的封装罢了,方便以后自己使用。目前只是开始,可能有些不足,后续会继续优化。可以在github上下载,地址是https://github.com/xiayuanquan/XYQPlayer,当然也请多多关注本博主夏远全

概念参考我的这篇博文:http://www.cnblogs.com/XYQ-208910/p/5662655.html 

二、框架

1、截图

2、文件

XYQAllHeader.h:所有的头文件

//
//  XYQAllHeader.h
//  XYQPlayer
//
//  Created by 夏远全 on 2017/4/8.
//  Copyright © 2017年 夏远全. All rights reserved.
//

#ifndef XYQAllHeader_h
#define XYQAllHeader_h

#import "XYQAudioTool.h"
#import "XYQMovieTool.h"
#import "XYQAudioToolView.h"
#import "XYQAudioToolLoader.h"
#import "XYQHUDView.h"
#import "XYQTimeProgress.h"
#import "UIImage+XYQCornerRadius.h"

#endif /* XYQAllHeader_h */
View Code

XYQAudioTool.h/m:音频播放工具类,播放包括短音频和音乐

//
//  XYQAudioTool.m
//  XYQPlayer
//
//  Created by 夏远全 on 2017/3/7.
//  Copyright © 2017年 夏远全. All rights reserved.
//

#import "XYQAudioTool.h"
#import "XYQAudioToolLoader.h"
#import "XYQAudioToolView.h"

@implementation XYQAudioTool

/**
 音频格式转换可以使用终端的命令行进行转换,基本使用:afconvert -f [格式] -d [bundleFileName]
 具体使用可以使用help查看:afconvert -help
 afconvert: audio format convert 音频格式转换
 */


static NSMutableDictionary *_soundDict;
static NSMutableDictionary *_musicDict;
static NSMutableDictionary *_caDisplayLinkDict;
static NSString *localFileName;
static NSString *playProgressRateNotification = @"playProgressRateNotification";


//****************************************************************************************//
//***************************************播放和停止音效(时间很短)*****************************//
//****************************************************************************************//
//****************************************************************************************//

#pragma mark 初始化字典
+(void)initialize
{
    
    //存放所有的音频ID,fileName作为key,SoundID作为value
    _soundDict = [NSMutableDictionary dictionary];
    
    //存放所有的音乐播放器,fileName作为key,audioPlayer作为value
    _musicDict = [NSMutableDictionary dictionary];
    
    //存储每一首歌曲的定时器,fileName作为key,caDispalyLink作为value
    _caDisplayLinkDict = [NSMutableDictionary dictionary];
    
    //设置音频会话类型
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategorySoloAmbient error:nil];
    [session setActive:YES error:nil];
}

#pragma mark 播放音效
+(void)playSoundFromBundleFileName:(NSString *)bundleFileName
{
    //判断文件名是否为空
    if (!bundleFileName)  return;
    
    //加载音效文件(短音频)   记住:每一个音效对应一个ID
    SystemSoundID soundID = [_soundDict[bundleFileName] unsignedIntValue];
    if (!soundID) {
        NSURL *url = [[NSBundle mainBundle]URLForResource:bundleFileName withExtension:nil];
        
        if (!url) return;
        
        //创建音效sound ID
        AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &soundID);
        
        //存入字典
        [_soundDict setObject:[NSNumber numberWithUnsignedInt:soundID] forKey:bundleFileName];
        
        //使用sound ID播放
        AudioServicesPlaySystemSound(soundID);
        //AudioServicesPlayAlertSound(SystemSoundID inSystemSoundID)  //播放时手机会震动
    }
}

+(void)playSoundFromLocalFileName:(NSString *)localFileName{
    
    //判断文件名是否为空
    if (!localFileName)  return;
    
    //加载音效文件(短音频)   记住:每一个音效对应一个ID
    SystemSoundID soundID = [_soundDict[localFileName] unsignedIntValue];
    if (!soundID) {
        
        NSURL *url = [NSURL fileURLWithPath:localFileName];
        
        if (!url) return;
        
        //创建音效sound ID
        AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &soundID);
        
        //存入字典
        [_soundDict setObject:[NSNumber numberWithUnsignedInt:soundID] forKey:localFileName];
        
        //使用sound ID播放
        AudioServicesPlaySystemSound(soundID);
        //AudioServicesPlayAlertSound(SystemSoundID inSystemSoundID)  //播放时手机会震动
    }
}


#pragma mark 销毁音效
+(void)disposeSoundFromBundleFileName:(NSString *)bundleFileName
{
    
    //判断文件名是否为空
    if (!bundleFileName)  return;
    
    //从字典中取出ID
    SystemSoundID soundID = (SystemSoundID)[[_soundDict objectForKey:bundleFileName] unsignedIntValue];
    
    //释放音效资源
    if (soundID) {
        AudioServicesDisposeSystemSoundID(soundID);
        [_soundDict removeObjectForKey:bundleFileName];
    }
}

+(void)disposeSoundFromLocalFileName:(NSString *)localFileName{
    
    //判断文件名是否为空
    if (!localFileName)  return;
    
    //从字典中取出ID
    SystemSoundID soundID = (SystemSoundID)[[_soundDict objectForKey:localFileName] unsignedIntValue];
    
    //释放音效资源
    if (soundID) {
        AudioServicesDisposeSystemSoundID(soundID);
        [_soundDict removeObjectForKey:localFileName];
    }
}



//****************************************************************************************//
//**********************************播放和停止音乐(时间较长)**********************************//
//****************************************************************************************//
//****************************************************************************************//




#pragma mark 播放音乐
+(AVAudioPlayer *)playMusicFromBundleFileName:(NSString *)bundleFileName{
    
    //判断文件名是否为空
    if (!bundleFileName)  return nil;
    
    //判断文件是否为MP3格式
//    if (![bundleFileName hasSuffix:@".mp3"]) return nil;
    
    //从字典中取出播放器
    AVAudioPlayer *audioPlayer = _musicDict[bundleFileName];
    
    //从字典中取出定时器
    CADisplayLink *link = _caDisplayLinkDict[bundleFileName];
    [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
    
    if (!audioPlayer){
        //加载音乐文件
        NSError *error = nil;
        NSURL *url = [[NSBundle mainBundle]URLForResource:bundleFileName withExtension:nil];
        if (!url) return nil;
        
        //创建播放器
        audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
        
        //播放速率、音量等
        //audioPlayer.enableRate = YES;
        //audioPlayer.rate = 5.0f;
        audioPlayer.volume = 30.0f;

        if (error) return nil;
        
        //创建定时器
        if (!link) {
            link = [CADisplayLink displayLinkWithTarget:self selector:@selector(startTimer:)];
        }
        
        //将播放器存入字典中
        [_musicDict setObject:audioPlayer forKey:bundleFileName];
        
        //将定时器存入字典中
        [_caDisplayLinkDict setObject:link forKey:bundleFileName];
        
        //创建缓冲(以便后面的播放流畅)
        [audioPlayer prepareToPlay];
        
        //开始播放
        [audioPlayer play];
        [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
        playmusicCallBack([XYQAudioTool currentPlayingAudioPlayer]);
        [link setPaused:NO];
    }
    
    if (!audioPlayer.isPlaying)
    {
        //开始播放
        [audioPlayer play];
        playmusicCallBack([XYQAudioTool currentPlayingAudioPlayer]);
        [link setPaused:NO];
    }
    
    return audioPlayer;
}


+(AVAudioPlayer*)playMusicFromURLOrLocalFileName:(NSString *)URLOrLocalFileName{
    
    //判断文件名是否为空
    if (!URLOrLocalFileName)  return nil;
    
    //判断文件是否为MP3格式
//    if (![URLOrLocalFileName hasSuffix:@".mp3"]) return nil;
    
    //判断文件是否在本地存在
    if (!localFileName) {
        if ([URLOrLocalFileName hasPrefix:@"http"] || [URLOrLocalFileName hasPrefix:@"https"]) {
            localFileName = [[XYQAudioToolLoader shareToolLoader] URLFileNameIsExsitesInLocalDocument:URLOrLocalFileName];
            if (!localFileName) return nil;
        }
    }
    
    //从字典中取出播放器
    AVAudioPlayer *audioPlayer = _musicDict[URLOrLocalFileName];
    
    //从字典中取出定时器
    CADisplayLink *link = _caDisplayLinkDict[URLOrLocalFileName];
    
    if (!audioPlayer){
        
        //加载音乐文件
        NSError *error = nil;
        NSURL *url = [NSURL fileURLWithPath:localFileName];
        if (!url) return nil;
        
        //创建播放器
        audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
        
        //播放速率、音量等
        //audioPlayer.enableRate = YES;
        //audioPlayer.rate = 5.0f;
        audioPlayer.volume = 30.0f;
        
        if (error) return nil;
        
        //创建定时器
        if (!link) {
            link = [CADisplayLink displayLinkWithTarget:self selector:@selector(startTimer:)];
        }
        
        //将播放器存入字典中
        [_musicDict setObject:audioPlayer forKey:URLOrLocalFileName];
        
        //将定时器存入字典中
        [_caDisplayLinkDict setObject:link forKey:URLOrLocalFileName];
        
        //创建缓冲(以便后面的播放流畅)
        [audioPlayer prepareToPlay];
        
        //开始播放
        [audioPlayer play];
        [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
        playmusicCallBack([XYQAudioTool currentPlayingAudioPlayer]);
        [link setPaused:NO];
    }
    
    if (!audioPlayer.isPlaying)
    {
        //开始播放
        [audioPlayer play];
        playmusicCallBack([XYQAudioTool currentPlayingAudioPlayer]);
        [link setPaused:NO];
    }
    
    return audioPlayer;
}


#pragma mark 暂停音乐
+(void)pauseMusicFromBundleFileName:(NSString *)bundleFileName
{
    
    //判断文件名是否为空
    if (!bundleFileName)  return;
    
    //判断文件是否为MP3格式
//    if (![bundleFileName hasSuffix:@".mp3"]) return;
    
    //从字典中取出播放器
    AVAudioPlayer *audioPlayer = _musicDict[bundleFileName];
    
    //从字典中取出定时器
    CADisplayLink *link = _caDisplayLinkDict[bundleFileName];
    
    //暂停
    if (audioPlayer && audioPlayer.isPlaying) {
        [audioPlayer pause];
        playmusicCallBack([XYQAudioTool currentPlayingAudioPlayer]);
        [link setPaused:YES];
    }
}

+(void)pauseMusicFromURLOrLocalFileName:(NSString *)URLOrLocalFileName{
    
    //判断文件名是否为空
    if (!URLOrLocalFileName)  return;
    
    //判断文件是否为MP3格式
//    if (![URLOrLocalFileName hasSuffix:@".mp3"]) return;
    
    //从字典中取出播放器
    AVAudioPlayer *audioPlayer = _musicDict[URLOrLocalFileName];
    
    //从字典中取出定时器
    CADisplayLink *link = _caDisplayLinkDict[URLOrLocalFileName];
    
    //暂停
    if (audioPlayer && audioPlayer.isPlaying) {
        [audioPlayer pause];
        playmusicCallBack([XYQAudioTool currentPlayingAudioPlayer]);
        [link setPaused:YES];
    }
}


#pragma mark 停止音乐
+(void)stopMusicFromBundleFileName:(NSString *)bundleFileName
{
    
    //判断文件名是否为空
    if (!bundleFileName)  return;
    
    //判断文件是否为MP3格式
//    if (![bundleFileName hasSuffix:@".mp3"]) return;
    
    //从字典中取出播放器
    AVAudioPlayer *audioPlayer = _musicDict[bundleFileName];
    
    //从字典中取出定时器
    CADisplayLink *link = _caDisplayLinkDict[bundleFileName];
    
    //停止并移除播放器
    if (audioPlayer)
    {
        [audioPlayer stop];
        playmusicCallBack([XYQAudioTool currentPlayingAudioPlayer]);
        [_musicDict removeObjectForKey:bundleFileName];
        [link invalidate];
        link = nil;
        [_caDisplayLinkDict removeObjectForKey:bundleFileName];
    }
}

+(void)stopMusicFromURLOrLocalFileName:(NSString *)URLOrLocalFileName{
    
    //判断文件名是否为空
    if (!URLOrLocalFileName)  return;
    
    //判断文件是否为MP3格式
//    if (![URLOrLocalFileName hasSuffix:@".mp3"]) return;
    
    //从字典中取出播放器
    AVAudioPlayer *audioPlayer = _musicDict[URLOrLocalFileName];
    
    //从字典中取出定时器
    CADisplayLink *link = _caDisplayLinkDict[URLOrLocalFileName];
    
    //停止并移除播放器
    if (audioPlayer)
    {
        [audioPlayer stop];
        playmusicCallBack([XYQAudioTool currentPlayingAudioPlayer]);
        [_musicDict removeObjectForKey:URLOrLocalFileName];
        [link invalidate];
        link = nil;
        [_caDisplayLinkDict removeObjectForKey:URLOrLocalFileName];
    }
}


#pragma mark 返回当前进度下的播放器
+(AVAudioPlayer *)currentPlayingAudioPlayer
{
    for(NSString *fileName in _musicDict) {
        AVAudioPlayer *audioplayer = _musicDict[fileName];
        
        if (audioplayer.isPlaying) {
            return audioplayer;
        }
    }
    return nil;
}


#pragma mark - 计算总时长
+(NSTimeInterval )caluceAllDuration{
    AVAudioPlayer *audioPlayer = [self currentPlayingAudioPlayer];
    return audioPlayer.duration;
}


#pragma mark - 开启计时器,发送播放进度通知
+(void)startTimer:(CADisplayLink*)link{
    
    [[NSNotificationCenter defaultCenter] postNotificationName:playProgressRateNotification object:@{@"currentTime":@([self currentPlayingAudioPlayer].currentTime),@"totalTime":@([self currentPlayingAudioPlayer].duration)}];
}

#pragma mark - 回调播放器
+(void)waitPlayingStateCallBack:(playMusicCallBack)playMusicCallBack{
    
    if (playMusicCallBack) {
        playmusicCallBack = playMusicCallBack;
    }
}


@end
View Code

XYQAudioToolView.h/m:音频播放界面类,显示播放音乐的界面,播放、暂停、光盘旋转

//
//  XYQAudioToolView.h
//  XYQPlayer
//
//  Created by 夏远全 on 2017/3/7.
//  Copyright © 2017年 夏远全. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>

/**************************************************************************************************
                                    自定义播放音乐的界面
 ***************************************************************************************************/


@interface XYQAudioToolView : UIView
/**
 文件地址数组(可以本地文件、网络文件)
 */
@property (strong,nonatomic)NSArray *musicArr;

/**
 光盘是否隐藏
 */
@property (assign,nonatomic)BOOL diskIsHide;

/**
 打开播放器
 @param musicArr       播放文件数组
 @param viewController 播放视图所在控制器
 */
+(instancetype)openAudioPlayerView:(NSArray *)musicArr audioPlayerViewController:(UIViewController *)viewController;


/**
 关闭播放器
 */
-(void)dismissAudioPlayerView;

@end
View Code

XYQAudioToolLoader.h/m:音频下载类,缓存音乐到本地

//
//  XYQAudioToolLoader.h
//  XYQPlayer
//
//  Created by 夏远全 on 2017/3/7.
//  Copyright © 2017年 夏远全. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

/**************************************************************************************************
                        从网络上缓冲下载音乐文件,然后存储到本地
 ***************************************************************************************************/

@interface XYQAudioToolLoader : NSObject

/**
 进度率
 */
@property (assign,nonatomic)CGFloat progressRate;

/**
 类方法创建实例
 */
+ (instancetype)shareToolLoader;

/**
 判断该网络文件是否在本地存在,如果存在直接返回本地文件,否则存到本地后再返回
 @return 返回本地文件路径
 */
- (NSString *)URLFileNameIsExsitesInLocalDocument:(NSString *)URLFileName;


/**
 执行下载任务
 @param URLFileName 文件URL
 */
- (void)excuteLoadMusic:(NSString *)URLFileName;

@end
View Code

XYQMovieTool.h/m:视频播放工具类,直接显示播放界面、还有截屏功能

//
//  XYQMovieToolView.h
//  XYQPlayer
//
//  Created by 夏远全 on 2017/4/9.
//  Copyright © 2017年 夏远全. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

/**************************************************************************************************
                              播放本地和网络视屏
 其实MPMoviePlayerController如果不作为嵌入视频来播放(例如在新闻中嵌入一个视频),通常在播放时都是占满一个屏幕的,特别是在iPhone、
 iTouch上。
 因此从iOS3.2以后苹果也在思考既然MPMoviePlayerController在使用时通常都是将其视图view添加到另外一个视图控制器中作为子视
 图,那么何不直接创建一个控制器视图内部创建一个MPMoviePlayerController属性并且默认全屏播放,开发者在开发的时候直接使用这个视图控
 器。
 这个内部有一个MPMoviePlayerController的视图控制器就是MPMoviePlayerViewController,它继承于UIViewController。
 MPMoviePlayerViewController内部多了一个moviePlayer属性和一个带有url的初始化方法,同时它内部实现了一些作为模态视图展示所特有的
 功
 能,例如默认是全屏模式展示、弹出后自动播放、作为模态窗口展示时如果点击“Done”按钮会自动退出模态窗口等。在下面的示例中就不直接将播放器
 放到主视图控制器,而是放到一个模态视图控制器中。
 ***************************************************************************************************/



@interface XYQMovieTool : NSObject


/**
 播放本地视频

 @param localURL    本地视频url
 @param containViewController 播放容器
 */
+(void)pushPlayMovieWithLocalURL:(NSString *)localURL viewController:(UIViewController *)containViewController;

/**
 播放网络视频
 
 @param netWorkURL  网络视频url
 @param containViewController 播放容器
 */
+(void)pushPlayMovieWithNetURL:(NSString *)netWorkURL viewController:(UIViewController *)containViewController;

/**
 播放本地视频
 
 @param localURL    本地视频url
 @param containViewController 播放容器
 */
+(void)presentPlayMovieWithLocalURL:(NSString *)localURL viewController:(UIViewController *)containViewController;

/**
 播放网络视频
 
 @param netWorkURL  网络视频url
 @param containViewController 播放容器
 */
+(void)presentPlayMovieWithNetURL:(NSString *)netWorkURL viewController:(UIViewController *)containViewController;


/**
 获取视频截图,此处必须先播放才能截图
 @param timesArr 时间帧数组,单位秒(s)
 */
+(void)thumbnailImageRequestWithTimes:(NSArray *)timesArr;

/**
 取消播放
 */
+(void)cancelPlay;

@end
View Code

XYQCachesManager.h/.m:缓存管理类,计算缓存大小、清除缓存

//
//  XYQCachesManager.h
//  XYQPlayer
//
//  Created by 夏远全 on 2017/4/22.
//  Copyright © 2017年 夏远全. All rights reserved.
//

#import <Foundation/Foundation.h>

/**************************************************************************************************
                        缓存管理类:计算缓存大小、清理缓存
 ***************************************************************************************************/

@interface XYQCachesManager : NSObject

/**
 文件路径数组
 */
@property (strong,nonatomic)NSArray *filePaths;


/**
 是否存在缓存
 */
@property (assign,nonatomic)BOOL    isExisitCaches;

/**
 单例
 */
+ (instancetype)sharedXYQCachesManager;

/**
 沙盒根目录
 @return 根目录
 */
+ (NSString *)documentsLastPath;


/**
 保存文件到指定路径下
 @param fromURL 初始文件的路径
 @param toURL   指定保存的路径
 @return 保存状态
 */
+ (NSError *)writeFileFromURL:(NSURL *)fromURL toURL:(NSURL *)toURL;


/**
 计算单个文件的大小
 @param filePath 文件路径
 @return 缓存大小
 */
+ (float)fileSizeAtPath:(NSString*) filePath;


/**
 计算遍历文件夹获得文件夹大小
 @param folderPath 文件夹路径
 @return 缓存大小
 */
+ (float)folderSizeAtPath:(NSString*) folderPath;


/**
 清除文件缓存
 */
+ (void)clearFileCaches;

@end



//
//  XYQCachesManager.m
//  XYQPlayer
//
//  Created by 夏远全 on 2017/4/22.
//  Copyright © 2017年 夏远全. All rights reserved.
//

#import "XYQCachesManager.h"
#import "XYQHUDView.h"

@implementation XYQCachesManager

static XYQCachesManager *_sharedCachesManager = nil;

+ (instancetype)sharedXYQCachesManager {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _sharedCachesManager = [[self alloc] init];
    });
    return _sharedCachesManager;
}

#pragma mark - 获取沙盒目录
+ (NSString *)documentsLastPath{
    return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}

#pragma mark - 保存文件
+ (NSError *)writeFileFromURL:(NSURL *)fromURL toURL:(NSURL *)toURL{
    
    NSError *error = nil;
    [[NSFileManager defaultManager] moveItemAtURL:fromURL toURL:toURL error:&error];
    return error;
}

#pragma mark - 清除文件缓存
+ (void)clearFileCaches{

    //遍历缓存文件
    __block float fileSize = 0;
    NSArray *tempFileList = [[NSArray alloc] initWithArray:[[NSFileManager defaultManager] contentsOfDirectoryAtPath:[self documentsLastPath] error:nil]];
    XYQCachesManager *xyaCachesManager = [XYQCachesManager sharedXYQCachesManager];
    [xyaCachesManager.filePaths enumerateObjectsUsingBlock:^(NSString *URLFileName, NSUInteger idx, BOOL * _Nonnull stop) {
        NSString *URLFileNameLast = [URLFileName componentsSeparatedByString:@"/"].lastObject;
        [tempFileList enumerateObjectsUsingBlock:^(NSString *fileName, NSUInteger idx, BOOL * _Nonnull stop)
         {
             if ([URLFileNameLast isEqualToString:fileName]) {
                 NSString *filePath = [[XYQCachesManager documentsLastPath] stringByAppendingPathComponent:URLFileNameLast];
                 fileSize += [self fileSizeAtPath:filePath];
                 [[NSFileManager defaultManager]  removeItemAtPath:filePath error:nil];
             }
         }];
        if (idx == xyaCachesManager.filePaths.count-1) {
            [XYQHUDView showBigHud:[NSString stringWithFormat:@"清除缓存%.1fM",fileSize]];
        }
    }];
}



#pragma mark - 通常用于删除缓存的时,计算缓存大小
//单个文件的大小
+ (float) fileSizeAtPath:(NSString*) filePath{
    NSFileManager* manager = [NSFileManager defaultManager];
    if ([manager fileExistsAtPath:filePath]){
        return [[manager attributesOfItemAtPath:filePath error:nil] fileSize]/(1024.0*1024.0);
    }
    return 0;
}

//遍历文件夹获得文件夹大小,返回多少M
+ (float ) folderSizeAtPath:(NSString*) folderPath{
    NSFileManager* manager = [NSFileManager defaultManager];
    if (![manager fileExistsAtPath:folderPath]) return 0;
    NSEnumerator *childFilesEnumerator = [[manager subpathsAtPath:folderPath] objectEnumerator];
    NSString* fileName;
    long long folderSize = 0;
    while ((fileName = [childFilesEnumerator nextObject]) != nil){
        NSString* fileAbsolutePath = [folderPath stringByAppendingPathComponent:fileName];
        folderSize += [self fileSizeAtPath:fileAbsolutePath];
    }
    return folderSize/(1024.0*1024.0);
}

@end
View Code

XYQHUDView.h/m:弹框提示,包括文本提示、下载进度提示

//
//  XYQHUDView.h
//  XYQPlayer
//
//  Created by 夏远全 on 2017/3/9.
//  Copyright © 2017年 夏远全. All rights reserved.
//

#import <UIKit/UIKit.h>

/**************************************************************************************************
                            自定义消息弹出框:单纯的文本弹框、加载动画弹框
 ***************************************************************************************************/

@interface XYQHUDView : UILabel

/**
 显示文本提示框

 @param message 消息
 */
+(void)showHud:(NSString *)message;



/**
 显示进度提示框

 @param progress 进度百分比
 @param view     容器
 */
+(void)showHudWithProgress:(CGFloat)progress inView:(UIView *)view;

/**
 刷新进度

 @param progress 进度百分比
 */
+(void)updateHudProgress:(CGFloat)progress;


/**
 隐藏提示框
 */
+(void)hideHud;

@end
View Code

XYQTimeProgress.h/m:音乐播放时间进度条

//
//  XYQProgress.h
//  XYQPlayer
//
//  Created by 夏远全 on 2017/4/7.
//  Copyright © 2017年 夏远全. All rights reserved.
//

#import <UIKit/UIKit.h>

/**************************************************************************************************
                                            自定义时间进度条
 ***************************************************************************************************/

@interface XYQTimeProgress : UIView
/**
 进度起始值
 */
@property (assign,nonatomic)NSTimeInterval startValue;
/**
 进度终点值
 */
@property (assign,nonatomic)NSTimeInterval endValue;
/**
 进度率
 */
@property (assign,nonatomic)CGFloat progressRate;


/**
 创建进度条

 @param frame         尺寸
 @param startValue    起始值
 @param endValue      终点值

 */
+(instancetype)createProgressWithFrame:(CGRect)frame StartValue:(NSTimeInterval)startValue  endValue:(NSTimeInterval)endValue;
+(instancetype)createProgressWithStartValue:(NSTimeInterval)startValue  endValue:(NSTimeInterval)endValue;

@end
View Code

UIImage+XYQCornerRadius.h/m:对图片进行处理的类

//
//  UIImage+XYQCornerRadius.h
//  XYQPlayer
//
//  Created by 夏远全 on 2017/3/8.
//  Copyright © 2017年 夏远全. All rights reserved.
//

#import <UIKit/UIKit.h>

/**************************************************************************************************
                                     切割圆角图片、旋转动画
 ***************************************************************************************************/

@interface UIImage (XYQCornerRadius)

/**
 圆角图片

 @param image 原始图片
 @param size  尺寸
 @param r     半径
 */
+ (UIImage *)createRoundedRectImage:(UIImage*)image size:(CGSize)size radius:(NSInteger)r;


/**
 开始旋转
 @param rotationView 旋转视图
 */
+ (void)startRotation:(UIImageView *)rotationView;

/**
 暂停动画
 @param layer 旋转视图layer
 */
+ (void)pauseAnimation:(CALayer *)layer;

@end
View Code

Source.bundle:资源包,存放图片icon

3、依赖

 

 

三、音乐播放和缓存逻辑

 

 

四、视频播放方式

 

五、音频播放test

#import "PlayMusicViewController.h"
#import "XYQAllHeader.h"

@interface PlayMusicViewController ()
@property (strong,nonatomic)XYQAudioToolView *audioPlayerView;
@end

@implementation PlayMusicViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"清除缓存" style:UIBarButtonItemStylePlain target:self action:@selector(clearCache)];
//1、网络音乐(此处需要给出准确的url,我的这个不可以用,只是给个参考的样式)
    //[self testPlay_Local_URL_Music:@[@"http://120.25.226.186:32812/xxx/minion_02.mp3"]];
    
    //2、本地音乐
    [self testPlay_Bundle_Music:[self musicArray]];
}

//测试创建音乐播放器(播放沙盒本地音乐包括从网络音乐下载缓存)
- (void)testPlay_Local_URL_Music:(NSArray *)musicFileLinkArray{
    
    self.audioPlayerView = [XYQAudioToolView openAudioPlayerView:musicFileLinkArray  audioPlayerViewController:self];
    self.audioPlayerView.diskIsHide = YES;
}


//测试创建音乐播放器(播放bundle根目录下的音乐)
- (void)testPlay_Bundle_Music:(NSArray *)musicNameArray{
    
    self.audioPlayerView = [XYQAudioToolView openAudioPlayerView:musicNameArray  audioPlayerViewController:self];
    self.audioPlayerView.diskIsHide = YES;
}

//Bundle根目录子下所有的音乐文件名
- (NSArray *)musicArray{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"Musics" ofType:@"plist"];
    NSArray *musicNameArr = [NSArray arrayWithContentsOfFile:path];
    return musicNameArr;
}

  //清除缓存

   - (void)clearCache{

    [XYQCachesManager clearFileCaches];

  }

//关闭播放器
-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [self.audioPlayerView dismissAudioPlayerView];
}

 

六、视频播放test

//
//  PlayMovieViewController.m
//  XYQPlayer
//
//  Created by 夏远全 on 2017/4/9.
//  Copyright © 2017年 夏远全. All rights reserved.
//

#import "PlayMovieViewController.h"
#import "XYQAllHeader.h"

@interface PlayMovieViewController ()

@end

@implementation PlayMovieViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    
    //1、push视频
    [XYQMovieTool pushPlayMovieWithNetURL:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4" viewController:self];
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    //2、present视频
    //[XYQMovieTool presentPlayMovieWithNetURL:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4" viewController:self];
}

//关闭播放器
-(void)viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [XYQMovieTool cancelPlay];
}

@end

 

七、演示截图

 音乐:

   

 

视频:

push:             present:  

  

 

八、cocoaPods支持:

pod search 'XYQPlayer'

 

九、声明

本博文为原创,如转载请注明出处,希望对大家有所帮助~~~~

cnblogs地址:http://www.cnblogs.com/XYQ-208910/p/6685412.html

github地址:https://github.com/xiayuanquan/XYQPlayer

简书地址:http://www.jianshu.com/p/1f8f434cfcba

 

posted @ 2017-04-09 16:49  XYQ全哥  阅读(1093)  评论(0编辑  收藏  举报