zoukankan      html  css  js  c++  java
  • IOS流媒体播放

     

    IOS流媒体播放

    1. 这里的流媒体地址是指服务端那边已经调好格式的可以在ios上播放的视频流。

    下面提供几个视频流的地址:

    NSString *linkStr = 

    http://61.160.227.6/rtencode_m3u8?bl=/f4v/61/140783661.h264_2.f4v&t=8&em=1&se=c629000050724fef&k=8bb5b375af9ab17fa859074fb394455fcd7505",

    @"http://61.160.230.12/rtencode_m3u8?bl=/f4v/85/140698785.h264_2.f4v&t=8&em=1&se=b245000050723fb4&k=0dfa39da8293f0684c6cd84fb395905fcd7505",

    @"http://58.215.144.42/rtencode_m3u8?bl=/f4v/46/140739646.h264_1.f4v&t=8&em=1&se=751300005072e2d8&k=8d77cf2355c3bf817f6e364fb396005fcd7505“

     @"http://ocj2.smgbb.cn/ocj1/ocj1.m3u8"

     @"http://ocj2.smgbb.cn/ocj2/ocj2.m3u8"

     

    2.播放视频

      CustomPlayerView.h 文件

     

      #import <UIKit/UIKit.h>

      #import <AVFoundation/AVFoundation.h>

     

      @interface CustomPlayerView : UIView

      @property(nonatomic,retainAVPlayer *player;

      @end

      CustomPlayerView.m 文件

      #import "CustomPlayerView.h"

     

      @implementation CustomPlayerView

      +(Class)layerClass{

          return [AVPlayerLayer class];

      }

     

      -(AVPlayer*)player{

          return [(AVPlayerLayer*)[self layer]  player];

      }

     

      -(void)setPlayer:(AVPlayer *)thePlayer{

          return [(AVPlayerLayer*)[self layer]  setPlayer:thePlayer];

      }

      @end

     

      CustomMoviePlayerController.h 文件

      #import <UIKit/UIKit.h>

      #import "CustomPlayerView.h"

      #import "MBProgressHUD.h"

     

      @interface CustomMoviePlayerController : UIViewController<UIPopoverControllerDelegate>{

          IBOutlet CustomPlayerView *moviePlayeView;

          IBOutlet UIButton *playButton;

          IBOutlet UISlider *movieProgressSlider;

          //视频的总时间

          CGFloat totalMovieDuration;

          IBOutlet UILabel *currentTimeLabel;

          IBOutlet UILabel *totalTimeLabel;

          MBProgressHUD *loadingView;

      }

      @property(nonatomic,retainNSURL *movieURL;

      -(IBAction)doneClick:(id)sender;

      -(IBAction)playClick:(id)sender;

      -(IBAction)movieProgressDragged:(id)sender;

      @end

    CustomMoviePlayerController.m文件

    //

    //  CustomMoviePlayerController.m

    //  VideoStreamDemo2

    //

       

                     

     

    #import "CustomMoviePlayerController.h"

     

    @interfaceCustomMoviePlayerController()

    -(void)initPlayer;

    -(void)monitorMovieProgress;

    -(NSString*)convertMovieTimeToText:(CGFloat)time;

    -(void)initMoviewPreview;

    -(CustomPlayerView*)previewViewCreate:(CGFloat)xOffsetInSlider;

    @end

     

    @implementation CustomMoviePlayerController

    @synthesize movieURL;

    #pragma mark - View lifecycle

     

    - (void)viewDidLoad

    {

        [superviewDidLoad];

        // Do any additional setup after loading the view from its nib.

        loadingView = [[MBProgressHUDalloc]initWithView:self.view];

        loadingView.labelText = @"正在加载...";

        [self.view  addSubview:loadingView];

        [self  initPlayer];

        [self  monitorMovieProgress];

        [self   initMoviewPreview];

     

    }

     

    - (void)dealloc {

        [movieURL release];

        [loadingViewrelease];

        //释放对视频播放完成的监测

        [[NSNotificationCenterdefaultCenter]removeObserver:selfname:AVPlayerItemDidPlayToEndTimeNotificationobject:moviePlayeView.player.currentItem];

        //释放掉对playItem的观察

        [moviePlayeView.player.currentItemremoveObserver:self

                                               forKeyPath:@"status" 

                                                  context:nil];

        [moviePlayeViewrelease];

        [super dealloc];

    }

     

    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

    {

        // Return YES for supported orientations

        return interfaceOrientation!=UIInterfaceOrientationPortraitUpsideDown;

    }

     

    -(void)initPlayer{

        //显示loadingView

        [loadingView  show:YES];

        //使用playerItem获取视频的信息,当前播放时间,总时间等

        AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:movieURL];

        //player是视频播放的控制器,可以用来快进播放,暂停等

        AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];

        [moviePlayeView setPlayer:player];

        [moviePlayeView.player  play];

        //计算视频总时间

        CMTime totalTime = playerItem.duration;

        //因为slider的值是小数,要转成float,当前时间和总时间相除才能得到小数,因为5/10=0

        totalMovieDuration = (CGFloat)totalTime.value/totalTime.timescale;

        //NSLog(@"totalMovieDuration:%f",totalMovieDuration);

        //在totalTimeLabel上显示总时间

        totalTimeLabel.text = [selfconvertMovieTimeToText:totalMovieDuration];

        

        //检测视频加载状态,加载完成隐藏loadingView

        [moviePlayeView.player.currentItemaddObserver:self

                                            forKeyPath:@"status" 

                                               options:NSKeyValueObservingOptionNew

                                               context:nil];

        //添加视频播放完成的notifation

        [[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(moviePlayDidEnd:)name:AVPlayerItemDidPlayToEndTimeNotificationobject:moviePlayeView.player.currentItem];

    }

     

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

    //    NSLog(@"keyPath:%@,object:%@",keyPath,NSStringFromClass([object class]));

        if ([keyPath isEqualToString:@"status"]) {

            AVPlayerItem *playerItem = (AVPlayerItem*)object;

            if (playerItem.status==AVPlayerStatusReadyToPlay) {

                //视频加载完成,隐藏loadingView

                [loadingView hide:YES];

            }

        }

    }

     

    -(NSString*)convertMovieTimeToText:(CGFloat)time{

        //把秒数转换成文字

        if (time<60.f) {

            return [NSString stringWithFormat:@"%.0f",time];

        }else{

            return [NSString stringWithFormat:@"%.2f",time/60];

        }

    }

     

    -(void)monitorMovieProgress{

        //使用movieProgressSlider反应视频播放的进度

        //第一个参数反应了检测的频率

        [moviePlayeView.playeraddPeriodicTimeObserverForInterval:CMTimeMake(11)queue:NULLusingBlock:^(CMTime time){

            //获取当前时间

            CMTime currentTime = moviePlayeView.player.currentItem.currentTime;

            //转成秒数

            CGFloat currentPlayTime = (CGFloat)currentTime.value/currentTime.timescale;

            movieProgressSlider.value = currentPlayTime/totalMovieDuration;

            //用label显示当前播放的秒数

            //判断秒数是否满一分钟,如果不满一分钟显示秒,如果满一分钟,显示分钟

            currentTimeLabel.text = [self convertMovieTimeToText:currentPlayTime];

            //NSLog(@"currentTimeLabel.text:%@",currentTimeLabel.text);

        }];

    }

     

    -(void)moviePlayDidEnd:(NSNotification*)notification{

        //视频播放完成,回退到视频列表页面

        [self doneClick:nil];

    }

     

    -(IBAction)doneClick:(id)sender{

        //停止播放,不然页面dimiss了以后,还有播放的声音

        [moviePlayeView.playerpause];

        [selfdismissModalViewControllerAnimated:YES];

    }

     

    -(IBAction)playClick:(id)sender{

        //播放暂停控制,进入页面就开始播放视频,然后播放按钮的文字是暂停

        //点击一下播放视频停止,按钮文字变成播放

        //判断是播放还是暂停状态

        if ([[playButtontitleForState:UIControlStateNormal]isEqualToString:@"暂停"]) {

            //从播放状态进入暂停

            [moviePlayeView.playerpause];

            [playButtonsetTitle:@"播放"forState:UIControlStateNormal];

        }else{

            //从暂停状态进入播放

            [moviePlayeView.playerplay];

            [playButtonsetTitle:@"暂停"forState:UIControlStateNormal];

        }

    }

     

    -(IBAction)movieProgressDragged:(id)sender{

        //拖动改变视频播放进度

        //计算出拖动的当前秒数

        NSInteger dragedSeconds = floorf(totalMovieDuration*movieProgressSlider.value);

        NSLog(@"dragedSeconds:%d",dragedSeconds);

        //转换成CMTime才能给player来控制播放进度

        CMTime dragedCMTime = CMTimeMake(dragedSeconds, 1);

        [moviePlayeView.playerpause];

        [moviePlayeView.player seekToTime:dragedCMTime completionHandler:^(BOOL finish){

            [moviePlayeView.playerplay];

        }];

    }

     

    //长按手势

    -(void)initMoviewPreview{

        UILongPressGestureRecognizer *longPress =          [[UILongPressGestureRecognizeralloc]initWithTarget:selfaction:@selector(progessSliderLongPress:)];

        [movieProgressSlideraddGestureRecognizer:longPress];

        [longPress release];

    }

     

    -(void)progessSliderLongPress:(UILongPressGestureRecognizer*)theLong{

        //因为长按手势的方法最少会被调用两次,所以为了不重复弹出popOver进行判断,只调用一次弹出popOver

        if (theLong.state==UIGestureRecognizerStateBegan) {

            //长按以后弹出popView在长按的位置

            CGPoint touchPoint = [theLong locationInView:self.view];

            //只能显示在进度条上方

            CGRect popOverFrame = CGRectMake(touchPoint.x-100, movieProgressSlider.frame.origin.y, 200, 150);

            UIViewController *previewMovieController = [[UIViewController alloc]init];

            //通过长按手势在slider的位置,计算视频预览的时间

            CGPoint touchPointInSlider = [theLong locationInView:movieProgressSlider];

            CustomPlayerView *previewView = [self previewViewCreate:touchPointInSlider.x];

            

            previewMovieController.view.backgroundColor = [UIColor whiteColor];

                    previewMovieController.view = previewView;

            UIPopoverController *popoverController = [[UIPopoverControlleralloc]initWithContentViewController:previewMovieController];

            //更改popover的contentSize

            popoverController.delegate = self;

            popoverController.popoverContentSize = CGSizeMake(200, 150);

            //箭头向下,指向进度条

            [popoverController presentPopoverFromRect:popOverFrameinView:self.viewpermittedArrowDirections:UIPopoverArrowDirectionDownanimated:YES];

            //播放视频

            [previewView.player play];

            [previewMovieController release];

            //不能在这里使用release和autorelease,因为popOver正在使用,release会导致crash

            //[popoverController release];

        }

    }

     

    //为了使调用视频预览的代码更清晰,把创建playerView的代码和创建popover的分开

    -(CustomPlayerView*)previewViewCreate:(CGFloat)xOffsetInSlider{

        //        NSLog(@"touchPoint:%@,touchPointInSlider:%@",NSStringFromCGPoint(touchPoint),NSStringFromCGPoint(touchPointInSlider));

        //把touchPointInSlider。x除以slider的宽度可以计算出预览的进度

        CGFloat previewValue = xOffsetInSlider/movieProgressSlider.bounds.size.width;

        //如果长按在进度条的中间,那么previewValue就是0。5,乘以视频的总时间,就知道了视频预览的时间

        NSInteger previewSeconds = floorf(previewValue*totalMovieDuration);

        //秒数舍弃小数部分,转换成cmTime

        CMTime previewCMTime = CMTimeMake(previewSeconds, 1);

        //初始化视频预览的view

        CustomPlayerView *previewView = [[CustomPlayerView alloc]initWithFrame:CGRectMake(0, 0, 200, 150)];

        AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:movieURL];

        //跳到视频预览的时间

        [playerItem seekToTime:previewCMTime];

        //player是视频播放的控制器,可以用来快进播放,暂停等

        AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];

        [previewView setPlayer:player];

        return [previewView autorelease];

    }

     

    - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController{

        //popOver已经使用完毕,release是可以的

        [popoverController release];

    }

    @end

     
  • 相关阅读:
    [BZOJ4029][HEOI2015]定价
    [BZOJ3261]最大异或和
    [BZOJ3166][Heoi2013]Alo
    [BZOJ1030][JSOI2007]文本生成器
    [BZOJ2595][Wc2008]游览计划
    Speculative store buffer
    十四 oracle 视图
    十三oracle --控制结构(分支,循环,控制)
    十二、oracle 数据库(表)的逻辑备份与恢复
    十一、oracle 数据库管理员
  • 原文地址:https://www.cnblogs.com/iOS-mt/p/4325202.html
Copyright © 2011-2022 走看看