一、前缀

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

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

二、框架

1、截图

2、文件

XYQAllHeader.h:所有的头文件

  1. //
  2. // XYQAllHeader.h
  3. // XYQPlayer
  4. //
  5. // Created by 夏远全 on 2017/4/8.
  6. // Copyright © 2017年 夏远全. All rights reserved.
  7. //
  8.  
  9. #ifndef XYQAllHeader_h
  10. #define XYQAllHeader_h
  11.  
  12. #import "XYQAudioTool.h"
  13. #import "XYQMovieTool.h"
  14. #import "XYQAudioToolView.h"
  15. #import "XYQAudioToolLoader.h"
  16. #import "XYQHUDView.h"
  17. #import "XYQTimeProgress.h"
  18. #import "UIImage+XYQCornerRadius.h"
  19.  
  20. #endif /* XYQAllHeader_h */

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

  1. //
  2. // XYQAudioTool.m
  3. // XYQPlayer
  4. //
  5. // Created by 夏远全 on 2017/3/7.
  6. // Copyright © 2017年 夏远全. All rights reserved.
  7. //
  8.  
  9. #import "XYQAudioTool.h"
  10. #import "XYQAudioToolLoader.h"
  11. #import "XYQAudioToolView.h"
  12.  
  13. @implementation XYQAudioTool
  14.  
  15. /**
  16. 音频格式转换可以使用终端的命令行进行转换,基本使用:afconvert -f [格式] -d [bundleFileName]
  17. 具体使用可以使用help查看:afconvert -help
  18. afconvert: audio format convert 音频格式转换
  19. */
  20.  
  21. static NSMutableDictionary *_soundDict;
  22. static NSMutableDictionary *_musicDict;
  23. static NSMutableDictionary *_caDisplayLinkDict;
  24. static NSString *localFileName;
  25. static NSString *playProgressRateNotification = @"playProgressRateNotification";
  26.  
  27. //****************************************************************************************//
  28. //***************************************播放和停止音效(时间很短)*****************************//
  29. //****************************************************************************************//
  30. //****************************************************************************************//
  31.  
  32. #pragma mark 初始化字典
  33. +(void)initialize
  34. {
  35.  
  36. //存放所有的音频ID,fileName作为key,SoundID作为value
  37. _soundDict = [NSMutableDictionary dictionary];
  38.  
  39. //存放所有的音乐播放器,fileName作为key,audioPlayer作为value
  40. _musicDict = [NSMutableDictionary dictionary];
  41.  
  42. //存储每一首歌曲的定时器,fileName作为key,caDispalyLink作为value
  43. _caDisplayLinkDict = [NSMutableDictionary dictionary];
  44.  
  45. //设置音频会话类型
  46. AVAudioSession *session = [AVAudioSession sharedInstance];
  47. [session setCategory:AVAudioSessionCategorySoloAmbient error:nil];
  48. [session setActive:YES error:nil];
  49. }
  50.  
  51. #pragma mark 播放音效
  52. +(void)playSoundFromBundleFileName:(NSString *)bundleFileName
  53. {
  54. //判断文件名是否为空
  55. if (!bundleFileName) return;
  56.  
  57. //加载音效文件(短音频) 记住:每一个音效对应一个ID
  58. SystemSoundID soundID = [_soundDict[bundleFileName] unsignedIntValue];
  59. if (!soundID) {
  60. NSURL *url = [[NSBundle mainBundle]URLForResource:bundleFileName withExtension:nil];
  61.  
  62. if (!url) return;
  63.  
  64. //创建音效sound ID
  65. AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &soundID);
  66.  
  67. //存入字典
  68. [_soundDict setObject:[NSNumber numberWithUnsignedInt:soundID] forKey:bundleFileName];
  69.  
  70. //使用sound ID播放
  71. AudioServicesPlaySystemSound(soundID);
  72. //AudioServicesPlayAlertSound(SystemSoundID inSystemSoundID) //播放时手机会震动
  73. }
  74. }
  75.  
  76. +(void)playSoundFromLocalFileName:(NSString *)localFileName{
  77.  
  78. //判断文件名是否为空
  79. if (!localFileName) return;
  80.  
  81. //加载音效文件(短音频) 记住:每一个音效对应一个ID
  82. SystemSoundID soundID = [_soundDict[localFileName] unsignedIntValue];
  83. if (!soundID) {
  84.  
  85. NSURL *url = [NSURL fileURLWithPath:localFileName];
  86.  
  87. if (!url) return;
  88.  
  89. //创建音效sound ID
  90. AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &soundID);
  91.  
  92. //存入字典
  93. [_soundDict setObject:[NSNumber numberWithUnsignedInt:soundID] forKey:localFileName];
  94.  
  95. //使用sound ID播放
  96. AudioServicesPlaySystemSound(soundID);
  97. //AudioServicesPlayAlertSound(SystemSoundID inSystemSoundID) //播放时手机会震动
  98. }
  99. }
  100.  
  101. #pragma mark 销毁音效
  102. +(void)disposeSoundFromBundleFileName:(NSString *)bundleFileName
  103. {
  104.  
  105. //判断文件名是否为空
  106. if (!bundleFileName) return;
  107.  
  108. //从字典中取出ID
  109. SystemSoundID soundID = (SystemSoundID)[[_soundDict objectForKey:bundleFileName] unsignedIntValue];
  110.  
  111. //释放音效资源
  112. if (soundID) {
  113. AudioServicesDisposeSystemSoundID(soundID);
  114. [_soundDict removeObjectForKey:bundleFileName];
  115. }
  116. }
  117.  
  118. +(void)disposeSoundFromLocalFileName:(NSString *)localFileName{
  119.  
  120. //判断文件名是否为空
  121. if (!localFileName) return;
  122.  
  123. //从字典中取出ID
  124. SystemSoundID soundID = (SystemSoundID)[[_soundDict objectForKey:localFileName] unsignedIntValue];
  125.  
  126. //释放音效资源
  127. if (soundID) {
  128. AudioServicesDisposeSystemSoundID(soundID);
  129. [_soundDict removeObjectForKey:localFileName];
  130. }
  131. }
  132.  
  133. //****************************************************************************************//
  134. //**********************************播放和停止音乐(时间较长)**********************************//
  135. //****************************************************************************************//
  136. //****************************************************************************************//
  137.  
  138. #pragma mark 播放音乐
  139. +(AVAudioPlayer *)playMusicFromBundleFileName:(NSString *)bundleFileName{
  140.  
  141. //判断文件名是否为空
  142. if (!bundleFileName) return nil;
  143.  
  144. //判断文件是否为MP3格式
  145. // if (![bundleFileName hasSuffix:@".mp3"]) return nil;
  146.  
  147. //从字典中取出播放器
  148. AVAudioPlayer *audioPlayer = _musicDict[bundleFileName];
  149.  
  150. //从字典中取出定时器
  151. CADisplayLink *link = _caDisplayLinkDict[bundleFileName];
  152. [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
  153.  
  154. if (!audioPlayer){
  155. //加载音乐文件
  156. NSError *error = nil;
  157. NSURL *url = [[NSBundle mainBundle]URLForResource:bundleFileName withExtension:nil];
  158. if (!url) return nil;
  159.  
  160. //创建播放器
  161. audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
  162.  
  163. //播放速率、音量等
  164. //audioPlayer.enableRate = YES;
  165. //audioPlayer.rate = 5.0f;
  166. audioPlayer.volume = 30.0f;
  167.  
  168. if (error) return nil;
  169.  
  170. //创建定时器
  171. if (!link) {
  172. link = [CADisplayLink displayLinkWithTarget:self selector:@selector(startTimer:)];
  173. }
  174.  
  175. //将播放器存入字典中
  176. [_musicDict setObject:audioPlayer forKey:bundleFileName];
  177.  
  178. //将定时器存入字典中
  179. [_caDisplayLinkDict setObject:link forKey:bundleFileName];
  180.  
  181. //创建缓冲(以便后面的播放流畅)
  182. [audioPlayer prepareToPlay];
  183.  
  184. //开始播放
  185. [audioPlayer play];
  186. [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
  187. playmusicCallBack([XYQAudioTool currentPlayingAudioPlayer]);
  188. [link setPaused:NO];
  189. }
  190.  
  191. if (!audioPlayer.isPlaying)
  192. {
  193. //开始播放
  194. [audioPlayer play];
  195. playmusicCallBack([XYQAudioTool currentPlayingAudioPlayer]);
  196. [link setPaused:NO];
  197. }
  198.  
  199. return audioPlayer;
  200. }
  201.  
  202. +(AVAudioPlayer*)playMusicFromURLOrLocalFileName:(NSString *)URLOrLocalFileName{
  203.  
  204. //判断文件名是否为空
  205. if (!URLOrLocalFileName) return nil;
  206.  
  207. //判断文件是否为MP3格式
  208. // if (![URLOrLocalFileName hasSuffix:@".mp3"]) return nil;
  209.  
  210. //判断文件是否在本地存在
  211. if (!localFileName) {
  212. if ([URLOrLocalFileName hasPrefix:@"http"] || [URLOrLocalFileName hasPrefix:@"https"]) {
  213. localFileName = [[XYQAudioToolLoader shareToolLoader] URLFileNameIsExsitesInLocalDocument:URLOrLocalFileName];
  214. if (!localFileName) return nil;
  215. }
  216. }
  217.  
  218. //从字典中取出播放器
  219. AVAudioPlayer *audioPlayer = _musicDict[URLOrLocalFileName];
  220.  
  221. //从字典中取出定时器
  222. CADisplayLink *link = _caDisplayLinkDict[URLOrLocalFileName];
  223.  
  224. if (!audioPlayer){
  225.  
  226. //加载音乐文件
  227. NSError *error = nil;
  228. NSURL *url = [NSURL fileURLWithPath:localFileName];
  229. if (!url) return nil;
  230.  
  231. //创建播放器
  232. audioPlayer = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
  233.  
  234. //播放速率、音量等
  235. //audioPlayer.enableRate = YES;
  236. //audioPlayer.rate = 5.0f;
  237. audioPlayer.volume = 30.0f;
  238.  
  239. if (error) return nil;
  240.  
  241. //创建定时器
  242. if (!link) {
  243. link = [CADisplayLink displayLinkWithTarget:self selector:@selector(startTimer:)];
  244. }
  245.  
  246. //将播放器存入字典中
  247. [_musicDict setObject:audioPlayer forKey:URLOrLocalFileName];
  248.  
  249. //将定时器存入字典中
  250. [_caDisplayLinkDict setObject:link forKey:URLOrLocalFileName];
  251.  
  252. //创建缓冲(以便后面的播放流畅)
  253. [audioPlayer prepareToPlay];
  254.  
  255. //开始播放
  256. [audioPlayer play];
  257. [link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
  258. playmusicCallBack([XYQAudioTool currentPlayingAudioPlayer]);
  259. [link setPaused:NO];
  260. }
  261.  
  262. if (!audioPlayer.isPlaying)
  263. {
  264. //开始播放
  265. [audioPlayer play];
  266. playmusicCallBack([XYQAudioTool currentPlayingAudioPlayer]);
  267. [link setPaused:NO];
  268. }
  269.  
  270. return audioPlayer;
  271. }
  272.  
  273. #pragma mark 暂停音乐
  274. +(void)pauseMusicFromBundleFileName:(NSString *)bundleFileName
  275. {
  276.  
  277. //判断文件名是否为空
  278. if (!bundleFileName) return;
  279.  
  280. //判断文件是否为MP3格式
  281. // if (![bundleFileName hasSuffix:@".mp3"]) return;
  282.  
  283. //从字典中取出播放器
  284. AVAudioPlayer *audioPlayer = _musicDict[bundleFileName];
  285.  
  286. //从字典中取出定时器
  287. CADisplayLink *link = _caDisplayLinkDict[bundleFileName];
  288.  
  289. //暂停
  290. if (audioPlayer && audioPlayer.isPlaying) {
  291. [audioPlayer pause];
  292. playmusicCallBack([XYQAudioTool currentPlayingAudioPlayer]);
  293. [link setPaused:YES];
  294. }
  295. }
  296.  
  297. +(void)pauseMusicFromURLOrLocalFileName:(NSString *)URLOrLocalFileName{
  298.  
  299. //判断文件名是否为空
  300. if (!URLOrLocalFileName) return;
  301.  
  302. //判断文件是否为MP3格式
  303. // if (![URLOrLocalFileName hasSuffix:@".mp3"]) return;
  304.  
  305. //从字典中取出播放器
  306. AVAudioPlayer *audioPlayer = _musicDict[URLOrLocalFileName];
  307.  
  308. //从字典中取出定时器
  309. CADisplayLink *link = _caDisplayLinkDict[URLOrLocalFileName];
  310.  
  311. //暂停
  312. if (audioPlayer && audioPlayer.isPlaying) {
  313. [audioPlayer pause];
  314. playmusicCallBack([XYQAudioTool currentPlayingAudioPlayer]);
  315. [link setPaused:YES];
  316. }
  317. }
  318.  
  319. #pragma mark 停止音乐
  320. +(void)stopMusicFromBundleFileName:(NSString *)bundleFileName
  321. {
  322.  
  323. //判断文件名是否为空
  324. if (!bundleFileName) return;
  325.  
  326. //判断文件是否为MP3格式
  327. // if (![bundleFileName hasSuffix:@".mp3"]) return;
  328.  
  329. //从字典中取出播放器
  330. AVAudioPlayer *audioPlayer = _musicDict[bundleFileName];
  331.  
  332. //从字典中取出定时器
  333. CADisplayLink *link = _caDisplayLinkDict[bundleFileName];
  334.  
  335. //停止并移除播放器
  336. if (audioPlayer)
  337. {
  338. [audioPlayer stop];
  339. playmusicCallBack([XYQAudioTool currentPlayingAudioPlayer]);
  340. [_musicDict removeObjectForKey:bundleFileName];
  341. [link invalidate];
  342. link = nil;
  343. [_caDisplayLinkDict removeObjectForKey:bundleFileName];
  344. }
  345. }
  346.  
  347. +(void)stopMusicFromURLOrLocalFileName:(NSString *)URLOrLocalFileName{
  348.  
  349. //判断文件名是否为空
  350. if (!URLOrLocalFileName) return;
  351.  
  352. //判断文件是否为MP3格式
  353. // if (![URLOrLocalFileName hasSuffix:@".mp3"]) return;
  354.  
  355. //从字典中取出播放器
  356. AVAudioPlayer *audioPlayer = _musicDict[URLOrLocalFileName];
  357.  
  358. //从字典中取出定时器
  359. CADisplayLink *link = _caDisplayLinkDict[URLOrLocalFileName];
  360.  
  361. //停止并移除播放器
  362. if (audioPlayer)
  363. {
  364. [audioPlayer stop];
  365. playmusicCallBack([XYQAudioTool currentPlayingAudioPlayer]);
  366. [_musicDict removeObjectForKey:URLOrLocalFileName];
  367. [link invalidate];
  368. link = nil;
  369. [_caDisplayLinkDict removeObjectForKey:URLOrLocalFileName];
  370. }
  371. }
  372.  
  373. #pragma mark 返回当前进度下的播放器
  374. +(AVAudioPlayer *)currentPlayingAudioPlayer
  375. {
  376. for(NSString *fileName in _musicDict) {
  377. AVAudioPlayer *audioplayer = _musicDict[fileName];
  378.  
  379. if (audioplayer.isPlaying) {
  380. return audioplayer;
  381. }
  382. }
  383. return nil;
  384. }
  385.  
  386. #pragma mark - 计算总时长
  387. +(NSTimeInterval )caluceAllDuration{
  388. AVAudioPlayer *audioPlayer = [self currentPlayingAudioPlayer];
  389. return audioPlayer.duration;
  390. }
  391.  
  392. #pragma mark - 开启计时器,发送播放进度通知
  393. +(void)startTimer:(CADisplayLink*)link{
  394.  
  395. [[NSNotificationCenter defaultCenter] postNotificationName:playProgressRateNotification object:@{@"currentTime":@([self currentPlayingAudioPlayer].currentTime),@"totalTime":@([self currentPlayingAudioPlayer].duration)}];
  396. }
  397.  
  398. #pragma mark - 回调播放器
  399. +(void)waitPlayingStateCallBack:(playMusicCallBack)playMusicCallBack{
  400.  
  401. if (playMusicCallBack) {
  402. playmusicCallBack = playMusicCallBack;
  403. }
  404. }
  405.  
  406. @end

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

  1. //
  2. // XYQAudioToolView.h
  3. // XYQPlayer
  4. //
  5. // Created by 夏远全 on 2017/3/7.
  6. // Copyright © 2017年 夏远全. All rights reserved.
  7. //
  8.  
  9. #import <UIKit/UIKit.h>
  10. #import <Foundation/Foundation.h>
  11.  
  12. /**************************************************************************************************
  13. 自定义播放音乐的界面
  14. ***************************************************************************************************/
  15.  
  16. @interface XYQAudioToolView : UIView
  17. /**
  18. 文件地址数组(可以本地文件、网络文件)
  19. */
  20. @property (strong,nonatomic)NSArray *musicArr;
  21.  
  22. /**
  23. 光盘是否隐藏
  24. */
  25. @property (assign,nonatomic)BOOL diskIsHide;
  26.  
  27. /**
  28. 打开播放器
  29. @param musicArr 播放文件数组
  30. @param viewController 播放视图所在控制器
  31. */
  32. +(instancetype)openAudioPlayerView:(NSArray *)musicArr audioPlayerViewController:(UIViewController *)viewController;
  33.  
  34. /**
  35. 关闭播放器
  36. */
  37. -(void)dismissAudioPlayerView;
  38.  
  39. @end

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

  1. //
  2. // XYQAudioToolLoader.h
  3. // XYQPlayer
  4. //
  5. // Created by 夏远全 on 2017/3/7.
  6. // Copyright © 2017年 夏远全. All rights reserved.
  7. //
  8.  
  9. #import <Foundation/Foundation.h>
  10. #import <UIKit/UIKit.h>
  11.  
  12. /**************************************************************************************************
  13. 从网络上缓冲下载音乐文件,然后存储到本地
  14. ***************************************************************************************************/
  15.  
  16. @interface XYQAudioToolLoader : NSObject
  17.  
  18. /**
  19. 进度率
  20. */
  21. @property (assign,nonatomic)CGFloat progressRate;
  22.  
  23. /**
  24. 类方法创建实例
  25. */
  26. + (instancetype)shareToolLoader;
  27.  
  28. /**
  29. 判断该网络文件是否在本地存在,如果存在直接返回本地文件,否则存到本地后再返回
  30. @return 返回本地文件路径
  31. */
  32. - (NSString *)URLFileNameIsExsitesInLocalDocument:(NSString *)URLFileName;
  33.  
  34. /**
  35. 执行下载任务
  36. @param URLFileName 文件URL
  37. */
  38. - (void)excuteLoadMusic:(NSString *)URLFileName;
  39.  
  40. @end

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

  1. //
  2. // XYQMovieToolView.h
  3. // XYQPlayer
  4. //
  5. // Created by 夏远全 on 2017/4/9.
  6. // Copyright © 2017年 夏远全. All rights reserved.
  7. //
  8.  
  9. #import <Foundation/Foundation.h>
  10. #import <UIKit/UIKit.h>
  11.  
  12. /**************************************************************************************************
  13. 播放本地和网络视屏
  14. 其实MPMoviePlayerController如果不作为嵌入视频来播放(例如在新闻中嵌入一个视频),通常在播放时都是占满一个屏幕的,特别是在iPhone、
  15. iTouch上。
  16. 因此从iOS3.2以后苹果也在思考既然MPMoviePlayerController在使用时通常都是将其视图view添加到另外一个视图控制器中作为子视
  17. 图,那么何不直接创建一个控制器视图内部创建一个MPMoviePlayerController属性并且默认全屏播放,开发者在开发的时候直接使用这个视图控
  18. 器。
  19. 这个内部有一个MPMoviePlayerController的视图控制器就是MPMoviePlayerViewController,它继承于UIViewController。
  20. MPMoviePlayerViewController内部多了一个moviePlayer属性和一个带有url的初始化方法,同时它内部实现了一些作为模态视图展示所特有的

  21. 能,例如默认是全屏模式展示、弹出后自动播放、作为模态窗口展示时如果点击“Done”按钮会自动退出模态窗口等。在下面的示例中就不直接将播放器
  22. 放到主视图控制器,而是放到一个模态视图控制器中。
  23. ***************************************************************************************************/
  24.  
  25. @interface XYQMovieTool : NSObject
  26.  
  27. /**
  28. 播放本地视频
  29.  
  30. @param localURL 本地视频url
  31. @param containViewController 播放容器
  32. */
  33. +(void)pushPlayMovieWithLocalURL:(NSString *)localURL viewController:(UIViewController *)containViewController;
  34.  
  35. /**
  36. 播放网络视频
  37.  
  38. @param netWorkURL 网络视频url
  39. @param containViewController 播放容器
  40. */
  41. +(void)pushPlayMovieWithNetURL:(NSString *)netWorkURL viewController:(UIViewController *)containViewController;
  42.  
  43. /**
  44. 播放本地视频
  45.  
  46. @param localURL 本地视频url
  47. @param containViewController 播放容器
  48. */
  49. +(void)presentPlayMovieWithLocalURL:(NSString *)localURL viewController:(UIViewController *)containViewController;
  50.  
  51. /**
  52. 播放网络视频
  53.  
  54. @param netWorkURL 网络视频url
  55. @param containViewController 播放容器
  56. */
  57. +(void)presentPlayMovieWithNetURL:(NSString *)netWorkURL viewController:(UIViewController *)containViewController;
  58.  
  59. /**
  60. 获取视频截图,此处必须先播放才能截图
  61. @param timesArr 时间帧数组,单位秒(s)
  62. */
  63. +(void)thumbnailImageRequestWithTimes:(NSArray *)timesArr;
  64.  
  65. /**
  66. 取消播放
  67. */
  68. +(void)cancelPlay;
  69.  
  70. @end

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

  1. //
  2. // XYQCachesManager.h
  3. // XYQPlayer
  4. //
  5. // Created by 夏远全 on 2017/4/22.
  6. // Copyright © 2017年 夏远全. All rights reserved.
  7. //
  8.  
  9. #import <Foundation/Foundation.h>
  10.  
  11. /**************************************************************************************************
  12. 缓存管理类:计算缓存大小、清理缓存
  13. ***************************************************************************************************/
  14.  
  15. @interface XYQCachesManager : NSObject
  16.  
  17. /**
  18. 文件路径数组
  19. */
  20. @property (strong,nonatomic)NSArray *filePaths;
  21.  
  22. /**
  23. 是否存在缓存
  24. */
  25. @property (assign,nonatomic)BOOL isExisitCaches;
  26.  
  27. /**
  28. 单例
  29. */
  30. + (instancetype)sharedXYQCachesManager;
  31.  
  32. /**
  33. 沙盒根目录
  34. @return 根目录
  35. */
  36. + (NSString *)documentsLastPath;
  37.  
  38. /**
  39. 保存文件到指定路径下
  40. @param fromURL 初始文件的路径
  41. @param toURL 指定保存的路径
  42. @return 保存状态
  43. */
  44. + (NSError *)writeFileFromURL:(NSURL *)fromURL toURL:(NSURL *)toURL;
  45.  
  46. /**
  47. 计算单个文件的大小
  48. @param filePath 文件路径
  49. @return 缓存大小
  50. */
  51. + (float)fileSizeAtPath:(NSString*) filePath;
  52.  
  53. /**
  54. 计算遍历文件夹获得文件夹大小
  55. @param folderPath 文件夹路径
  56. @return 缓存大小
  57. */
  58. + (float)folderSizeAtPath:(NSString*) folderPath;
  59.  
  60. /**
  61. 清除文件缓存
  62. */
  63. + (void)clearFileCaches;
  64.  
  65. @end
  66.  
  67. //
  68. // XYQCachesManager.m
  69. // XYQPlayer
  70. //
  71. // Created by 夏远全 on 2017/4/22.
  72. // Copyright © 2017年 夏远全. All rights reserved.
  73. //
  74.  
  75. #import "XYQCachesManager.h"
  76. #import "XYQHUDView.h"
  77.  
  78. @implementation XYQCachesManager
  79.  
  80. static XYQCachesManager *_sharedCachesManager = nil;
  81.  
  82. + (instancetype)sharedXYQCachesManager {
  83. static dispatch_once_t onceToken;
  84. dispatch_once(&onceToken, ^{
  85. _sharedCachesManager = [[self alloc] init];
  86. });
  87. return _sharedCachesManager;
  88. }
  89.  
  90. #pragma mark - 获取沙盒目录
  91. + (NSString *)documentsLastPath{
  92. return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
  93. }
  94.  
  95. #pragma mark - 保存文件
  96. + (NSError *)writeFileFromURL:(NSURL *)fromURL toURL:(NSURL *)toURL{
  97.  
  98. NSError *error = nil;
  99. [[NSFileManager defaultManager] moveItemAtURL:fromURL toURL:toURL error:&error];
  100. return error;
  101. }
  102.  
  103. #pragma mark - 清除文件缓存
  104. + (void)clearFileCaches{
  105.  
  106. //遍历缓存文件
  107. __block float fileSize = ;
  108. NSArray *tempFileList = [[NSArray alloc] initWithArray:[[NSFileManager defaultManager] contentsOfDirectoryAtPath:[self documentsLastPath] error:nil]];
  109. XYQCachesManager *xyaCachesManager = [XYQCachesManager sharedXYQCachesManager];
  110. [xyaCachesManager.filePaths enumerateObjectsUsingBlock:^(NSString *URLFileName, NSUInteger idx, BOOL * _Nonnull stop) {
  111. NSString *URLFileNameLast = [URLFileName componentsSeparatedByString:@"/"].lastObject;
  112. [tempFileList enumerateObjectsUsingBlock:^(NSString *fileName, NSUInteger idx, BOOL * _Nonnull stop)
  113. {
  114. if ([URLFileNameLast isEqualToString:fileName]) {
  115. NSString *filePath = [[XYQCachesManager documentsLastPath] stringByAppendingPathComponent:URLFileNameLast];
  116. fileSize += [self fileSizeAtPath:filePath];
  117. [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
  118. }
  119. }];
  120. if (idx == xyaCachesManager.filePaths.count-) {
  121. [XYQHUDView showBigHud:[NSString stringWithFormat:@"清除缓存%.1fM",fileSize]];
  122. }
  123. }];
  124. }
  125.  
  126. #pragma mark - 通常用于删除缓存的时,计算缓存大小
  127. //单个文件的大小
  128. + (float) fileSizeAtPath:(NSString*) filePath{
  129. NSFileManager* manager = [NSFileManager defaultManager];
  130. if ([manager fileExistsAtPath:filePath]){
  131. return [[manager attributesOfItemAtPath:filePath error:nil] fileSize]/(1024.0*1024.0);
  132. }
  133. return ;
  134. }
  135.  
  136. //遍历文件夹获得文件夹大小,返回多少M
  137. + (float ) folderSizeAtPath:(NSString*) folderPath{
  138. NSFileManager* manager = [NSFileManager defaultManager];
  139. if (![manager fileExistsAtPath:folderPath]) return ;
  140. NSEnumerator *childFilesEnumerator = [[manager subpathsAtPath:folderPath] objectEnumerator];
  141. NSString* fileName;
  142. long long folderSize = ;
  143. while ((fileName = [childFilesEnumerator nextObject]) != nil){
  144. NSString* fileAbsolutePath = [folderPath stringByAppendingPathComponent:fileName];
  145. folderSize += [self fileSizeAtPath:fileAbsolutePath];
  146. }
  147. return folderSize/(1024.0*1024.0);
  148. }
  149.  
  150. @end

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

  1. //
  2. // XYQHUDView.h
  3. // XYQPlayer
  4. //
  5. // Created by 夏远全 on 2017/3/9.
  6. // Copyright © 2017年 夏远全. All rights reserved.
  7. //
  8.  
  9. #import <UIKit/UIKit.h>
  10.  
  11. /**************************************************************************************************
  12. 自定义消息弹出框:单纯的文本弹框、加载动画弹框
  13. ***************************************************************************************************/
  14.  
  15. @interface XYQHUDView : UILabel
  16.  
  17. /**
  18. 显示文本提示框
  19.  
  20. @param message 消息
  21. */
  22. +(void)showHud:(NSString *)message;
  23.  
  24. /**
  25. 显示进度提示框
  26.  
  27. @param progress 进度百分比
  28. @param view 容器
  29. */
  30. +(void)showHudWithProgress:(CGFloat)progress inView:(UIView *)view;
  31.  
  32. /**
  33. 刷新进度
  34.  
  35. @param progress 进度百分比
  36. */
  37. +(void)updateHudProgress:(CGFloat)progress;
  38.  
  39. /**
  40. 隐藏提示框
  41. */
  42. +(void)hideHud;
  43.  
  44. @end

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

  1. //
  2. // XYQProgress.h
  3. // XYQPlayer
  4. //
  5. // Created by 夏远全 on 2017/4/7.
  6. // Copyright © 2017年 夏远全. All rights reserved.
  7. //
  8.  
  9. #import <UIKit/UIKit.h>
  10.  
  11. /**************************************************************************************************
  12. 自定义时间进度条
  13. ***************************************************************************************************/
  14.  
  15. @interface XYQTimeProgress : UIView
  16. /**
  17. 进度起始值
  18. */
  19. @property (assign,nonatomic)NSTimeInterval startValue;
  20. /**
  21. 进度终点值
  22. */
  23. @property (assign,nonatomic)NSTimeInterval endValue;
  24. /**
  25. 进度率
  26. */
  27. @property (assign,nonatomic)CGFloat progressRate;
  28.  
  29. /**
  30. 创建进度条
  31.  
  32. @param frame 尺寸
  33. @param startValue 起始值
  34. @param endValue 终点值
  35.  
  36. */
  37. +(instancetype)createProgressWithFrame:(CGRect)frame StartValue:(NSTimeInterval)startValue endValue:(NSTimeInterval)endValue;
  38. +(instancetype)createProgressWithStartValue:(NSTimeInterval)startValue endValue:(NSTimeInterval)endValue;
  39.  
  40. @end

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

  1. //
  2. // UIImage+XYQCornerRadius.h
  3. // XYQPlayer
  4. //
  5. // Created by 夏远全 on 2017/3/8.
  6. // Copyright © 2017年 夏远全. All rights reserved.
  7. //
  8.  
  9. #import <UIKit/UIKit.h>
  10.  
  11. /**************************************************************************************************
  12. 切割圆角图片、旋转动画
  13. ***************************************************************************************************/
  14.  
  15. @interface UIImage (XYQCornerRadius)
  16.  
  17. /**
  18. 圆角图片
  19.  
  20. @param image 原始图片
  21. @param size 尺寸
  22. @param r 半径
  23. */
  24. + (UIImage *)createRoundedRectImage:(UIImage*)image size:(CGSize)size radius:(NSInteger)r;
  25.  
  26. /**
  27. 开始旋转
  28. @param rotationView 旋转视图
  29. */
  30. + (void)startRotation:(UIImageView *)rotationView;
  31.  
  32. /**
  33. 暂停动画
  34. @param layer 旋转视图layer
  35. */
  36. + (void)pauseAnimation:(CALayer *)layer;
  37.  
  38. @end

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

3、依赖

三、音乐播放和缓存逻辑

四、视频播放方式

五、音频播放test

  1. #import "PlayMusicViewController.h"
  2. #import "XYQAllHeader.h"
  3.  
  4. @interface PlayMusicViewController ()
  5. @property (strong,nonatomic)XYQAudioToolView *audioPlayerView;
  6. @end
  7.  
  8. @implementation PlayMusicViewController
  9.  
  10. - (void)viewDidLoad {
  11. [super viewDidLoad];
  12. self.view.backgroundColor = [UIColor whiteColor];
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"清除缓存" style:UIBarButtonItemStylePlain target:self action:@selector(clearCache)];
  1. //1、网络音乐(此处需要给出准确的url,我的这个不可以用,只是给个参考的样式)
  2. //[self testPlay_Local_URL_Music:@[@"http://120.25.226.186:32812/xxx/minion_02.mp3"]];
  3.  
  4. //2、本地音乐
  5. [self testPlay_Bundle_Music:[self musicArray]];
  6. }
  7.  
  8. //测试创建音乐播放器(播放沙盒本地音乐包括从网络音乐下载缓存)
  9. - (void)testPlay_Local_URL_Music:(NSArray *)musicFileLinkArray{
  10.  
  11. self.audioPlayerView = [XYQAudioToolView openAudioPlayerView:musicFileLinkArray audioPlayerViewController:self];
  12. self.audioPlayerView.diskIsHide = YES;
  13. }
  14.  
  15. //测试创建音乐播放器(播放bundle根目录下的音乐)
  16. - (void)testPlay_Bundle_Music:(NSArray *)musicNameArray{
  17.  
  18. self.audioPlayerView = [XYQAudioToolView openAudioPlayerView:musicNameArray audioPlayerViewController:self];
  19. self.audioPlayerView.diskIsHide = YES;
  20. }
  21.  
  22. //Bundle根目录子下所有的音乐文件名
  23. - (NSArray *)musicArray{
  24. NSString *path = [[NSBundle mainBundle] pathForResource:@"Musics" ofType:@"plist"];
  25. NSArray *musicNameArr = [NSArray arrayWithContentsOfFile:path];
  26. return musicNameArr;
  27. }

//清除缓存

- (void)clearCache{

[XYQCachesManager clearFileCaches];

}

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

六、视频播放test

  1. //
  2. // PlayMovieViewController.m
  3. // XYQPlayer
  4. //
  5. // Created by 夏远全 on 2017/4/9.
  6. // Copyright © 2017年 夏远全. All rights reserved.
  7. //
  8.  
  9. #import "PlayMovieViewController.h"
  10. #import "XYQAllHeader.h"
  11.  
  12. @interface PlayMovieViewController ()
  13.  
  14. @end
  15.  
  16. @implementation PlayMovieViewController
  17.  
  18. - (void)viewDidLoad {
  19. [super viewDidLoad];
  20. self.view.backgroundColor = [UIColor whiteColor];
  21.  
  22. //1、push视频
  23. [XYQMovieTool pushPlayMovieWithNetURL:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4" viewController:self];
  24. }
  25.  
  26. -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
  27.  
  28. //2、present视频
  29. //[XYQMovieTool presentPlayMovieWithNetURL:@"http://120.25.226.186:32812/resources/videos/minion_02.mp4" viewController:self];
  30. }
  31.  
  32. //关闭播放器
  33. -(void)viewWillDisappear:(BOOL)animated{
  34. [super viewWillDisappear:animated];
  35. [XYQMovieTool cancelPlay];
  36. }
  37.  
  38. @end

七、演示截图

音乐:

   

视频:

push:             present: 

 

八、cocoaPods支持:

  1. 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

iOS:简易的音视屏播放框架XYQPlayer的更多相关文章

  1. Java利用VLC开发简易视屏播放器

    1.环境配置 (1)下载VLC  VlC官网http://www.videolan.org/    各个版本的下载地址http://download.videolan.org/pub/videolan ...

  2. Android中使用SurfaceView+MediaPlayer+自定义的MediaController实现自定义的视屏播放器

    效果图如下: (PS本来是要给大家穿gif动态图的,无奈太大了,没法上传) 功能实现:暂停,播放,快进,快退,全屏,退出全屏,等基本功能 实现的思路: 在主布局中放置一个SurfaceView,在Su ...

  3. Android视屏播放兼容性问题分享

    最近产品提了一个紧急需求:webview加载的URL,需要支持视频播放. 为了快速完成需求,功能实现上直接使用系统自带播放器播放视频.由于是自带播放器,需要进行兼容性测试,过程发现了不少问题,这里分享 ...

  4. h5-自定义视屏播放器

    1.html代码 <h3 class="playerTitle">视屏播放器</h3> <div class="player"&g ...

  5. django-网页视屏播放

    基本都基于第三方: -cc视频 -播放免费视频 -收费视频 -需要做认证,cc视频会给你发消息,你返回,携带数据 -在前端页面中添加响应的视屏框的代码 -功能实现,有相关接口文档,配置即可

  6. opencv视屏流嵌入wxpython框架

    前几篇博客分享搭建人脸识别与情绪判断的环境和源码,但是没有UI,界面很难看,一打开就是opencv弹出的一个视屏框.处女座的我看着非常难受,于是决定做一个UI,稍微规矩好看一点,再怎么说,这样的话也算 ...

  7. iOS多种刷新样式、音乐播放器、仿抖音视频、旅游App等源码

    iOS精选源码 企业级开源项目,模仿艺龙旅行App 3D立体相册,可以旋转的立方体 横竖屏切换工具,使用陀螺仪检测手机设备方向,锁屏状... Swift版Refresh(可以自定义多种样式)架构方面有 ...

  8. 加入ffmpeg播放视屏

    下面的字反了..,另外没声音 2018-4-28 前段时间已经做的差不多了,音频的pack取出来用openAL播放,并实现了视屏同步播放,并且支持unity 现在的问题就是支持大分辨率视屏播放的问题, ...

  9. iOS从零开始学习直播之1.播放

      对于直播来说,客户端主要做两件事情,推流和播放.今天先讲播放. 播放流程 1.拉流:服务器已有直播内容,从指定地址进行拉取的过程.其实就是向服务器请求数据. 2.解码:对视屏数据进行解压缩. 3. ...

随机推荐

  1. SQL-修改表名,列名

    sql 1.sql server修改表名.列名 修改表名:EXEC sp_rename ‘原有表名’, '新表名'; 修改列名:EXEC sp_rename ‘表名.[原有列名]’, ‘新列名' , ...

  2. 通过css属性hack完成select样式美化,并兼容IE

    最近在重构时遇到了select样式问题,并且需要在不影响语义化的情况下,兼容IE8. 经过一番的百度后始终没有找到合适的纯CSS解决方案,最后换了一下思路,大胆使用了属性hack: 在chrome和F ...

  3. 多线程学习笔记六之并发工具类CountDownLatch和CyclicBarrier

    目录 简介 CountDownLatch 示例 实现分析 CountDownLatch与Thread.join() CyclicBarrier 实现分析 CountDownLatch和CyclicBa ...

  4. collectionFramwork-1

    1. Set.List和Map可以看做集合的三大类. List集合是有序集合,集合中的元素可以重复,访问集合中的元素可以根据元素的索引来访问. Set集合是无序集合,集合中的元素不可以重复,访问集合中 ...

  5. 关于操作Access数据库jdk选择问题

    关于操作Access数据库,使用jdk64位无法通过ODBC无法获取数据,只能通过jdk32位进行开发.

  6. Codeforces Round #373 (Div. 2) B. Anatoly and Cockroaches 水题

    B. Anatoly and Cockroaches 题目连接: http://codeforces.com/contest/719/problem/B Description Anatoly liv ...

  7. TCP三次握手&四次挥手(示意图)

    经典的三次握手示意图:(#add,“握手”即图中左边到右边的连线)    经典的四次握手关闭图:    TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: 位码即t ...

  8. C# .Net 多进程同步 通信 共享内存 内存映射文件 Memory Mapped

    节点通信存在两种模型:共享内存(Shared memory)和消息传递(Messages passing). 内存映射文件对于托管世界的开发人员来说似乎很陌生,但它确实已经是很远古的技术了,而且在操作 ...

  9. LightOJ 1366 - Pair of Touching Circles (统计矩形内外切圆对)

    1366 - Pair of Touching Circles   PDF (English) Statistics Forum Time Limit: 3 second(s) Memory Limi ...

  10. Processing an OS Descriptor request -- Remote Desktop Protocol

    Special processing on the client is needed when processing TS_URB_OS_FEATURE_DESCRIPTOR_REQUEST. The ...