说起实时流传输协议,没有做过的就会感到很陌生,但是项目组必须用到,就要去查资料,将其解决。我前不久做的项目正好碰上,就在此说说自己的拙见。既然用到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