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 [AVPlayerLayerclass];
}
-(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
//
// Created by 劉 大兵 on 12-5-17.
// Copyright (c) 2012年 中華中等專業學校. All rights reserved.
//
#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.viewaddSubview:loadingView];
[selfinitPlayer];
[selfmonitorMovieProgress];
[selfinitMoviewPreview];
}
- (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
[loadingViewshow:YES];
//使用playerItem獲取視頻的信息,當前播放時間,總時間等
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:movieURL];
//player是視頻播放的控制器,可以用來快進播放,暫停等
AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
[moviePlayeView setPlayer:player];
[moviePlayeView.playerplay];
//計算視頻總時間
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 = [[UIPopoverController alloc]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