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,retain) AVPlayer *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,retain) NSURL *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(1, 1)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

 

IOS流媒体播放的更多相关文章

  1. iOS中 流媒体播放和下载 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博 iOS中关于流媒体的简介:介于下载本地播放与实时流媒体之间的一种播放形式,下载本地播放必须全部将文件下载完成后才能播 ...

  2. m4a文件在iOS上的流媒体播放

    Date: 2016-03-23 Title: m4a文件在iOS上的流媒体播放 Tags: m4a, mp4, iOS, Android URL: m4a-streaming-play-on-mob ...

  3. 寒城攻略:Listo 教你用Swift 语言编写 IOS 平台流媒体播放器

    先展示播放器效果:   依然继承 Listo 本人的强迫症,还是从最初到完毕完整的写一个攻略来记录一下,这里声明 Listo 本人也是看了非常多的戴维营攻略才总结分享给大家这一篇攻略的. 首先,Lis ...

  4. EasyPlayer iOS开源流媒体播放器中AAC解码PCM问题

    本文转自EasyDarwin开源团队成员Penggy的博客:http://www.jianshu.com/p/feeb107b6657 最近遇到在 iOS 平台上实时播放 AAC 音频数据流, 一开始 ...

  5. iOS开发系列--音频播放、录音、视频播放、拍照、视频录制

    --iOS多媒体 概览 随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制, ...

  6. ios项目里扒出来的json文件

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Menlo; color: #000000 } p.p2 { margin: 0.0px 0. ...

  7. Github上关于iOS的各种开源项目集合(强烈建议大家收藏,查看,总有一款你需要)

    下拉刷新 EGOTableViewPullRefresh - 最早的下拉刷新控件. SVPullToRefresh - 下拉刷新控件. MJRefresh - 仅需一行代码就可以为UITableVie ...

  8. IOS多媒体

    概览 随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制,还是对麦克风.摄像 ...

  9. 《转》iOS音频视频初级开发

    代码改变世界 Posts - 73, Articles - 0, Comments - 1539 Cnblogs Dashboard Logout HOME CONTACT GALLERY RSS   ...

随机推荐

  1. VCC、VDD、VEE、VSS

    转载自:http://www.cnblogs.com/asus119/archive/2011/10/11/2206841.html 版本一: 简单说来,可以这样理解: 一.解释 VCC:C=circ ...

  2. Qt编程之Qt样例表(QSS)

    For a long time, Qt has allowed you to decorate your GUIs with CSS’ish style sheets. Inspired by the ...

  3. left join 关联条件位置

    select e.last_name, e.department_id, d.department_name from hr.employees e left outer join hr.depart ...

  4. 【转】[教程]隐藏ActionBar中的MenuItem

    原文网址:http://blog.csdn.net/appte/article/details/12104823 有时候我们需要在不同的时候改变ActionBar中MenuItem的项数,或者隐藏某些 ...

  5. ios9邮箱添加163邮箱

    电脑登陆163邮箱➡️设置➡️开启pop3/smtp/imap功能➡️保存.开启后系统会给你个"客户端授权密码",同时会发短信到你手机里. 打开手机,设置➡️邮件,通讯录,日历➡️ ...

  6. 如何右键新建HTML

    直接转载的,原文作者写的很详细:http://blog.csdn.net/ruanjiayou/article/details/51284864 14年在qq日志里写过 2014-10-25  htt ...

  7. css(二)

    重新排传智的首页!头部和左边的部分完成了! <!doctype html> <html lang="en"> <head> <meta c ...

  8. HybridApp开发准备工作——WebView

    如大家所见,手机真是越来越离不开我们的日常生活了,像我,现在出门必带的是手机.移动电源.公交卡:钱包什么的再也没出过门.两年前,我还在Android的应用开发中当了一次过客.嗯,当时JAVA学得太糟糕 ...

  9. php form表单post提交获取不到数据,而使用get提交能获取到数据 的解决办法

    开发环境:xampp,mac,phpstorm 其实出现这个问题的原因就是在于phpstorm,它默认使用的是自带的内部服务器,这个服务器使用63342端口,而且服务器内部有问题,导致POST方法异常 ...

  10. ZigBee心电传输(三)

    这段时间因为另外一个项目需要,我搞Zed板去了.现在接着上一步的工作吧,继续把心电做完.这里想要测试一下把心电波形数据传输出来,然后用协调器接收,并从串口显示出来.之后再用ZigBee转蓝牙,从而可以 ...