Java网络视频点播系统.docx
《Java网络视频点播系统.docx》由会员分享,可在线阅读,更多相关《Java网络视频点播系统.docx(28页珍藏版)》请在冰点文库上搜索。
Java网络视频点播系统
课程设计计划书
设计题目:
Java网络视频点播系统
系别:
计算机系
专业:
计算机科学与技术
题目:
Java网络视频点播系统
设计目标:
1)类似暴风播放器可以在本地实现mpeg,avi等常用格式的播放,可以通过菜单设定定时截取视频成静态图像(如按照用户要求如0.05秒,0.1秒,1秒,2秒,5秒,10秒等)按照jpg格式保存在指定的目录,并在播放视频的同时展开这些图像文件,动态扩展。
(基本要求)
2)可以在局域网内按照B/S架构或者apache服务器中开展视频点播(高级要求)
提示:
可以用JMF类库实现以上的功能,这里提供部分源码(《java网络程序设计》中的),可以在XX中下载源码并做修改!
网络功能可以参考java中的Socket类库!
设计环境:
JDK1.6,apache,JMF1.1,Eclipse或者My-Eclipse
目 录
1、引言
2、需求分析
3.、程序设计过程
3.1实验原理
3.2程序设计图
3.3程序布局结构图
3.4核心代码
4、实验结果
5、总结分析
6、参考文献
一.引言
1.1课题背景
随着宽带网络系统的建成和发展,视频点播(VideoOnDemand,简称V0D)系统被广泛应用于在线电影点播、多媒体课件点播、图书馆视频资料查询等用途。
视频点播是综合了计算机技术、通讯技术、电视技术而迅速兴起的一门综合性技术。
它涉及到信息量巨大的音频和视频在网上传播的问题,网络是硬件条件,而流媒体技术则解决了如何在网络上传输动态的音视频节目的难题。
1.2流媒体简介
流媒体是指传输及播放的流媒体文件,经过特殊的压缩方式分成一个个压缩包,由视频服务器向用户计算机连接、实时地传送,用户机不必等到整个文件全部下载完毕,仅需将起始几秒的数据先下载到本地的缓冲区中就可以开始播放,采用一边播放、一边下载、一边丢弃的方式,客户端的缓冲区建在内存中,不占用硬盘空间,不会在用户端留下任何拷贝,保护了知识产权,同时提高带宽利用率。
流媒体技术是一个综合的技术,它包括采集、编码、传输、储存、解码等多技术。
1.3本课题研究的意义
视频点播的本质是信息的使用者根据自己的需求主动获得多媒体信息,它区别于信息发布的最大不同:
一是主动性、二是选择性。
从某种意义上说这是信息的接受者根据自身需要进行自我完善和自我发展的方式,这种方式在当今的信息社会中将越来越符合信息资源消费者的深层需要,可以说视频点播是信息获取的未来主流方式在多媒体视音频方面的表现。
视频点播的概念将会在信息获取的领域快速扩展,具有无限广阔的发展前景。
二、需求分析
研制视频点播系统的总体目标是将网络技术、信息技术、现代管理技术相结合,建立视频点播和信息交流平台。
视频点播系统采用流媒体技术,充分利用了网络资源,为广大用户提供在线点播服务,
本系统首先要实现动态性。
所谓的动态性就是能动态更新内容,如更新用户信息、视频文件信息、用户留言等。
这要求与数据库有良好的连接。
2.1任务目的:
1.实现视频文件的正确播放;
2.能够实现对视频播放的控制,如暂停,播放,快进,快退,上一个,下一个等功能;
3.能够进行文件视频的选择,全屏,音量的控制,拖动,播放模式的控制等;
4.任意改变播放视频界面大小等功能。
2.2要求掌握:
1.掌握Java的语言规范,面向对象的核心概念和特性。
2.掌握Java的编程技术,包括异常处理,图形界面设计,多线程,网络通信程序等。
3.掌握Java应用软件的开发环境和开发过程
4.掌握基于Jsp网站的开发环境和开发过程
5.掌握面向对象的思想和程序设计方法。
2.3程序的设计、调试、运行的软件环境需求:
操作系统:
Windows7
数据库及数据库管理软件:
SQLServer2000
JDK环境:
JavaSEDevelopmentKit(JDK)Version6
开发工具:
Eclipse3.2
运行平台:
Windows、Linux各个版本、MAC等任何平台
运行环境:
JavaSERuntimeEnvironment(JRE)Version
2.4用户身份级别要求
即根据身份的不同对系统的使用权限有所不同。
从权限大小大致可以分为:
系统管理员、注册用户、发布员、未注册用户。
系统提供灵活的角色设定和权限的分配功能。
系统管理员:
是权限最大的用户,拥有视频点播系统的所有权限,主要负责对系统平台的日常网络维护管理,可以对系统进行修改,排除故障。
发布员:
拥有注册用户的权限并可以上传视频文件。
注册用户:
权限包括查看系统中视频的信息、点播及下载视频、发表言论、投票等。
未注册用户:
是权限最小的用户,只能查看系统中视频的信息。
2.5系统功能需求与划分
用户管理:
对使用本系统注册用户信息的操作。
包括删除用户、修改密码、权限的设置等操作。
用户注册:
未注册用户可以注册新的帐号,在注册页面填写相关的注册信息,添加注册信息到系统的数据库中,以后就能用该账户登录到系统中。
用户登录:
注册用户填写登录信息经过系统验证之后就能浏览该账户的权限所能访问的页面。
具体操作:
在登录表中填入相关信息,系统验证信息是否正确,如果正确就允许用户登录到系统中,用户可以访问该账户所允许访问的页面。
没有注册的用户需先注册。
用户权限验证:
验证用户的权限是否能够访问用户要求访问的页面。
具体操作:
用户登录时验证用户输入的登录信息是否正确,如果正确就读取数据库中该账户的权限字段并储存到系统中,当用户要求访问某个页面时就验证该用户的权限是否能访问该页面。
视频点播和下载模块:
点播和下载视频文件
视频文件管理:
系统管理员根据用户需求添加或删除视频文件,发布员根据用户需求上传视频文件。
具体操作:
对视频文件参数的基本设置。
包括添加、删除、修改等。
注销:
所有的系统合法用户登录完成操作后退出系统都要进行“注销”操作、或者进行用户转换也需要进行“注销”操作。
操作对象:
所有合法用户。
三.程序设计过程
3.1实验原理
JMF提供了一个平台无关的框架来呈现时基媒体(time-basedmedia)。
JavaMediaPlayerAPI的设计目标是支持多种标准的媒体格式,包括MPEG-1,MPEG-2,QuickTime,AVI,WAV,AU和MIDI.使用JMF,可以同步呈现不同来源的时基媒体。
现有的一些媒体播放器都严重依赖原生码来执行解压缩、渲染等计算密集型任务。
而JMFAPI则隐藏了具体实现,只提供抽象的编程接口。
举例来说,一个用JMF制作的播放器,具体运行的过程中可能会调用到操作系统的本地方法,但开发者写代码时可以无视本地方法的存在。
JMFPlayerAPI:
接入不同的协议和分发(传输)机制;接入不同的媒体数据类型
定义事件模型,用于Player和应用程序间的异步通信
3.2数据源(DataSource)
一个DataSource封装了媒体的地址、协议和分发的软件。
一个JavaMediaPlayer包含一个DataSource。
一旦创建,这个DataSource不能被用于其他媒体的传输。
一个Player的数据源可以用MediaLocator或URL来标示。
MdiaLocator(媒体定位器)是一个JMF类,用来描述Player播放的媒体。
MediaLocator与URL类似,并且可以从URL来创建。
他们的区别在于,在Java中,URL只有其协议是已知协议时才能被创建,而MediaLocator则没有这个限制。
Java媒体播放器可以播放来自多种数据源的媒体数据,包括本地、网络文件和实时广播等。
JMF支持两种不同的数据源。
PullData-Source(数据源被动的被获取)-由客户端发起数据传输并控制数据流,已知的协议包括HTTP(超文本传输协议)和本地文件。
PushData-Source(数据源主动推送)-由服务器发起数据传输并控制推送数据流。
此类数据源包括广播媒体,多点传送的媒体和VOD(视频点播)。
客户端程序所能够控制的度量,取决于媒体源的类型。
举个例子说,MPEG文件可以被重定位(reposition),那么播放MPEG的客户端程序就可以允许用户重播或者跳进至一个新时间点;而由服务器段控制的广播媒体则不能被重定位;另外VOD协议则支持有限的用户操作,比如一个VOD客户端程序可以允许用户跳进至新位置,但不能快进和快倒。
3.2.1Players
一个JavaMediaPlayer是一个对象。
她基于时间来处理数据流,从DataSource读取数据并在确切的时间点渲染媒体。
一个JavaMediaPlayer必须实现Playerinterface.
Clock定义了基本的计时和同步操作,她被Player用来控制媒体的呈现。
Controller继承Clock对外提供提供如下方法:
1.管理系统资源
2.预载数据
3.提供监听机制(Observable),对外发送媒体事件通知
∙Duration提供了检测媒体时长的途径。
∙Player支持标准的用户控制,并放宽了来自于Clock的一些操作限制。
多个Player共享一个公共的计时和同步模型。
一个Player的媒体时间表示了媒体流的当前位置。
每一个Player有一个TimeBase。
TimeBase定义了Player的时间流逝。
当一个Player被执行start,他的媒体时间会被映射到time-base时间。
如多个媒体要同步,那么他们必须使用同一个TimeBase.
一个Player的用户界面可以包含一个可视组件和一个控制面板组件(control-panelcomponent)。
我们用的时候可以选择实现一个自定义的用户界面,或者使用Player的默认的控制面板组件。
一般来说,一个Player在能够呈现媒体之前,必须先执行一序列的操作。
而这些操作有可能会耗费一定的时间,所以JMF定义了一些操作状态,并且提供了状态转换的操作机制。
3.2.2MediaEvents
JMF事件报告机制允许我们的程序响应媒体驱动的错误,比如数据丢失或资源不可用。
事件系统同时也提供了重要的通知协议;当我们的程序调用一个Player的异步方法时,只有当收到响应的事件消息时,才能确认操作是否完成。
有两种JMF对象会抛出事件,他们是:
GainControl对象和Controller对象。
对于事件,GainControl和Controller遵循JavaBeans形式。
GainControl对象只抛出一种类型的事件GainChangeEvent。
我们通过实现GainChangeListenerinterface来响应gain(增益?
)的变化。
Controller则会抛出多种派生自ControllerEvent的事件。
我们通过实现ControllerListenerinterface来接收诸如Player的Controller抛出的事件消息。
下图显示了Controller抛出的各种事件类型:
ControllerEvents可分为三类:
改变通知、关闭事件和转换事件
变化通知(Changenotificationevents)诸如RateChangeEvent和DurationUpdateEvent。
他们表示Player的一些属性数值发生了变化。
这类事件通常是对一些方法调用的回馈。
例如,一个Player的setRate方法被调用,他会抛出一个RateChangeEvent.
转换事件(TransitionEvents)让我们的程序能够响应Player的状态变化。
当Player从一个状态转换到另一个状态时,就会抛出一个转换事件。
(在1.4中,我们会提供更多的关于Player状态的信息)
当player关闭时,则会抛出关闭事件(ControllerClosedEvents)。
当一个Player不再可用时,抛出ControllerClosedEvent.ControllerErrorEvent(控制器错误事件)则是关闭事件的一个特例。
我们写程序时,通过监听控制器错误事件,可以对Player故障作出响应,从而增进用户体验。
3.2.3PlayerStates
JavaMediaPlayer有6种状态。
Clock接口定义了两种主要的状态:
Stopped和Started。
在普通操作中,Plyaer在到达Started状态前,会逐个通过上图中的每一个状态。
Unrealized(未实现)状态表示Player已经被实例化,但还不知道媒体的任何信息。
当Player第一次被创建,他的状态就是Urealized。
Player的realize方法被调用后,会从Unrealized转入Realizing(实现中)状态。
这时的Player应该正在检测资源需求。
在relization过程中,Player会获取只需加在一次的资源。
这些资源包括非独享的渲染资源。
(独享资源指的受限的资源。
例如只能被一个播放器使用的个别硬件资源,此类资源会在预取(Prefetching)的过程中加载。
)Realizing中的Player常常通过网络下载东西。
Player结束Realizing状态后,会转入Realized(已实现)状态。
这个状态下,Player会知道他需要哪些资源,还知道媒体的类型信息。
因为RealizedPlayer知道怎样渲染数据,所以他能够提供可视组件和控件。
此时,Player与其他系统对象的连接已经就位,但此时还不会占用任何会阻止其他Player启动的资源。
Prefetch被调用后,Player会从Realized状态转入Prefetching(预取中)状态。
此时播放器在为呈现媒体作准备,包括调用媒体数据、获取独享资源和其他一些准备工作。
在媒体呈现过程中,一些操作可能会导致Prefetching状态重现,例如重新定位播放位置、播放器请求额外的缓冲区等。
当Player结束预取,将转入Prefetched(预取完成)状态。
此时Player已经准备开始播放但尚为实际开始。
调用start方法将使Player转入Started状态。
此时,Player的媒体时间被映射到time-base时间,并且clock开始运行。
此时播放器有可能会等待一个恰当的时间来呈现媒体数据。
当player从一个状态转入另一个状态时,会抛出TransitionEvents(转换事件),我们可以通过实现ControllerListener接口来监听这些时间并作出恰当的响应。
当播放器开始Realizing和Prefetching的时候,我们可以使用事件报告机制对Player进行管理,在调用Player方法之前,我们可以先检查Player状态,在作出恰当的操作。
3.2.4CallingJMFMethods调用JMF方法时的一些约定
JMF对于errors(错误)和exceptions(异常)作如下约定。
JavaMediaErrors是当程序调用了一个当前状态下非法的方法时抛出的。
Errors是在外部程序有控制权的状态下执行了非法的请求而抛出的。
举例来说,调用一个处于Started的Player的方法时抛出的就是error。
开发者有责任在调用方法前确认Player已被停止。
JMFerror是可以通过优化代码来避免的,应用程序不应该捕获JMFerrors,好的应用程序不会碰到这些错误。
JavaMediaExceptions是当程序调用了不能完成的方法或在当前状态下不适用的方法。
Exceptions是在外部程序没有控制权的状态下抛出的。
例如当我们试图同步两个time-base不匹配的Player时,就会抛出异常。
之所以是异常而不是错误,是因为我们无从检测time-base是否匹配,是无法预期的。
有时,JMF的一些方法会返回非预期的结果,通过检查返回直,我们可以检测实际发生的事情:
我们可以通过返回直检查实际被设置的数值,例如:
并不是所有的播放器都可以每周期5次的速率呈现媒体数据,如果我们调了setRate(5.0),播放器将会设置一个合法的近似直,这个数值可能是5.0也可能是1.0,我们需要检查返回数据来确认被设置的数据。
有时,我们请求的信息是不可用的。
例如:
Player在播完一个媒体之前,可能不知道媒体的时长,这时如果我们调了getDuration(),getDuration会返回DURATION_UNKNOWN.当媒体被播放完一次,再调getDuration时,则会返回正确的时长。
3.3程序设计图
3.4程序布局结构图
图程序的布局结构如下(树形结构图):
3.5核心代码:
/******************************************************/
publicppp(Strings){//构造函数
super(s);
setComponentProperty();
addPlayListListener();
addPlayButtonListener();
addPlayMenuListener();
addRightClickListener();
addFrameChangeListener();
}//构造函数结束
/******************************************************/
publicvoidaddPlayListListener(){//对list列表中鼠标事件进行监听并处理
list.addMouseListener(newMouseAdapter(){//list列表监听事件
publicvoidmousePressed(MouseEvente){
//super.mousePressed(e);
System.out.println(e.getModifiers());//通过这个函数返回值区分是单击还是双击
intmods=e.getModifiers();
if(mods==4){//4时为右击
popupMenuList.add(menuItem_playSelect);
popupMenuList.add(menuItem_delete);
popupMenuList.add(menuItem_Addfile);
popupMenuList.add(menuItem_deleteAll);
popupMenuList.show(list,e.getX(),e.getY());
}
}
publicvoidmouseClicked(MouseEvente){
if(e.getClickCount()==2){//在列表框中双击事件
for(inti=0;iif(fileDirection.get(i).toString().endsWith(list.getSelectedValue().toString()))
try{
startPlayer(fileDirection.get(i).toURL().toString());//开始播放选中文件
but_play.setIcon(newImageIcon("pause.png"));
play_temp=true;
IsPlaying=true;
break;
}catch(MalformedURLExceptionE){
E.printStackTrace();
}
}
}
});
menuItem_delete.addMouseListener(newMouseAdapter(){//单击list中“从列表中删除”事件
publicvoidmousePressed(MouseEvente){
model.removeElement(list.getSelectedValue());
fileName.removeElement(list.getSelectedValue());
fileDirection.removeElement(list.getSelectedValue());
}
});
menuItem_playSelect.addMouseListener(newMouseAdapter(){//单击list中“播放选中文件”事件
publicvoidmousePressed(MouseEvente){
try{
for(inti=0;iif(fileDirection.get(i).toString().endsWith(list.getSelectedValue().toString()))
{
startPlayer(fileDirection.get(i).toURL().toString());
System.out.println(fileDirection.get(i).toURL().toString());
but_play.setIcon(newImageIcon("pause_.png"));
play_temp=true;
IsPlaying=true;
}
}catch(MalformedURLExceptione1){
e1.printStackTrace();
}
}
});
menuItem_Addfile.addMouseListener(newMouseAdapter(){//单击list中“向列表中添加”事件
publicvoidmousePressed(MouseEvente){
JFileChooserfileChooser=newJFileChooser();//实例化文件选择器
fileChooser.setMultiSelectionEnabled(true);//可以同时选中多个文件
fileChooser.setFileFilter(newMyFileFilter());//设置文件选择时选择的文件的默认类型
fileChooser.showOpenDialog(ppp.this);//显示对话框
File[]mediaFiles=fileChooser.getSelectedFiles();//得到选择的文件