LrcShowView.m 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. //
  2. // LrcShowView.m
  3. // BuguLive
  4. //
  5. // Created by 岳克奎 on 16/12/16.
  6. // Copyright © 2016年 xfg. All rights reserved.
  7. //
  8. #import "LrcShowView.h"
  9. @implementation LrcShowView
  10. #pragma mark -self
  11. /**
  12. * @brief:LrcShowView 承载上下两行歌词
  13. *
  14. * @discussion: 1.歌词也算是数据吧。。所以简历数据层处理数据
  15. *
  16. */
  17. - (instancetype)initWithCoder:(NSCoder *)aDecoder{
  18. if (self = [super initWithCoder:aDecoder]) {
  19. //因没实力化,子控件要在from nib 写
  20. }
  21. return self;
  22. }
  23. - (void)awakeFromNib{
  24. [super awakeFromNib];
  25. }
  26. #pragma mark - 歌词lab数据更新
  27. /**
  28. * @brief:歌词lab数据更新(C++player的代理不断向外传输数据)
  29. *
  30. * @ prama : currentTime
  31. * @ prama : totalTime
  32. * @ prama : presnet
  33. *
  34. * @discussion:1.小于 10行 的歌词 默认木有歌词 只是显示 歌曲信息
  35. * 2.不能每次都要去数据源找数据 当去取数据的时候,记录下当前行 开始时间+结束时间 每次依据这个判断 是不是要更新数据
  36. * 3.数据的取法: 根据当前时间 判断再哪一个 时间区间-->得到index-->直接取出对应的lrcModel -->更新记录+更新数据
  37. */
  38. dispatch_source_t timer;//开启定时器 赋值必须在定时器里
  39. - (void)setCurrentTime:(CGFloat)currentTime
  40. musicTotalTime:(CGFloat)totalTime
  41. present:(CGFloat)present{
  42. //NSLog(@"eqeq----------------------%f -------%f -----------%f",currentTime,totalTime,present);
  43. // 默认歌词小于十行的,显示 歌手+歌曲 已经够意思了
  44. if (self.lrcModelMArray.count<10) {
  45. return;
  46. NSDictionary *dic = self.lrcTimePointMArray[0];
  47. if (![dic valueForKey:@"lrcContentStr"]) {
  48. self.lrcUpLab.text = dic[@"lrcContentStr"];
  49. }
  50. return;
  51. }
  52. //如果播放完毕。以为C++播放器的一直走,代理也一直走,导致这个方法也一直走。播放完毕销毁再重新建吧
  53. if (currentTime+1 >totalTime) {
  54. self.lineIndex = 0;
  55. self.recordCurrentTime = 0;
  56. self.recordCurrentModelStartTime = 0;
  57. self.recordNextModelStartTime = 0;
  58. if (timer) {
  59. dispatch_cancel(timer);
  60. timer = nil;
  61. }
  62. return;//结束
  63. }
  64. //记录 当前歌词进度的时间点
  65. __weak typeof(self)weak_Self = self;
  66. weak_Self.recordCurrentTime = present*totalTime;
  67. //开GCD定时器
  68. dispatch_queue_t queue =dispatch_get_main_queue();
  69. if (timer) {
  70. dispatch_cancel(timer);
  71. timer = nil;}
  72. timer =dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0, 0, queue);
  73. dispatch_time_t start =dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC));
  74. uint64_t interval = (uint64_t)(0.01f *NSEC_PER_SEC);
  75. dispatch_source_set_timer(timer , start, interval,0);
  76. dispatch_source_set_event_handler(timer, ^{
  77. //
  78. weak_Self.musicTimeCountDownLab.text = [NSString stringWithFormat:@"-%02d:%02d",(int)((totalTime-currentTime)/60)%60,(int)(totalTime-currentTime)%60];
  79. // 根据 下一次开始的时间 来判断 要不要执行更迭model 不能每次取数据 只有当前时间不在 当前行了,要去下一样,才去取数据
  80. // 当前时间 小于 下下一次开始时间
  81. if (weak_Self.recordNextModelStartTime>= weak_Self.recordCurrentTime) {
  82. // 当第一个model加载 进度 必定是上面lab
  83. // 某行 时间间隔
  84. float lineTotalTime =self.recordNextModelStartTime-weak_Self.recordCurrentModelStartTime;
  85. float linePlayTime =self.recordCurrentTime-weak_Self.recordCurrentModelStartTime;
  86. // 根据 lineIndex判断要显示上行还是下行,给lrcLab传入进度
  87. if (weak_Self.lineIndex%2==0) {
  88. weak_Self.lrcUpLab.progress = linePlayTime/lineTotalTime;
  89. }else{
  90. weak_Self.lrcDowmLab.progress = linePlayTime/lineTotalTime;
  91. }
  92. }else{
  93. //某行 数据的取法
  94. //判断当前的时间 是否 在 model 的区间里面 时间点我可以全部返回 回来
  95. for (int i = 0; i< _lrcTimePointMArray.count; i++) {
  96. CGFloat lrctimePoint = (CGFloat)[_lrcTimePointMArray[i] integerValue];
  97. // 注意 取到最后一个的时候,i+1是我自己加的,然后记录最后次数据没必要,因为最后一次不就是totalTime么
  98. CGFloat nextLrctimePoint;
  99. if(_lrcTimePointMArray.count-1 == i){
  100. nextLrctimePoint = totalTime;
  101. }else{
  102. nextLrctimePoint = (CGFloat)[_lrcTimePointMArray[i+1] integerValue];
  103. }
  104. if (weak_Self.recordCurrentTime>=lrctimePoint && weak_Self.recordCurrentTime< nextLrctimePoint) {
  105. //符合时间段 得到index
  106. self.lineIndex = i;
  107. // 得到 正在播放区间
  108. LrcModel *model = weak_Self.lrcModelMArray[weak_Self.lineIndex];
  109. LrcModel *nextModel = weak_Self.lrcModelMArray[weak_Self.lineIndex+1];
  110. //记录下个开始的时间 当前model开始的时间
  111. weak_Self.recordNextModelStartTime = (CGFloat)nextModel.lrcStartTimeStr.integerValue;
  112. weak_Self.recordCurrentModelStartTime = (CGFloat)model.lrcStartTimeStr.integerValue;
  113. //确保一开始进度是0
  114. weak_Self.lrcUpLab.progress = 0;
  115. weak_Self.lrcDowmLab.progress = 0;
  116. // 根据 lineIndex 判断。每次进来更新数据 要更新2行的数据,上下行都要更新 不要考虑下一行是否为空,数据源创建时候已经处理
  117. if (weak_Self.lineIndex%2 == 0) {
  118. weak_Self.lrcUpLab.text = model.lrcContentStr;
  119. weak_Self.lrcDowmLab.text = nextModel.lrcContentStr;
  120. }else{
  121. weak_Self.lrcDowmLab.text = model.lrcContentStr;
  122. weak_Self.lrcUpLab.text = nextModel.lrcContentStr;
  123. }
  124. return ;
  125. }
  126. }
  127. }
  128. if (totalTime == currentTime) {
  129. // 数据归0
  130. self.lineIndex = 0;
  131. self.recordCurrentTime = 0;
  132. self.recordCurrentModelStartTime = 0;
  133. self.recordNextModelStartTime = 0;
  134. //定时器销毁
  135. dispatch_cancel(timer);
  136. timer = nil;
  137. }
  138. });
  139. // 启动定时器 GO!Go!
  140. dispatch_resume(timer);
  141. }
  142. - (void)showCurrentTime:(CGFloat)currentTime musicTotalTime:(CGFloat)totalTime present:(CGFloat)present{
  143. // NSLog(@"eqeq----------------------%f -------%f -----------%f",currentTime,totalTime,present);
  144. // 默认歌词小于十行的,显示 歌手+歌曲 已经够意思了
  145. if (self.lrcModelMArray.count<10) {
  146. return;
  147. NSDictionary *dic = self.lrcTimePointMArray[0];
  148. if (![dic valueForKey:@"lrcContentStr"]) {
  149. self.lrcUpLab.text = dic[@"lrcContentStr"];
  150. }
  151. return;
  152. }
  153. //如果播放完毕。以为C++播放器的一直走,代理也一直走,导致这个方法也一直走。播放完毕销毁再重新建吧
  154. if (currentTime+1 >totalTime) {
  155. self.lineIndex = 0;
  156. self.recordCurrentTime = 0;
  157. self.recordCurrentModelStartTime = 0;
  158. self.recordNextModelStartTime = 0;
  159. if (timer) {
  160. dispatch_cancel(timer);
  161. timer = nil;
  162. }
  163. return;//结束
  164. }
  165. //记录 当前歌词进度的时间点
  166. __weak typeof(self)weak_Self = self;
  167. weak_Self.recordCurrentTime = present*totalTime;
  168. //开GCD定时器
  169. dispatch_queue_t queue =dispatch_get_main_queue();
  170. if (timer) {
  171. dispatch_cancel(timer);
  172. timer = nil;}
  173. timer =dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,0, 0, queue);
  174. dispatch_time_t start =dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC));
  175. uint64_t interval = (uint64_t)(0.01f *NSEC_PER_SEC);
  176. dispatch_source_set_timer(timer , start, interval,0);
  177. dispatch_source_set_event_handler(timer, ^{
  178. //
  179. weak_Self.musicTimeCountDownLab.text = [NSString stringWithFormat:@"-%02d:%02d",(int)((totalTime-currentTime)/60)%60,(int)(totalTime-currentTime)%60];
  180. // 根据 下一次开始的时间 来判断 要不要执行更迭model 不能每次取数据 只有当前时间不在 当前行了,要去下一样,才去取数据
  181. // 当前时间 小于 下下一次开始时间
  182. if (weak_Self.recordNextModelStartTime>= weak_Self.recordCurrentTime) {
  183. // 当第一个model加载 进度 必定是上面lab
  184. // 某行 时间间隔
  185. float lineTotalTime =self.recordNextModelStartTime-weak_Self.recordCurrentModelStartTime;
  186. float linePlayTime =self.recordCurrentTime-weak_Self.recordCurrentModelStartTime;
  187. // 根据 lineIndex判断要显示上行还是下行,给lrcLab传入进度
  188. if (weak_Self.lineIndex%2==0) {
  189. weak_Self.lrcUpLab.progress = linePlayTime/lineTotalTime;
  190. }else{
  191. weak_Self.lrcDowmLab.progress = linePlayTime/lineTotalTime;
  192. }
  193. }else{
  194. //某行 数据的取法
  195. //判断当前的时间 是否 在 model 的区间里面 时间点我可以全部返回 回来
  196. for (int i = 0; i< _lrcTimePointMArray.count; i++) {
  197. CGFloat lrctimePoint = (CGFloat)[_lrcTimePointMArray[i] integerValue];
  198. // 注意 取到最后一个的时候,i+1是我自己加的,然后记录最后次数据没必要,因为最后一次不就是totalTime么
  199. CGFloat nextLrctimePoint;
  200. if(_lrcTimePointMArray.count-1 == i){
  201. nextLrctimePoint = totalTime;
  202. }else{
  203. nextLrctimePoint = (CGFloat)[_lrcTimePointMArray[i+1] integerValue];
  204. }
  205. if (weak_Self.recordCurrentTime>=lrctimePoint && weak_Self.recordCurrentTime< nextLrctimePoint) {
  206. //符合时间段 得到index
  207. self.lineIndex = i;
  208. // 得到 正在播放区间
  209. LrcModel *model = weak_Self.lrcModelMArray[weak_Self.lineIndex];
  210. LrcModel *nextModel = weak_Self.lrcModelMArray[weak_Self.lineIndex+1];
  211. //记录下个开始的时间 当前model开始的时间
  212. weak_Self.recordNextModelStartTime = (CGFloat)nextModel.lrcStartTimeStr.integerValue;
  213. weak_Self.recordCurrentModelStartTime = (CGFloat)model.lrcStartTimeStr.integerValue;
  214. //确保一开始进度是0
  215. weak_Self.lrcUpLab.progress = 0;
  216. weak_Self.lrcDowmLab.progress = 0;
  217. // 根据 lineIndex 判断。每次进来更新数据 要更新2行的数据,上下行都要更新 不要考虑下一行是否为空,数据源创建时候已经处理
  218. if (weak_Self.lineIndex%2 == 0) {
  219. weak_Self.lrcUpLab.text = model.lrcContentStr;
  220. weak_Self.lrcDowmLab.text = nextModel.lrcContentStr;
  221. }else{
  222. weak_Self.lrcDowmLab.text = model.lrcContentStr;
  223. weak_Self.lrcUpLab.text = nextModel.lrcContentStr;
  224. }
  225. return ;
  226. }
  227. }
  228. }
  229. if (totalTime == currentTime) {
  230. // 数据归0
  231. self.lineIndex = 0;
  232. self.recordCurrentTime = 0;
  233. self.recordCurrentModelStartTime = 0;
  234. self.recordNextModelStartTime = 0;
  235. //定时器销毁
  236. dispatch_cancel(timer);
  237. timer = nil;
  238. }
  239. });
  240. // 启动定时器 GO!Go!
  241. dispatch_resume(timer);
  242. }
  243. #pragma mark - set/get
  244. // 歌词每行model 的数据源数组
  245. - (void)setLrcModelMArray:(NSMutableArray *)lrcModelMArray{
  246. _lrcModelMArray = lrcModelMArray;
  247. }
  248. //记录当前时间
  249. - (void)setRecordCurrentTime:(CGFloat)recordCurrentTime{
  250. _recordCurrentTime = recordCurrentTime;
  251. }
  252. // 记录当前行model 的开始执行这行的起点时间
  253. - (void)setRecordCurrentModelStartTime:(CGFloat)recordCurrentModelStartTime{
  254. _recordCurrentModelStartTime =recordCurrentModelStartTime;
  255. }
  256. // 记录当下行model 的开始执行这行的起点时间
  257. - (void)setRecordNextModelStartTime:(CGFloat)recordNextModelStartTime{
  258. _recordNextModelStartTime = recordNextModelStartTime;
  259. }
  260. @end