iOS_音频波形图Time、Wave实现,滑动设置播放进度

实现如下:

需要的数据源:

1、demo.mp3:音频文件

2、samplePoints 数组:每秒音量(0-1)数组,根据音频pcm采样数据文件计算出来的(遍历:每秒取一点,并记录下最大值;最后按取值为0至1,进行缩放。计算完的数存如数组)

(这里不过多描述计算音量过程,以后有时间补...)

接下来是UI实现思路:

一、滑动视图:

用了两个TableView,上面的显示时间和刻度,下面的显示音量Lines。

为了让时间显示在cell中间,所以设置结构如下图:

time tableView 不可滑动,Wave tableView的 scrollViewDidScroll 回调里设置time tableView的偏移量,使其保持一致。

二、数据处理

根据上面UI结构,所以第一个cell只有10s的数据,而后开始每个cell画30s,直到最后一个有多少画多少

// 因为时间刻度显示问题,为了把label放在中间,所以第一个section左边空出了10s,每个section画30s的数据
// 刻度的每个间隔是2s,也就是需要可以画2条线(kAudioPlayerLineSpacing:每条线的间距;每个刻度的就*2)
- (void)setPoints:(NSArray *)points {
  _points = points;
  NSMutableArray *tempArray = [NSMutableArray arrayWithArray:_points];
  self.pointArrays = [[NSMutableArray alloc] init];
  NSInteger index = 0;
  while (tempArray.count > 0) {
    if (index == 0) {
      if (tempArray.count >= 20) { // section0 数据
        [self.pointArrays addObject:[tempArray subarrayWithRange:NSMakeRange(0, 20)]];
        [tempArray removeObjectsInRange:NSMakeRange(0, 20)];
      }
    } else {
      if (tempArray.count >= 30) {
        [self.pointArrays addObject:[tempArray subarrayWithRange:NSMakeRange(0, 30)]];
        [tempArray removeObjectsInRange:NSMakeRange(0, 30)];
      } else {
        [self.pointArrays addObject:[tempArray copy]];
        [tempArray removeAllObjects];
      }
    }
    index++;
  }
  self.timeView.points = self.pointArrays;
  self.waveView.points = self.pointArrays;
}

三、播放器

AVPlayer:通过`addPeriodicTimeObserverForInterval:queue:usingBlock:`实现每秒回调,监听播放进度

_player = [[AVPlayer alloc] initWithURL:self.playURL];
__weak typeof(self) weakSelf = self;
[_player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
  float currentTime = weakSelf.player.currentTime.value / weakSelf.player.currentTime.timescale;
  [weakSelf.waveView setContentOffset:CGPointMake(0, currentTime * kAudioPlayerLineSpacing)];
}];

kAudioPlayerLineSpacing:是每条Line之间的距离(可以随意设置)

所以每个刻度的间距就是:kAudioPlayerLineSpacing * 2 (因为个刻度表示2s)

四、滑动控制播放进度

1、首先去掉tableView的滑动惯性,否则滑动出界就很难控制

在 scrollViewWillBeginDecelerating: 开始减速方法里设置  [scrollView setContentOffset: animated:NO]

(设置偏移为手指滑动到的位置,并不需要滑动动画,即可去掉滑动惯性)

2、然后滑动的时候需要暂停player,否则就会跟 TimeObserver 回调里设置的偏移 冲突

在 scrollViewWillBeginDragging: 方法里调用 [_player pause]

在 scrollViewDidEndDragging: 方法里根据 偏移 和 kAudioPlayerLineSpacing 计算出需要播放的时间(秒数),

- (void)didEndDraggingY:(CGFloat)y {
  // 拖拽结束后,根据偏移计算时间,设置播放进度
  CGFloat second = y / kAudioPlayerLineSpacing;
  [self.player seekToTime:CMTimeMakeWithSeconds(second, NSEC_PER_SEC)];
  if (self.playBtn.selected) { // 如果是播放状态则开始播放
    [self.player play];
  }
}

github demo

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫小言mo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值