说起实时流传输协议,没有做过的就会感到很陌生,但是项目组必须用到,就要去查资料,将其解决。我前不久做的项目正好碰上,就在此说说自己的拙见。既然用到rtsp,那很有可能是做的视频监控软件,毕竟他是需要实时监控周期场景的一举一动。
我们在实现播放rtsp协议之前,有以下几个问题需要搞定:
(1).什么是rtsp协议?他的协议头和协议头与http有什么区别,参数分别代表什么?
(2).如果利用Android的播放控件VideoView来播放RTSP的流,怎样与服务器进行桥接?
其实这些是前期准备工作,下边直接供应代码:
1.定义服务器连接和断开以及发生错误的接口。
- 
public interface IEvent{
- 
- 
/**
- 
- 
*当channel得到connect事件时调用这个方法.
- 
- 
*@paramkey
- 
- 
*@throwsIOException
- 
- 
*/
- 
- 
public void connect(SelectionKeykey)throwsIOException;
- 
- 
/**
- 
- 
*当channel可读时调用这个方法.
- 
- 
*@paramkey
- 
- 
*@throwsIOException
- 
- 
*/
- 
- 
public void read(SelectionKeykey)throwsIOException;
- 
- 
/**
- 
- 
*当channel可写时调用这个方法
- 
- 
*@throwsIOException
- 
- 
*/
- 
- 
public void write()throwsIOException;
- 
- 
/**
- 
- 
*当channel发生错误时调用.
- 
- 
*@parame
- 
- 
*/
- 
- 
public void error(Exceptione);
- 
- 
}
2.用线程来控制实时播放的情况,实现接口
- 
publicclassRTPHandleextendsThreadimplementsIEvent{
- 
- 
privatefinalStringTAG=“RTPHandle”;
- 
- 
privatestaticfinalintBUFFER_SIZE=10240;
- 
- 
privateSocketChannelRTPChannel;
- 
- 
publicbooleanisRunning=true;
- 
- 
privateSelectorselector;
- 
- 
privatefinalByteBufferreceiveBuf;
- 
- 
/*服务器地址*/
- 
- 
privatefinalInetSocketAddressremoteAddr;
- 
- 
- 
- 
privatefinalInetAddressaddr;
- 
- 
- 
- 
privatefinalintport;
- 
- 
privatefinalInetSocketAddresslocalAddress;
- 
- 
privateintlocalPort;
- 
- 
privateAtomicBooleanshutdown;
- 
- 
publicRTPHandle(InetSocketAddressremoteAddr){
- 
- 
this.remoteAddr=remoteAddr;
- 
- 
this.addr=remoteAddr.getAddress();
- 
- 
this.port=remoteAddr.getPort();
- 
- 
this.localAddress=newInetSocketAddress(getLocalAddress(),0);
- 
- 
receiveBuf=ByteBuffer.allocate(BUFFER_SIZE);
- 
- 
if(selector==null){
- 
- 
try{
- 
- 
selector=Selector.open();
- 
- 
}catch(Exceptione){
- 
- 
Log.e(TAG,“SelectoropenERROR”);
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
}
- 
- 
initial();
- 
- 
shutdown=newAtomicBoolean(false);
- 
- 
}
- 
- 
privatevoidinitial(){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
try{
- 
- 
RTPChannel=SocketChannel.open();
- 
- 
RTPChannel.configureBlocking(false);
- 
- 
RTPChannel.socket().bind(localAddress);
- 
- 
localPort=RTPChannel.socket().getLocalPort();
- 
- 
Log.e(TAG,“isBound:”+RTPChannel.socket().isBound()
- 
- 
+“localPort:”+localPort);
- 
- 
if(RTPChannel.connect(remoteAddr)){
- 
- 
Log.i(TAG,“RTPChannelstarttoconnect”+remoteAddr);
- 
- 
}
- 
- 
RTPChannel.register(selector,SelectionKey.OP_CONNECT
- 
- 
|SelectionKey.OP_READ,this);
- 
- 
Log.i(TAG,“RTPportopenSuccess”);
- 
- 
}catch(Exceptione){
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
}
- 
- 
- 
- 
publicvoidrun(){
- 
- 
while(!shutdown.get()){
- 
- 
select();
- 
- 
try{
- 
- 
Thread.sleep(100);
- 
- 
}catch(finalExceptione){
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
}
- 
- 
shutdown();
- 
- 
}
- 
- 
privatevoidshutdown(){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
if(isConnected()){
- 
- 
try{
- 
- 
RTPChannel.close();
- 
- 
Log.i(TAG,“端口关闭成功”);
- 
- 
}catch(finalIOExceptione){
- 
- 
Log.i(TAG,“端口关闭错误:”);
- 
- 
}finally
- 
{
- 
- 
RTPChannel=null;
- 
- 
}
- 
- 
}else{
- 
- 
Log.i(TAG,“通道为空或者没有连接”);
- 
- 
}
- 
- 
}
- 
- 
privatevoidselect(){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
intn=0;
- 
- 
try{
- 
- 
if(selector==null){
- 
- 
return;
- 
- 
}
- 
- 
n=selector.select(1000);
- 
- 
}catch(finalExceptione){
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
//如果select返回大于0,处理事件
- 
- 
if(n>0){
- 
- 
for(finalIterator<SelectionKey>i=selector.selectedKeys()
- 
- 
.iterator();i.hasNext();){
- 
- 
//得到下一个Key
- 
- 
finalSelectionKeysk=i.next();
- 
- 
i.remove();
- 
- 
//检查其是否还有效
- 
- 
if(!sk.isValid()){
- 
- 
continue;
- 
- 
}
- 
- 
//处理事件
- 
- 
finalIEventhandler=(IEvent)sk.attachment();
- 
- 
try{
- 
- 
if(sk.isConnectable()){
- 
- 
handler.connect(sk);
- 
- 
}elseif(sk.isReadable()){
- 
- 
handler.read(sk);
- 
- 
}else{
- 
- 
//System.err.println(“Ooops”);
- 
- 
}
- 
- 
}catch(finalExceptione){
- 
- 
handler.error(e);
- 
- 
sk.cancel();
- 
- 
}
- 
- 
}
- 
- 
}
- 
- 
}
- 
- 
privatebooleanisConnected(){
- 
- 
returnRTPChannel!=null&&RTPChannel.isConnected();
- 
- 
}
- 
- 
privatebyte[]recieve(){
- 
- 
if(isConnected()){
- 
- 
try{
- 
- 
intlen=0;
- 
- 
intreadBytes=0;
- 
- 
synchronized(receiveBuf){
- 
- 
receiveBuf.clear();
- 
- 
try{
- 
- 
while((len=RTPChannel.read(receiveBuf))>0){
- 
- 
readBytes+=len;
- 
- 
}
- 
- 
}finally{
- 
- 
receiveBuf.flip();
- 
- 
}
- 
- 
if(readBytes>0){
- 
- 
finalbyte[]tmp=newbyte[readBytes];
- 
- 
receiveBuf.get(tmp);
- 
- 
returntmp;
- 
- 
}else{
- 
- 
Log.i(TAG,“ReceiveEmpty”);
- 
- 
returnnull;
- 
- 
}
- 
- 
}
- 
- 
}catch(finalIOExceptione){
- 
- 
Log.e(TAG,“ReceiveEmpty”);
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
}else{
- 
- 
Log.e(TAG,“portdisconnect”);
- 
- 
}
- 
- 
returnnull;
- 
- 
}
- 
- 
privatevoidhandle(byte[]msg){
- 
- 
Stringtmp=newString(msg);
- 
- 
Log.i(TAG,tmp);
- 
- 
}
- 
- 
//@Override
- 
- 
publicvoidconnect(SelectionKeykey)throwsIOException{
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
if(isConnected()){
- 
- 
return;
- 
- 
}
- 
- 
RTPChannel.finishConnect();
- 
- 
while(!RTPChannel.isConnected()){
- 
- 
try{
- 
- 
Thread.sleep(300);
- 
- 
}catch(finalInterruptedExceptione){
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
RTPChannel.finishConnect();
- 
- 
}
- 
- 
}
- 
- 
//@Override
- 
- 
publicvoiderror(Exceptione){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
//@Override
- 
- 
publicvoidread(SelectionKeykey)throwsIOException{
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
finalbyte[]msg=recieve();
- 
- 
if(msg!=null){
- 
- 
handle(msg);
- 
- 
}else{
- 
- 
key.cancel();
- 
- 
}
- 
- 
}
- 
- 
//@Override
- 
- 
publicvoidwrite()throwsIOException{
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
}
- 
- 
publicintgetRTPChannelPort(){
- 
- 
returnlocalPort;
- 
- 
}
- 
- 
privateStringgetLocalAddress(){
- 
- 
Enumeration<NetworkInterface>netInterfaces=null;
- 
- 
StringBuffersb=newStringBuffer(“”);
- 
- 
try{
- 
- 
netInterfaces=NetworkInterface.getNetworkInterfaces();
- 
- 
while(netInterfaces.hasMoreElements()){
- 
- 
NetworkInterfaceni=netInterfaces.nextElement();
- 
- 
Enumeration<InetAddress>ips=ni.getInetAddresses();
- 
- 
while(ips.hasMoreElements()){
- 
- 
if(sb.toString().length()>0)
- 
- 
returnsb.toString();
- 
- 
;
- 
- 
InetAddresslocal=ips.nextElement();
- 
- 
sb.append(local.getHostAddress());
- 
- 
}
- 
- 
}
- 
- 
}catch(Exceptione){
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
returnsb.toString();
- 
- 
}
- 
- 
}
3.连接服务器操作
- 
publicclassRTSPConnectextendsThreadimplementsIEvent{
- 
- 
privatestaticfinalStringTAG=“RTSPConnect”;
- 
- 
privatestaticfinalStringRTSP_VERSION=“RTSP/1.0\r\n”;
- 
- 
privatestaticfinalStringRTSP_OK=“RTSP/1.0200OK”;
- 
- 
/*远程主机地址*/
- 
- 
privatefinalInetSocketAddressremoteAddress;
- 
- 
/*本机地址*/
- 
- 
privatefinalInetSocketAddresslocalAddress;
- 
- 
/*数据源地址*/
- 
- 
privateStringaddress;
- 
- 
/*发送缓冲区*/
- 
- 
privatefinalByteBuffersendBuf;
- 
- 
/*接收缓冲区*/
- 
- 
privatefinalByteBufferreceiveBuf;
- 
- 
privatestaticfinalintBUFFER_SIZE=10240;
- 
- 
/*端口选择器*/
- 
- 
privateSelectorselector;
- 
- 
privateSocketChannelsocketChannel;
- 
- 
privateRTPReceiveUDPrtp;
- 
- 
/*RTP接收端口*/
- 
- 
privateintRTPPort;
- 
- 
/*连接状态*/
- 
- 
privateStatussysStatus;
- 
- 
privateStringsessionId;
- 
- 
privateStringtrackInfo;
- 
- 
privateintseq=1;
- 
- 
privatebooleanisSended;
- 
- 
/**
- 
- 
*线程是否结束的标志
- 
- 
*/
- 
- 
privateAtomicBooleanshutdown;
- 
- 
/**
- 
- 
*计算进度的Handler
- 
- 
*/
- 
- 
privateHandlermHandler;
- 
- 
privateenumStatus{
- 
- 
init,options,describe,getparameter,setup,play,setparameter,pause,teardown
- 
- 
}
- 
- 
/**
- 
- 
*获得主机地址
- 
- 
*
- 
- 
*@return
- 
- 
*/
- 
- 
publicstaticStringgetLocalAddress(){
- 
- 
Enumeration<NetworkInterface>netInterfaces=null;
- 
- 
StringBuffersb=newStringBuffer(“”);
- 
- 
try{
- 
- 
netInterfaces=NetworkInterface.getNetworkInterfaces();
- 
- 
while(netInterfaces.hasMoreElements()){
- 
- 
NetworkInterfaceni=netInterfaces.nextElement();
- 
- 
Enumeration<InetAddress>ips=ni.getInetAddresses();
- 
- 
while(ips.hasMoreElements()){
- 
- 
if(sb.toString().length()>0)
- 
- 
returnsb.toString();
- 
- 
InetAddresslocal=ips.nextElement();
- 
- 
sb.append(local.getHostAddress());
- 
- 
}
- 
- 
}
- 
- 
}catch(Exceptione){
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
returnsb.toString();
- 
- 
}
- 
- 
/**
- 
- 
*连接服务器
- 
- 
*
- 
- 
*@paramremoteAddress
- 
- 
*@paramaddress
- 
- 
*/
- 
- 
publicRTSPConnect(InetSocketAddressremoteAddress,Stringaddress){
- 
- 
//TODOAuto-generatedconstructorstub
- 
- 
this.remoteAddress=remoteAddress;
- 
- 
this.localAddress=newInetSocketAddress(getLocalAddress(),0);
- 
- 
this.address=address;
- 
- 
//初始化缓冲区
- 
- 
sendBuf=ByteBuffer.allocateDirect(BUFFER_SIZE);
- 
- 
receiveBuf=ByteBuffer.allocateDirect(BUFFER_SIZE);
- 
- 
if(selector==null){
- 
- 
try{
- 
- 
selector=Selector.open();
- 
- 
}catch(Exceptione){
- 
- 
Log.e(TAG,“SelectoropenERROR”);
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
}
- 
- 
startup();
- 
- 
sysStatus=Status.init;
- 
- 
shutdown=newAtomicBoolean(false);
- 
- 
isSended=false;
- 
- 
}
- 
- 
/**
- 
- 
*连接服务器
- 
- 
*
- 
- 
*@parammHandler
- 
- 
*@paramremoteAddress
- 
- 
*@paramaddress
- 
- 
*/
- 
- 
publicRTSPConnect(HandlermHandler,InetSocketAddressremoteAddress,
- 
- 
Stringaddress){
- 
- 
//TODOAuto-generatedconstructorstub
- 
- 
this.mHandler=mHandler;
- 
- 
this.remoteAddress=remoteAddress;
- 
- 
this.localAddress=newInetSocketAddress(getLocalAddress(),0);
- 
- 
this.address=address;
- 
- 
//初始化缓冲区
- 
- 
sendBuf=ByteBuffer.allocateDirect(BUFFER_SIZE);
- 
- 
receiveBuf=ByteBuffer.allocateDirect(BUFFER_SIZE);
- 
- 
if(selector==null){
- 
- 
try{
- 
- 
selector=Selector.open();
- 
- 
}catch(Exceptione){
- 
- 
Log.e(TAG,“SelectoropenERROR”);
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
}
- 
- 
startup();
- 
- 
sysStatus=Status.init;
- 
- 
shutdown=newAtomicBoolean(false);
- 
- 
isSended=false;
- 
- 
}
- 
- 
publicvoidstartup(){
- 
- 
try{
- 
- 
socketChannel=SocketChannel.open();//打开端口
- 
- 
socketChannel.configureBlocking(false);
- 
- 
socketChannel.socket().bind(localAddress);
- 
- 
Log.e(TAG,“isBound:”+socketChannel.socket().isBound()
- 
- 
+“Port:”+socketChannel.socket().getLocalPort());
- 
- 
if(socketChannel.connect(remoteAddress)){
- 
- 
Log.i(TAG,“socketChannelstarttoConnect”+remoteAddress);
- 
- 
}
- 
- 
socketChannel.register(selector,SelectionKey.OP_CONNECT
- 
- 
|SelectionKey.OP_READ|SelectionKey.OP_WRITE,this);
- 
- 
Log.i(TAG,“portopenSuccess”);
- 
- 
}catch(Exceptione){
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
rtp=newRTPReceiveUDP();
- 
- 
}
- 
- 
/*判断是否连接*/
- 
- 
privatebooleanisConnected(){
- 
- 
returnsocketChannel!=null&&socketChannel.isConnected();
- 
- 
}
- 
- 
/**
- 
- 
*接收收据
- 
- 
*
- 
- 
*@return
- 
- 
*/
- 
- 
privatebyte[]recieve(){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
if(isConnected()){
- 
- 
try{
- 
- 
intlen=0;
- 
- 
intreadBytes=0;
- 
- 
synchronized(receiveBuf){
- 
- 
receiveBuf.clear();
- 
- 
try{
- 
- 
while((len=socketChannel.read(receiveBuf))>0){
- 
- 
readBytes+=len;
- 
- 
System.out.println(“接收收据======>>>>>>”+readBytes
- 
- 
+“byte”);
- 
- 
//Messagemsg=newMessage();
- 
- 
//msg.what=2012062011;
- 
- 
//msg.obj=readBytes;
- 
- 
//mHandler.sendMessage(msg);
- 
- 
}
- 
- 
}finally{
- 
- 
receiveBuf.flip();
- 
- 
}
- 
- 
if(readBytes>0){
- 
- 
finalbyte[]tmp=newbyte[readBytes];
- 
- 
receiveBuf.get(tmp);
- 
- 
returntmp;
- 
- 
}else{
- 
- 
Log.i(TAG,“接收到数据为空,重新启动连接”);
- 
- 
returnnull;
- 
- 
}
- 
- 
}
- 
- 
}catch(finalIOExceptione){
- 
- 
Log.e(TAG,“接收消息错误!”);
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
}else{
- 
- 
Log.e(TAG,“端口没有连接”);
- 
- 
}
- 
- 
returnnull;
- 
- 
}
- 
- 
privatevoidhandle(byte[]msg){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
Stringtmp=newString(msg);
- 
- 
Log.i(TAG,“handletmp===>>>>>”+tmp);
- 
- 
if(tmp.startsWith(RTSP_OK)){
- 
- 
switch(sysStatus){
- 
- 
caseinit:
- 
- 
sysStatus=Status.options;
- 
- 
break;
- 
- 
caseoptions:
- 
- 
sysStatus=Status.describe;
- 
- 
trackInfo=“Audio”;//默认为Audio
- 
- 
break;
- 
- 
casedescribe:
- 
- 
sysStatus=Status.getparameter;
- 
- 
break;
- 
- 
casegetparameter:
- 
- 
sessionId=tmp.substring(tmp.indexOf(“Session:”)+9,tmp.indexOf(“;timeout=”));
- 
- 
Log.e(TAG,“sessionID:”+sessionId);
- 
- 
if(sessionId!=null&&sessionId.length()>0){
- 
- 
sysStatus=Status.setup;
- 
- 
}
- 
- 
break;
- 
- 
casesetup:
- 
- 
sysStatus=Status.play;
- 
break;
- 
- 
caseplay:
- 
- 
sysStatus=Status.setparameter;
- 
- 
break;
- 
- 
casesetparameter:
- 
- 
sysStatus=Status.pause;
- 
- 
break;
- 
- 
casepause:
- 
- 
sysStatus=Status.teardown;
- 
- 
break;
- 
- 
caseteardown:
- 
- 
sysStatus=Status.init;
- 
- 
break;
- 
- 
default:
- 
- 
Log.e(TAG,“MSGERROR:”+tmp);
- 
- 
break;
- 
- 
}
- 
- 
isSended=false;
- 
- 
}else{
- 
- 
Log.e(TAG,“RETURNERROR:”+tmp);
- 
- 
}
- 
- 
}
- 
- 
//@Override
- 
- 
publicvoidconnect(SelectionKeykey)throwsIOException{
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
if(isConnected()){
- 
- 
return;
- 
- 
}
- 
- 
socketChannel.finishConnect();
- 
- 
while(!socketChannel.isConnected()){
- 
- 
try{
- 
- 
Thread.sleep(300);
- 
- 
}catch(finalInterruptedExceptione){
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
socketChannel.finishConnect();
- 
- 
}
- 
- 
}
- 
- 
//@Override
- 
- 
publicvoiderror(Exceptione){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
//@Override
- 
- 
publicvoidread(SelectionKeykey)throwsIOException{
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
finalbyte[]msg=recieve();
- 
- 
if(msg!=null){
- 
- 
handle(msg);
- 
- 
}else{
- 
- 
key.cancel();
- 
- 
}
- 
- 
}
- 
- 
//@Override
- 
- 
publicvoidwrite()throwsIOException{
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
if(isConnected()){
- 
- 
try{
- 
- 
socketChannel.write(sendBuf);
- 
- 
}catch(finalIOExceptione){
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
}else{
- 
- 
Log.e(TAG,“writeERROR:通道为空或者未连接”);
- 
- 
}
- 
- 
}
- 
- 
- 
- 
publicvoidrun(){
- 
- 
while(!shutdown.get()){
- 
- 
try{
- 
- 
if(isConnected()&&(!isSended)){
- 
- 
switch(sysStatus){
- 
- 
caseinit:
- 
- 
doOption();
- 
- 
break;
- 
- 
caseoptions:
- 
- 
doDescribe();
- 
- 
break;
- 
- 
casedescribe:
- 
- 
doGetParameter();
- 
- 
break;
- 
- 
casegetparameter:
- 
- 
rtp.start();
- 
- 
doSetup();
- 
- 
break;
- 
- 
casesetup:
- 
- 
if(sessionId==null&&sessionId.length()>0){
- 
- 
Log.e(TAG,“setupERROR”);
- 
- 
}else{
- 
- 
doPlay();
- 
- 
}
- 
- 
break;
- 
- 
caseplay:
- 
- 
doSetParameter();
- 
- 
break;
- 
- 
casesetparameter:
- 
- 
doPause();
- 
- 
break;
- 
- 
casepause:
- 
- 
doTeardown();
- 
- 
break;
- 
- 
default:
- 
- 
break;
- 
- 
}
- 
- 
}
- 
- 
select();
- 
- 
try{
- 
- 
Thread.sleep(100);
- 
- 
}catch(finalExceptione){
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
}catch(finalExceptione){
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
}
- 
- 
shutdown();
- 
- 
}
- 
- 
publicvoidshutdown(){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
if(isConnected()){
- 
- 
try{
- 
- 
socketChannel.close();
- 
- 
Log.i(TAG,“端口关闭成功”);
- 
- 
}catch(finalIOExceptione){
- 
- 
Log.i(TAG,“端口关闭错误:”+e.getMessage().toString());
- 
- 
}finally{
- 
- 
socketChannel=null;
- 
- 
}
- 
- 
}else{
- 
- 
Log.i(TAG,“通道为空或者没有连接”);
- 
- 
}
- 
- 
}
- 
- 
privatevoidselect(){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
intn=0;
- 
- 
try{
- 
- 
if(selector==null){
- 
- 
return;
- 
- 
}
- 
- 
n=selector.select(1000);
- 
- 
}catch(finalExceptione){
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
//如果select返回大于0,处理事件
- 
- 
if(n>0){
- 
- 
for(finalIterator<SelectionKey>i=selector.selectedKeys()
- 
- 
.iterator();i.hasNext();){
- 
- 
//得到下一个Key
- 
- 
finalSelectionKeysk=i.next();
- 
- 
i.remove();
- 
- 
//检查其是否还有效
- 
- 
if(!sk.isValid()){
- 
- 
continue;
- 
- 
}
- 
- 
//处理事件
- 
- 
finalIEventhandler=(IEvent)sk.attachment();
- 
- 
try{
- 
- 
if(sk.isConnectable()){
- 
- 
handler.connect(sk);
- 
- 
}elseif(sk.isReadable()){
- 
- 
handler.read(sk);
- 
- 
}else{
- 
- 
//System.err.println(“Ooops”);
- 
- 
}
- 
- 
}catch(finalExceptione){
- 
- 
handler.error(e);
- 
- 
sk.cancel();
- 
- 
}
- 
- 
}
- 
- 
}
- 
- 
}
- 
- 
privatevoiddoSetup(){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
StringBuildersb=newStringBuilder();
- 
- 
sb.append(“SETUP”);
- 
- 
sb.append(this.address);
- 
- 
sb.append(“/”);
- 
- 
sb.append(trackInfo);
- 
- 
sb.append(RTSP_VERSION);
- 
- 
sb.append(“Cseq:”);
- 
- 
sb.append(seq++);
- 
- 
sb.append(“\r\n”);
- 
- 
//sb.append(“Transport:RTP/AVP;UNICAST;client_port=16264-16265;mode=play\r\n”);
- 
- 
RTPPort=rtp.getLocalPort();
- 
- 
sb.append(“Transport:RTP/AVP;unicast;client_port=”+RTPPort
- 
- 
+“;mode=PLAY\r\n”);
- 
- 
sb.append(“\r\n”);
- 
- 
Log.w(TAG,“doSetup:”+sb.toString());
- 
- 
send(sb.toString().getBytes());
- 
- 
}
- 
- 
privatevoiddoTeardown(){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
StringBuildersb=newStringBuilder();
- 
- 
sb.append(“TEARDOWN”);
- 
- 
sb.append(this.address);
- 
- 
sb.append(“/”);
- 
- 
sb.append(RTSP_VERSION);
- 
- 
sb.append(“Cseq:”);
- 
- 
sb.append(seq++);
- 
- 
sb.append(“\r\n”);
- 
- 
sb.append(“User-Agent:RealMediaPlayerHelixDNAClient/10.0.0.11279(win32)\r\n”);
- 
- 
sb.append(“Session:”);
- 
- 
sb.append(sessionId);
- 
- 
sb.append(“\r\n”);
- 
- 
send(sb.toString().getBytes());
- 
- 
Log.w(TAG,“doTeardown:”+sb.toString());
- 
- 
}
- 
- 
privatevoiddoPause(){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
StringBuildersb=newStringBuilder();
- 
- 
sb.append(“PAUSE”);
- 
- 
sb.append(this.address);
- 
- 
sb.append(“/”);
- 
- 
sb.append(RTSP_VERSION);
- 
- 
sb.append(“Cseq:”);
- 
- 
sb.append(seq++);
- 
- 
sb.append(“\r\n”);
- 
- 
sb.append(“Session:”);
- 
- 
sb.append(sessionId);
- 
- 
sb.append(“\r\n”);
- 
- 
send(sb.toString().getBytes());
- 
- 
Log.w(TAG,“doPause:”+sb.toString());
- 
- 
}
- 
- 
privatevoiddoPlay(){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
StringBuildersb=newStringBuilder();
- 
- 
sb.append(“PLAY”);
- 
- 
sb.append(this.address);
- 
- 
sb.append(RTSP_VERSION);
- 
- 
sb.append(“Session:”);
- 
- 
sb.append(sessionId);
- 
- 
sb.append(“\r\n”);
- 
- 
sb.append(“Cseq:”);
- 
- 
sb.append(seq++);
- 
- 
sb.append(“\r\n”);
- 
- 
sb.append(“Range:npt=0.000-“);
- 
- 
sb.append(“\r\n”);
- 
- 
sb.append(“\r\n”);
- 
- 
Log.w(TAG,“doPlay:”+sb.toString());
- 
- 
send(sb.toString().getBytes());
- 
- 
}
- 
- 
privatevoiddoGetParameter(){
- 
- 
StringBuildersb=newStringBuilder();
- 
- 
sb.append(“GET_PARAMETER”);
- 
- 
sb.append(this.address);
- 
- 
sb.append(RTSP_VERSION);
- 
- 
sb.append(“Content-length:0”);
- 
- 
sb.append(“\r\n”);
- 
- 
sb.append(“Cseq:”);
- 
- 
sb.append(seq++);
- 
- 
sb.append(“\r\n”);
- 
- 
sb.append(“\r\n”);
- 
- 
Log.w(TAG,“doGetParameter:”+sb.toString());
- 
- 
send(sb.toString().getBytes());
- 
- 
}
- 
- 
privatevoiddoSetParameter(){
- 
- 
StringBuildersb=newStringBuilder();
- 
- 
sb.append(“SET_PARAMETER”);
- 
- 
sb.append(this.address);
- 
- 
sb.append(RTSP_VERSION);
- 
- 
sb.append(“Seission:”);
- 
- 
sb.append(sessionId);
- 
- 
sb.append(“\r\n”);
- 
- 
sb.append(“Cseq:”);
- 
- 
sb.append(seq++);
- 
- 
sb.append(“\r\n”);
- 
- 
sb.append(“\r\n”);
- 
- 
Log.w(TAG,“doSetParameter:”+sb.toString());
- 
- 
send(sb.toString().getBytes());
- 
- 
}
- 
- 
privatevoiddoDescribe(){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
StringBuildersb=newStringBuilder();
- 
- 
sb.append(“DESCRIBE”);
- 
- 
sb.append(this.address);
- 
- 
sb.append(RTSP_VERSION);
- 
- 
sb.append(“Cseq:”);
- 
- 
sb.append(seq++);
- 
- 
sb.append(“\r\n”);
- 
- 
sb.append(“\r\n”);
- 
- 
Log.w(TAG,“doDescribe:”+sb.toString());
- 
- 
send(sb.toString().getBytes());
- 
- 
}
- 
- 
privatevoiddoOption(){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
StringBuildersb=newStringBuilder();
- 
- 
sb.append(“OPTIONS”);
- 
- 
sb.append(this.address);
- 
- 
sb.append(RTSP_VERSION);
- 
- 
sb.append(“Cseq:”);
- 
- 
sb.append(seq++);
- 
- 
sb.append(“\r\n”);
- 
- 
sb.append(“\r\n”);
- 
- 
Log.w(TAG,“doOption:”+sb.toString());
- 
- 
send(sb.toString().getBytes());
- 
- 
}
- 
- 
privatevoidsend(byte[]out){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
if(out==null||out.length<1){
- 
- 
return;
- 
- 
}
- 
- 
synchronized(sendBuf){
- 
- 
sendBuf.clear();
- 
- 
sendBuf.put(out);
- 
- 
sendBuf.flip();
- 
- 
}
- 
- 
//发送出去
- 
- 
try{
- 
- 
write();
- 
- 
isSended=true;
- 
- 
}catch(finalIOExceptione){
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
}
- 
- 
}
4.服务器接收客户端的请求并作出相应的反馈操作
- 
publicclassRTPReceiveUDPextendsThread{
- 
- 
privatefinalstaticStringTAG=“RTPRecevieUDP”;
- 
- 
privatefinalstaticintBUFFER_SIZE=10240;
- 
- 
privatefinalstaticStringTEMP_FILE=“fm932radio”;
- 
- 
//privatefinalstaticintDEFAULT_PORT=55566;//默认接收端口
- 
- 
privateintlocalPort;
- 
- 
privatebooleanisRunning=true;
- 
- 
privateintreadTimestamp=0;
- 
- 
//privateStringcurrentFilePath;
- 
- 
privateStringtempFilePath;
- 
- 
privateDatagramSocketRTPRecevie;
- 
- 
privateDatagramPacketRTPPacket;
- 
- 
privatebyte[]buf;
- 
- 
publicRTPReceiveUDP(){
- 
- 
try{
- 
- 
RTPRecevie=newDatagramSocket();
- 
- 
localPort=RTPRecevie.getLocalPort();
- 
- 
buf=newbyte[BUFFER_SIZE];
- 
- 
RTPPacket=newDatagramPacket(buf,BUFFER_SIZE);
- 
- 
createTempFile();
- 
- 
Log.i(TAG,“RTPRecevieUDPpreparedsuccess”);
- 
- 
}catch(SocketExceptione){
- 
- 
//TODOAuto-generatedcatchblock
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
}
- 
- 
publicintgetLocalPort(){
- 
- 
returnlocalPort;
- 
- 
}
- 
- 
/*没有参数则对全局的buf[]进行操作*/
- 
- 
privateintgetTimestamp(){
- 
- 
byte[]tmp=newbyte[4];
- 
- 
inttimestamp;
- 
- 
for(inti=0;i<4;i++)
- 
- 
tmp[i]=buf[i+4];
- 
- 
timestamp=bytesToInt(tmp);
- 
- 
returntimestamp;
- 
- 
}
- 
- 
privateintbytesToInt(byte[]b){
- 
- 
intmask=0xff;
- 
- 
inttemp=0;
- 
- 
intn=0;
- 
- 
for(inti=0;i<4;i++){
- 
- 
n<<=8;
- 
- 
temp=b[i]&mask;
- 
- 
n|=temp;
- 
- 
}
- 
- 
returnn;
- 
- 
}
- 
- 
privatevoidcreateTempFile(){
- 
- 
byte[]wmaHeader=newbyte[]{(byte)0x30,(byte)0x26,(byte)0xB2,
- 
- 
(byte)0x75,(byte)0x8E,(byte)0x66,(byte)0xCF,
- 
- 
(byte)0x11,(byte)0xA6,(byte)0xD9,(byte)0x00,
- 
- 
(byte)0xAA,(byte)0x62,(byte)0xCE,(byte)0x6C};
- 
- 
byte[]allSize=newbyte[]{(byte)0x00,(byte)0x00,(byte)0x00,
- 
- 
(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00};
- 
- 
byte[]unKnown=newbyte[]{(byte)0x00,(byte)0x00,(byte)0x00,
- 
- 
(byte)0x00,(byte)0x00,(byte)0x00};
- 
- 
try{
- 
- 
//文件名=日期+时间+TEMP_FILE
- 
- 
SimpleDateFormatsdf=newSimpleDateFormat(“yyyyMMddhhmmss”);
- 
- 
Datenow=newDate(System.currentTimeMillis());
- 
- 
StringtimeResult=sdf.format(now);
- 
- 
FiletempFile=File.createTempFile(TEMP_FILE+timeResult,“.dat”);
- 
- 
tempFilePath=tempFile.getAbsolutePath();
- 
- 
System.out.println(“downloadpath======>>>>>>”+tempFilePath+“,filesize===>>>>”+tempFile.length());
- 
- 
FileOutputStreamfos=newFileOutputStream(tempFilePath,true);
- 
- 
fos.write(wmaHeader);
- 
- 
fos.write(allSize);
- 
- 
fos.write(unKnown);
- 
- 
fos.close();
- 
- 
}catch(IOExceptione){
- 
- 
//TODOAuto-generatedcatchblock
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
}
- 
- 
- 
- 
publicvoidrun(){
- 
- 
while(isRunning){
- 
- 
try{
- 
- 
RTPRecevie.receive(RTPPacket);
- 
- 
inttimestamp=getTimestamp();
- 
- 
if(readTimestamp==timestamp)
- 
- 
continue;
- 
- 
readTimestamp=timestamp;
- 
- 
handle();
- 
- 
Log.e(TAG,“timestamp:”+timestamp);
- 
- 
}catch(IOExceptione){
- 
- 
//TODOAuto-generatedcatchblock
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
}
- 
- 
}
- 
- 
privatevoidhandle(){
- 
- 
//TODOAuto-generatedmethodstub
- 
- 
try{
- 
- 
FileOutputStreamfos=newFileOutputStream(tempFilePath,true);
- 
- 
fos.write(buf,12,buf.length-12);
- 
- 
}catch(FileNotFoundExceptione){
- 
- 
//TODOAuto-generatedcatchblock
- 
- 
e.printStackTrace();
- 
- 
}catch(IOExceptione){
- 
- 
//TODOAuto-generatedcatchblock
- 
- 
e.printStackTrace();
- 
- 
}
- 
- 
}
- 
- 
}
- 
- 
5.在Activity中调用方法,实现播放
- 
- 
if(strHead.equals(“rtsp:”)){//根据已截取文件的前四个字符判断是否是rtsp协议
- 
- 
connect=newRTSPConnect(newInetSocketAddress(
- 
- 
“流媒体的IP地址”,端口号默认为554),
- 
- 
“rtsp://流媒体的IP地址:554”);
- 
- 
connect.start();
- 
- 
mVideoView.setVideoURI(Uri.parse(strVideoUrl));
- 
- 
mVideoView.requestFocus();
- 
- 
mVideoView.start();
- 
- 
}elseif(strHead.equals(“http:”)){
- 
- 
mVideoView.setVideoURI(Uri.parse(strVideoUrl));
- 
- 
}
- 转自:https://blog.csdn.net/ameyume/article/details/8123382