zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    《编程珠玑,字字珠玑》读书笔记完结篇——AVL树
    中国人,不能自卑,要自强于世界民族之林
    做饭方法
    创建一个强名称密钥文件+ 如何在 Visual C# .NET 中将程序集安装到全局程序集缓存中
    .Net 题目
    页面传值的另一种办法
    成功的12条黄金法则
    English学习资料大全
    .NET中的Serialization
    页面标签使用 实现定位
  • 原文地址:https://www.cnblogs.com/XYQ-208910/p/6685412.html
Copyright © 2011-2022 走看看