标签:
1、概述
流媒体技术是一种专门用于网络多媒体信息传播和处理的新技术,该技术能够在网络上实现传播和播放同时进行的实时工作模式,相对于其他的一些音、视频网络传输和处理技术,流媒体比较成熟和使用,目前已经成为网上音、视频(特别是实时音视频)传输的主要解决方案。
流媒体与常规视 频媒体之间的不同在于,流媒体可以边下载边播放。“流”的重要作用体现在可以明显的节省时间,由于常规视频媒体文件比较大,并且只能下载下来后才能播放, 因此下载需要很长的时间,妨碍了信息的流通,流媒体的应用是近几年来Internet发展的产物,广泛应用于远程教育、网络电台、视频点播、收费播放等。
目前,制约流媒 体宽带应用发展的关键在于互联网的服务质量,流媒体从理论上解决了大容量网络多媒体数据传输的实时性要求问题,但是由于大型分组交换网络中数据传输受到诸 多因素的影响,网络的状况是不可靠的,其带宽、负荷等的变化难以满足流媒体宽带业务的实时性服务质量要求。并且常常造成播放卡壳、延迟、视频抖动剧烈,给 使用者感官造成很大影响,所以解决好流媒体网络应用的服务质量问题对于流媒体宽带应用是极为重要的。
2、流媒体技术原理
流媒体的传输的 实现需要缓存。因为Internet以分组传输为基础进行断续的异步传输,对一个实时的A/V源或存储的A/V文件。在传输中它们要被分解为许多的分组, 由于网络是动态变化的,各个分组选择的路由可能不尽相同,故到达客户端的时间延迟也就不等,甚至先发的数据分组有可能后到。为此,使用缓存系统来弥补延迟 和抖动的影响,并保证分组的顺序正确,从而使媒体数据能连续输出,而不会因为网络暂时拥塞使播放出现停顿。
流媒体传输的实现需要合适的传输协议。由于TCP需要较多的开销,因此不太适合传输实时数据。在流媒体传输的实现方案中,一般采用HTTP/TCP来传输控制信息,而用RTP/UDP来传输实时声音数据。
图1 流媒体传输基本原理图
流媒体传输的过 程如图1所示。一般描述如下:用户选择某一流媒体服务后,Web浏览器与Web服务器之间使用HTTP/TCP交换控制信息,以便把需要传输的实时数据从 原始信息中检索出来,然后客户机上的Web浏览器启动A/V Helper程序,使用HTTP从Web服务器检索相关参数对Helper程序初始化。这些参数可能包括目录信息、A/V数据的编码类型或与A/V检索相 关的服务器地址。
A/V Helper程序及A/V服务器运行实时流协议(RTSP,Real-Time Streaming Protocol),以交换A/V传输所需的控制信息。与CD播放机或VCRs所提供的功能相似,RTSP提供了操纵播放、快进、快倒、暂停及录制等命令 的方法。A/V服务器使用RTP/UDP协议将A/V数据传输给A/V客户程序(一般可以认为客户程序等同于Helper程序),一旦A/V数据抵达客户 端,A/V客户程序即可播放输出。
需要说明的是,在流媒体传输中。使用RTP/UDP和RTSP/TCP两种不同的通信协议与A/V服务器建立联系,是为了能够把服务器的输出重定向到一个不同于运行A/V Helper程序所在客户机的目的地址。实现流媒体传输一般都需要专用服务器和播放器。
3、流媒体传输模式
流媒体之所以能够实现多媒体数据的实时播放是采用了专门的网络控制协议和数据传输机制。服务器端有专门的流媒体发布系统,而客户端则有专门的播放器,这两部分都需要通过数据缓存区进行数据的缓存。
与普通的分组交 换网络不同,流媒体系统的缓存区中的数据在数据传输过程中是动态的,也可成为是交换状态的,数据以堆栈方式进出缓冲区,而不需要等待数据全部达到客户机后 才从缓冲区中被释放出来,由于数据缓冲区中的数据是“流动”的,再加上数据的播放需要维持一个稳定的数据输出速度,随时都要求缓冲区有相应的数据提供给播 放器,如果没有相应的数据,则会出现内容播放过程中的暂停和画面的条约,出现前一种情况一般是由于网络传输速度跟不上数据的播放速度,而发生了数据的下 溢,而后一种情况的发生是由于网络传输速度过快,超过了播放的速度,而又没有适当的传输控制而造成的数据上溢。
4、网络传输与控制协议
多媒体业务流由于其数据量大、实时等特点,对网络传输也提出相应的要求,主要表现在高带宽、低传输时延、同步和高可靠性几方面。为了保证好的QoS,必须考虑传输模式、协议栈和应用体系控制等问题。以下主要讨论应用于流媒体实时控制和传输的几种协议。
4.1 RTP/RTCP协议簇
RTP/RTCP是 端对端基于组播的应用层协议。其中RTP(Realtime Transfer Protocol)用于数据传输,RTCP(Realtime Transfer Control Protocol)用于统计、管理和控制RTP传输,两者协同工作,能够显著提高网络实时数据的传输效率。
RTP和 RTCP都定义在RFC1889中。RTP用于在单播或多播情况下传输实时数据,通常工作在UDP上。RTP协议核心在于其数据包格式,它提供应用于多媒 体的多个域,包括VOD,VoIP,电视会议等,并且不规定负载的大小,因此能够灵活应用于各媒体环境。但RTP协议本身不提供数据包的可靠传送和拥塞控 制,必须依靠RTCP提供这些服务。RTCP的主要功能是为应用程序提供媒体质量信息。在RTP会话期间,每个参与者周期性地彼此发送RTCP控制包,包 中封装了发送端或接收端的统计信息。包括发送包数、丢包数、包抖动等,这样发送端可以根据这些信息改变发送速率,接收端则可以判断包丢失等问题出在哪个网 络段。总的来说,RTCP在流媒体传输中的作用有:QoS管理与控制、媒体同步和附加信息传递。
在RTP/RTCP协议基础上,不同的媒体类型需要不同的封装和管理技术。目前国际上正在研究基于RTP/RTCP的媒体流化技术,包括MPEG-1/2/4的媒体流化技术。
4.2 RSVP协议
资源预留协议 RSVP(Resource reSerVation Protocol)是针对IP网络传输层不能保证QoS和支持多点传输而提出的协议。RSVP在业务流传送前先预约一定的网络资源,建立静态或动态的传输 逻辑通路。从而保证每一业务流都有足够的“独享”带宽,因而能够克服网络的拥塞和丢包,提高QoS性能。
值得一提的 是,RSVP是由接收方执行操作的协议。接收方决定预留资源的优先级,并对预留资源进行初始化和管理。在网络节点(如路由器)上被要求预留的资源包括缓冲 区和带宽等,一般数据包通过位于网路节点上的“滤包器”使用预留资源,RSVP共有3种预留类型:无滤包器形式、固定滤包器形式和动态滤包器形式。
4.3 RTSP协议
实时流协议 (Real-Time Streaming Protocol)由RealNetworks和Netscape共同提出。是工作在RTP之上的应用层协议。它的主要目标是为单播和多播提供可靠的播放 性能。RTSP的主要思想是提供控制多种应用数据传送的功能。即提供一种选择传送通道的方法,例如UDP、TCP、IP多播,同时提供基于RTP传送机制 的方法。RTSP控制通过单独协议发送的流,与控制通道无关,例如,RTSP控制可通过TCP连接,而数据流通过UDP。通过建立并控制一个或几个时间同 步的连续流数据,其中可能包括控制流,RTSP能为服务器提供远程控制。另外,由于RTSP在语法和操作上与HTTP类似,RTSP请求可由标准HTTP 或MIME解析器解析,并且RTSP请求可被代理、通道与缓存处理。与HTTP相比,RTSP是双向的,即客户机和服务器都可以发出RTSP请求。
实现RTSP的系统必须支持通过TCP传输RTSP,并支持UDP。RTSP服务器的TCP和UDP缺省端口都是554。目前最新的微软Media Services V9和RealSystem都支持RTSP协议。
5、媒体价值链和运营模式
宽带流媒体业务 的价值链至少需要包括几个部分:应用提供商、内容开发商、业务支撑系统运营商、网络提供商、用户。其中,用户最终获得宽带流媒体应用业务,并为之付费。应 用提供商是宽带流媒体业务的直接提供者,直接面对用户提供业务。内容提供商是流媒体内容资源的拥有者,负责节目的制作,包括流媒体文件的生成、编码、压 缩。业务支撑系统运营商提供一个独立的可运营的管理和传输平台,为宽带流媒体应用提供支撑环境。网络提供商提供基本的承载网络。
目前,流媒体业务的运营模式还在不断发展中,网络运营商、应用提供商、内容提供商都在不断寻求成熟的运营模式和合作模式。
6、结束语
流媒体技术包含 了从服务器构架到网络协议等一系列技术,目前这些技术还在不断发展和完善中,同时各运营商也正在探索合适的商业模式。尽管如此,流媒体技术转变了传统互联 网限于文本和图片的二维呆板的内容表现形式,是宽带应用的发展方向。同时流媒体能够广泛应用于VOD、远程教学、网络广告、交互视频游戏等,大大拓宽服务 范围,因此各电信运营商都看好流媒体业务,并希望能够以此带动宽带产业进入高速发展的时期。可以预见,流媒体业务将成为宽带网络上的主流信息业务。
#import "ViewController.h"
@interface ViewController (){
//播放屏幕
PlayerView *_playerView;
UISlider *_proSlider;
//播放器
AVPlayer *_player;
}
@end
@implementation ViewController
- (BOOL)prefersStatusBarHidden{
return YES;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_playerView = [[PlayerView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 250)];
[self.view addSubview:_playerView];
_proSlider = [[UISlider alloc] initWithFrame:CGRectMake(50, 300, 250, 20)];
[_proSlider addTarget:self action:@selector(changeProgress) forControlEvents:UIControlEventValueChanged];
[self.view addSubview:_proSlider];
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(50, 350, 100, 40);
[button setTitle:@"play" forState:UIControlStateNormal];
[button addTarget:self action:@selector(play) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(200, 350, 100, 40);
[button setTitle:@"pause" forState:UIControlStateNormal];
[button addTarget:self action:@selector(pause) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:button];
//路径
NSString *path = [[NSBundle mainBundle] pathForResource:@"bsm" ofType:@"mp4"];
//转成url
NSURL *url = [NSURL fileURLWithPath:path];
//URL转成资源类
AVURLAsset *asset = [AVURLAsset assetWithURL:url];
//准备播放
[asset loadValuesAsynchronouslyForKeys:@[@"tracks"] completionHandler:^{
//资源类转成播放项
AVPlayerItem *item = [AVPlayerItem playerItemWithAsset:asset];
//播放器
_player = [[AVPlayer alloc] initWithPlayerItem:item];
//关联屏幕和播放器
[_playerView setPlayer:_player];
//在arc中,当两个对象互为强引用时,需改变其中一个强引用指针为弱引用指针,才能消除警告,一般不改变全局成员变量指针。
__weak AVPlayer *player = _player;
__weak UISlider *slider = _proSlider;
//添加进度 帧 帧/秒
[_player addPeriodicTimeObserverForInterval:CMTimeMake(1, 1) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
//当前时间/总时间
float pro = CMTimeGetSeconds(player/*_player*/.currentTime) / CMTimeGetSeconds(player.currentItem.duration);
[slider/*_proSlider*/ setValue:pro animated:YES];
}];
}];
}
//进度
- (void)changeProgress{
//当前时间 = 总时间*进度
CMTime currenttime = CMTimeMultiplyByFloat64(_player.currentItem.duration, _proSlider.value);
[_player seekToTime:currenttime];
}
//播放
- (void)play{
[_player play];
}
//暂停
- (void)pause{
[_player pause];
}
////////////////////////************************************************************//
#import "PlayerView.h"
@implementation PlayerView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
return self;
}
//将PlayerView实例化后,将要显示的是AVPlayer层,要不然显示的是self.view.layer层
+ (Class)layerClass{
return [AVPlayerLayer class];
}
- (void)setPlayer:(AVPlayer *)player{
//取出layer
AVPlayerLayer *layer = (AVPlayerLayer*)self.layer;
//关联播放起器
[layer setPlayer:player];
}
标签:
原文地址:http://www.cnblogs.com/wxw511518/p/4433316.html