iOS开发播放音频上下集切换等等功能

import "AssistiveTouch.h" 最主要我用的是XIB,需要自己定制自己定制

import "KGCAssisiveCell.h" 订制的Cell

import "KGCPlayOnlineM3u8.h" //由于我们的mp3链接地址是加密的和视频统一分装的

import "KGC_TimeManager.h" //定时器使用

import "KGCActionStatistic.h"//公司的统计

import "UIImage+GIF.h"// 加载的动画,不用考虑

@interface AssistiveTouch ()

@property (nonatomic, strong) NSDateFormatter * dateFormatter;

@property(nonatomic,strong) NSMutableArray * subtitlesarray;

@property(nonatomic,strong) NSMutableArray * begintimearray;

@property (weak, nonatomic) IBOutlet UIView * mViewBack;

@property (weak, nonatomic) IBOutlet UIView * mViewPlayer;

@property (weak, nonatomic) IBOutlet UIButton * upBtnclick;

@property (weak, nonatomic) IBOutlet UIButton * nextBtnclick;

@property (weak, nonatomic) IBOutlet UILabel * mTexthints;

@property(nonatomic,strong) UIView * mViewPlay;

@property (nonatomic) int currentLine;

@property (nonatomic) int PlayerStact;

@property (nonatomic) BOOL isShow;

@property(nonatomic)CGFloat mCurrentSecond;

@property (nonatomic,strong)UIImageView * imageVIewGif;

@property (nonatomic,strong)NSMutableArray * mArray;

@end

@implementation AssistiveTouch

-(id)initWithCoder:(NSCoder*)aDecoder

{

self= [superinitWithCoder:aDecoder];

if(self)

{

    [self initFrameViewTop];

}

return self;

}

  • (void)btnclickTop:(int)tag

{

pragma mark --- 记录学习进度的

[self RecordonUpdateProgress:YES];

[selfstop];

if(self.Delegate) {

    [self.Delegate PlayTheNextSection:tag];

}

}

  • (IBAction)rightBtn:(UIButton*)sender

{

NSArray *selSectionArr = [KGCLogicalprocessing sharprocessing].scoLists[[KGCLogicalprocessing sharprocessing].tmpIndexPath.section][@"lesson"];

if ([KGCLogicalprocessing sharprocessing].tmpIndexPath.row == [selSectionArr count] - 1) {

    if(self.Delegate){

        [self.Delegate showMessage:@"您好,当前播放为最后一课"];

    }

}else{

     [self RecordonUpdateProgress:NO];

     [selfbtnclickTop:2];

}

}

  • (IBAction)LeftBtn:(UIButton*)sender

{

if ([KGCLogicalprocessing sharprocessing].tmpIndexPath.row == 0) {

    if(self.Delegate){

         [self.Delegate showMessage:@"您好,当前播放为第一课"];

    }

}else{

    [self RecordonUpdateProgress:NO];

    [selfbtnclickTop:1];

}

}

+(AssistiveTouch*)instanceTextView

{

NSArray* nibView =  [[NSBundle mainBundle] loadNibNamed:@"AssistiveTouch" owner:nil options:nil];

return[nibViewobjectAtIndex:0];

}

  • (void)subArrayAndbegin

{

if (_subtitlesarray || _begintimearray){

    [_subtitlesarray removeAllObjects];

    [_begintimearray removeAllObjects];

}

  _subtitlesarray = [[NSMutableArray alloc] init];

  _begintimearray = [[NSMutableArray alloc] init];

  __weaktypeof(self) weakSelf =self;

    [[KGCLogicalprocessing sharprocessing] string:0 strurl:@"" block:^(NSMutableArray *arrayOne,NSMutableArray *arrayTwo, BOOL is) {

        weakSelf.begintimearray= arrayOne;

        weakSelf.subtitlesarray= arrayTwo;

        if(weakSelf.begintimearray.count==0) {

            weakSelf.mTexthints.hidden=NO;

        }else{

            weakSelf.mTexthints.hidden=YES;

        }

}];

}

-(void)awakeFromNib

{

[super awakeFromNib];

self.mArray = [NSMutableArray array];

for(inti =0; i<40; i++) {

    [self.mArray addObject:[UIImage imageNamed:[NSString stringWithFormat:@"加载动画%d.png",i+1]]];}

[self PickerViewinit];

}

  • (void)PickerViewinit

{

self.currentLine = 0;

self.mTableView.delegate = self;

self.mTableView.dataSource = self;

[self.mTableView setHeight:kScreenWidth*270/480-68-80];

self.mViewPlayer.frame = CGRectMake(0, self.mTableView.bottomY, self.width, 80);

[self.mSlider setHeight:2];

[self.mSlider setThumbImage:[UIImage imageNamed:@"btn-进度点标识.png"] forState:UIControlStateNormal];

[_mSlider addTarget:self action:@selector(progressSliderBeginVauleChange) forControlEvents:UIControlEventTouchDown];

[_mSlider addTarget:self action:@selector(progressSliderVauleEndChange) forControlEvents:UIControlEventTouchCancel | UIControlEventTouchUpInside];

UITapGestureRecognizer*tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(animateShow:)];

[self addGestureRecognizer:tap];

self.imageVIewGif = [[UIImageView alloc] initWithFrame:CGRectMake(self.width*0.35, 0, self.width*0.3, self.width/10)];

[self addSubview:self.imageVIewGif];

}

  • (void)animateShow:(UITapGestureRecognizer*)tap

{

[UIView animateWithDuration:0.1 animations:^{

if(self.isShow==NO) {

    [self setHeight:25 hidden:YES];

}else{

    [self setHeight:80 hidden:NO];

}

}];

}

  • (void)setHeight:(CGFloat)height hidden:(BOOL)hidden

{

self.isShow= hidden;

self.mViewBack.hidden= hidden;

[self.mTableViewsetHeight:kScreenWidth*270/480-68-height];

self.mViewPlayer.frame = CGRectMake(0, self.mTableView.bottomY, self.width, height);

}

  • (NSDateFormatter*)dateFormatter

{

if (!_dateFormatter)

{

    _dateFormatter = [[NSDateFormatter alloc] init];

}

return _dateFormatter;

}

  • (NSString*)convertTime:(CGFloat)second

{

NSDate *d = [NSDate dateWithTimeIntervalSince1970:second];

if(second/3600>=1)

{

    [[selfdateFormatter]setDateFormat:@"HH:mm:ss"];

}else{

    [[selfdateFormatter]setDateFormat:@"mm:ss"];

}

NSString*showtimeNew = [[selfdateFormatter]stringFromDate:d];

returnshowtimeNew;

}

  • (void)initFrameViewTop

{

self.userInteractionEnabled = YES;

self.window.windowLevel = UIWindowLevelAlert + 1;

[self.window makeKeyAndVisible];

[self setWidth:kScreenWidth-20];

[self setHeight:kScreenWidth*270/480-68];

[self setCenterX:kScreenWidth/2];

[self setBottomY:kScreenWidth*270/480];

}

//播放当前mp3

-(void)initPlay:(NSString)strUrl strProgress:(NSString)progress

{

[self subArrayAndbegin];

if(KlogIn) {

    [[KGC_TimeManager sharprocessing] pq_open];

    [KGC_TimeManager sharprocessing].mStatetype = TimerManagerStateRun;

}

self.isPlayer=YES;

self.swithURL= strUrl;

[self initPLayAudio:self.swithURL];

[self ReachabilityStatus:progress];

}

pragma makr === 点击播放按钮

  • (IBAction)btnClickPlay:(UIButton*)sender {

    self.btnPlayVideon.selected= !sender.selected;

    [selfplayMp3];

}

  • (void)playMp3

{

if (self.PlayerStact==AVPlayerStatusReadyToPlay)

{

    if(self.isPlayer) {

        [[KGC_TimeManager sharprocessing] TimerManagerState:TimerManagerStateSuspend];

        self.isPlayer=NO;

        [self.playerpause];

    }else{

        [[KGC_TimeManager sharprocessing] TimerManagerState:TimerManagerStateRun];

        self.isPlayer=YES;

        [self.playerplay];

    }

}

}

pragma mark -- 初始化音频播放器

-(void)initPLayAudio:(NSString*)strUrl

{

AVAudioSession *session = [AVAudioSession sharedInstance];

[sessionsetActive:YESerror:nil];

[sessionsetCategory:AVAudioSessionCategoryPlayback error:nil];

self.mAVPlayerItem = [[AVPlayerItem alloc]initWithURL:[NSURL URLWithString:strUrl]];

self.player = [[AVPlayer alloc]initWithPlayerItem:self.mAVPlayerItem];

// self.player.playImmediatelyAtRate = 0;

self.player.rate=1.0;

pragma mark -- 添加监听状态

[self.mAVPlayerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];

pragma mark -- KVO监听音乐缓冲状态

[self.player.currentItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeListenerCallback:)  name:AVAudioSessionRouteChangeNotification object:nil];

pragma mark -- 通过KVO添加播放结束事件监听

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.mAVPlayerItem];

[self.playerplay];

[self progressCurrent];

}

  • (void)progressCurrent

{

__weak typeof(self) weakSelf = self;

[self.player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {

    floatcurrent =CMTimeGetSeconds(time);

    floattotal =CMTimeGetSeconds(weakSelf.mAVPlayerItem.duration);

    [weakSelf.imageVIewGifstopAnimating];

    [weakSelfrollLycNumber:(int)current];

    weakSelf.endTime.text= [weakSelfconvertTime:total];

    weakSelf.playTime.text= [weakSelfconvertTime:current];

    weakSelf.mCurrentSecond= current;

// weakSelf.mCurrenttotal = total;

}];

}

//发送学习进度

  • (void)RecordonUpdateProgress:(BOOL)isSuccess

{

  if(KlogIn) {

    [KGCActionStatistic onUpdateProgress:[KGCLogicalprocessing sharprocessing].tmpIndexPath array:[KGCLogicalprocessing sharprocessing].scoLists last:self.mCurrentSecond is:isSuccess endTime:[NSString stringWithFormat:@"%d",[KGC_TimeManager sharprocessing].timeInterval]];

  }

}

  • (void)imagViewGiftoAnimation

{

if(![self.imageVIewGifisAnimating]) {

    self.imageVIewGif.animationImages = self.mArray;

    self.imageVIewGif.animationDuration = 1.0;

    self.imageVIewGif.animationRepeatCount = 0;

    [self.imageVIewGif startAnimating];

}

}

staticvoidextracted(AssistiveTouch*object) {

[objectimagViewGiftoAnimation];

}

  • (void)observeValueForKeyPath:(NSString)keyPath ofObject:(id)object change:(NSDictionary)change context:(void*)context

{

[selfplayerStac:keyPath];

[selfkeyPath:keyPath];

extracted(self);

}

pragma mark -- 缓存进度条显示

  • (void)keyPath:(NSString*)keyPath

{

if([keyPathisEqualToString:@"loadedTimeRanges"]) {

    NSTimeIntervaltimeIntervale = [selfavailableDuration];

    CMTimeduratione =self.mAVPlayerItem.duration;

    CGFloattotalDuration =CMTimeGetSeconds(duratione);

    NSString*str = [NSStringstringWithFormat:@"%f",timeIntervale];

    NSString*strr = [NSStringstringWithFormat:@"%f",totalDuration];

    if([strisEqualToString:@"nan"] || [strrisEqualToString:@"nan"]) {

        return;

    }

    [self.mProgressViewsetProgress:timeIntervale/totalDurationanimated:YES];

    if(CMTimeGetSeconds(duratione))

    {

        self.mSlider.maximumValue=CMTimeGetSeconds(duratione);

    }else{

        self.mSlider.maximumValue=1;

    }

}

}

  • (NSTimeInterval)availableDuration

{

NSArray *loadedTimeRanges = [[self.player currentItem] loadedTimeRanges];

CMTimeRange timeRange = [loadedTimeRanges.firstObject CMTimeRangeValue];// 获取缓冲区域

floatstartSeconds =CMTimeGetSeconds(timeRange.start);

floatdurationSeconds =CMTimeGetSeconds(timeRange.duration);

NSTimeIntervalresult = startSeconds + durationSeconds;

returnresult;

}

pragma mark 监听耳机插拔事件

  • (void)audioRouteChangeListenerCallback:(NSNotification*)notification {

    NSDictionary*interuptionDict = notification.userInfo;

    NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];

    switch(routeChangeReason) {

// case AVAudioSessionRouteChangeReasonNewDeviceAvailable: {//耳机插入

// [UIView animateWithDuration:1 animations:^{

// }];

// }

// break;

    case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: {//耳机拔出

        [UIView animateWithDuration:1 animations:^{

            [self.playerpause];

            self.isPlayer=NO;

            self.btnPlayVideon.selected=NO;

        }];

    }

        break;

// case AVAudioSessionRouteChangeReasonCategoryChange:

// break;

}

}

pragma mark -- 监听当时的状态是否可以进行播放

  • (void)playerStac:(NSString*)keyPath

{

if([keyPathisEqualToString:@"status"]) {

    switch(self.player.status) {

        case AVPlayerStatusUnknown:

            self.PlayerStact = AVPlayerStatusUnknown;

            break;

        case AVPlayerStatusReadyToPlay:

            [self monitoringPlayback:self.mAVPlayerItem];

            self.PlayerStact = AVPlayerStatusReadyToPlay;

            self.btnPlayVideon.selected=YES;

            self.isPlayer=YES;

            break;

        case AVPlayerStatusFailed:

            self.PlayerStact=AVPlayerStatusFailed;

            if(self.Delegate){

                [self.DelegateshowMessage:@"请检查您的网络~"];

            }

            self.btnPlayVideon.selected=NO;

            self.isPlayer=NO;

            break;

        default:

            break;

    }

}

}

pragma MARK --滑杆

  • (void)monitoringPlayback:(AVPlayerItem*)playerItem

{

__weak typeof(self) weakSelf = self;

[self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:NULL usingBlock:^(CMTime time){

    CGFloatcurrentSecond = playerItem.currentTime.value/playerItem.currentTime.timescale;

    [weakSelf.mSlidersetValue:currentSecondanimated:YES];

}];

}

pragma mark -- 进来的时候进行进度更新

  • (void)ReachabilityStatus:(NSString*)progress

{

[self.player seekToTime:CMTimeMake([progress intValue],1)];

}

pragma mark -- 用户拖动进度条,修改播放进度

  • (void)playSliderValueChange:(UISlider*)sender

{

[self.player seekToTime:CMTimeMake(sender.value * CMTimeGetSeconds(self.player.currentItem.duration), 1)];

}

  • (void)playbackFinished:(NSNotification*)notice

{

pragma mark -- 添加时间

[self RecordonUpdateProgress:YES];

[self btnclickTop:2];

}

pragma mark -- 不是彻底的关闭

  • (void)stop

{

self.btnPlayVideon.selected = NO;

self.isPlayer=NO;

[[KGCPlayOnlineM3u8 KGCPlayOnlineM3u8] removerM3u8];

[[KGC_TimeManager sharprocessing] pq_close];

[self.playerpause];

}

pragma tableView--delegate

pragma tableView

-(NSInteger)numberOfSectionsInTableView:(UITableView*)tableView {

return 1;

}

-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {

return _subtitlesarray.count;

}

  • (CGFloat)tableView:(UITableView)tableView heightForRowAtIndexPath:(NSIndexPath)indexPath

{

return 20;

}

-(UITableViewCell)tableView:(UITableView)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {

staticNSString*KGCPostIdentifier =@"KGCAssisiveCell";

 KGCAssisiveCell* cell = [tableViewdequeueReusableCellWithIdentifier:KGCPostIdentifier];

 if(!cell){

     NSArray *nibs = [[NSBundle mainBundle]loadNibNamed:@"KGCAssisiveCell" owner:nil options:nil];

     cell = [nibslastObject];

 }

if (_subtitlesarray.count > 0) {

    if(indexPath.row!=0) {

        cell.labelText.text= [_subtitlesarrayobjectAtIndex:indexPath.row];

        cell.labelText.highlightedTextColor = [UIColor whiteColor];

    }

}

 returncell;

}

  • (void)rollLycNumber:(int)number

{

if (_begintimearray.count != 0) {

    for(inti =0; i<_begintimearray.count; i++) {

        if(number == [[_begintimearrayobjectAtIndex:i]intValue]) {

            self.currentLine++;

            [self currentIndexTextIndexRow:self.currentLine];

        }else{

            NSIndexPath *indexpath = [NSIndexPath indexPathForRow:self.currentLine-1 inSection:0];

            KGCAssisiveCell*cell=[self.mTableViewcellForRowAtIndexPath:indexpath];

            cell.labelText.font= [UIFontsystemFontOfSize:13];

        }

    }

}

}

  • (void)currentIndexTextIndexRow:(int)row

{

  NSIndexPath *indexpath = [NSIndexPath indexPathForRow:row inSection:0];

  KGCAssisiveCell*cell=[self.mTableViewcellForRowAtIndexPath:indexpath];

  [self.mTableView selectRowAtIndexPath:indexpath animated:YES scrollPosition:UITableViewScrollPositionMiddle];

  cell.selectionStyle = UITableViewCellSelectionStyleDefault;

  cell.labelText.font = [UIFont systemFontOfSize:14];

}

pragma mark ---- 滑竿开始滑动

  • (void)progressSliderBeginVauleChange

{

[self.playerpause];

}

pragma mark ----- 滑竿停止滑动

  • (void)progressSliderVauleEndChange

{

if (self.PlayerStact == AVPlayerStatusReadyToPlay)// ljn-防止滑动崩溃

{

    __weaktypeof(self) weakSelf =self;

    CMTime changedTime = CMTimeMakeWithSeconds(self.mSlider.value, 1);

    [self.playerseekToTime:changedTimecompletionHandler:^(BOOLfinished) {

         [weakSelf.playerplay];

    }];

}

}

  • (void)removerNot

{

[self.mAVPlayerItem removeObserver:self forKeyPath:@"status"];

[self.mAVPlayerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];

[[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:self.mAVPlayerItem];

[[NSNotificationCenter defaultCenter] removeObserver:self];

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容