APP与终端设备通信经验四(码流链路建立)

需求:APP作为服务端的程序。主动接收来自终端推送过来的码流视频信息,并且播放。

过程:
1、app发送一条信令协议,告知终端,请给我推送数据
2、同时app开始开启服务端程序开始监听一个端口号
3、终端收到了这条协议后开始推送数据。
4、app接收数据,并且完成数据的渲染显示。

在前几篇文章里说道的信令链路是
app端拿到端口号和IP进行socket连接

  //实例化一个Socket对象
            socket = new Socket();
            //与对应的ip、端口进行连接,先要把桥建好
            socket.connect(new InetSocketAddress(ip, port), 3000);

在这个基础上,同时还需要app作为服务端

public class ServerSocketThreadTM extends Thread {

  /**
     *
     * 使用TCP协议,连接访问
     * @param port 端口
     * @param mMessageListener 收到服务器端数据时将回调该接口内的
     *  public void Message(String msg)方法
     */
    public ServerSocketThreadTM(ServerSocket sSocket, int port,
                        MessageListener mMessageListener, ConnectedState connectedState) {
//        this.ip = ip;
        Log.i(TAG,"@@@server init");
        this.port = port;
        this.mMessageListener = mMessageListener;
        this.connectedState=connectedState;
        this.serverSocket=sSocket;
    }

 public void run() {
        Log.v("socketThread", "@@@server run");
        try {
   
            Log.v("socketThread", "@@@server socket ok");
            clientSocket = serverSocket.accept();
            if (clientSocket.isConnected()) {
                Log.d(TAG, "@@@server建立连接");
                client = new ServerSocketThreadTM.Client(clientSocket,mMessageListener);
                //打开对应的输入/输出流监听
                client.start();
                isStart=true;
                connectedState.IsConnected(true);
            }else{
                Log.d(TAG, "@@@server未建立连接");
                isStart=false;
//                try {
//                    Thread.sleep(500);
//                }catch (Exception e){
//
//                }

                connectedState.IsConnected(false);
            }
        } catch (Exception e) {
            Log.v("socketThread", "@@@server Except");
            e.printStackTrace();

            isStart=false;
            connectedState.IsConnected(false);
        }
    }
}

Client封装了输入输出的两个线程

  public class Client {

        private SClientInputThreadTM in;
        private SClientOutputThreadTM out;

        public Client(Socket socket, MessageListener mMessageListener) {
            //用这个监听输入流线程来接收信息
            in = new SClientInputThreadTM(socket);
            in.setMessageListener(mMessageListener);
            //以后就用这个监听输出流的线程来发送信息了
            out = new SClientOutputThreadTM(socket);
        }

        public void start() {
            in.setStart(true);
            out.setStart(true);
            in.start();
//            out.start();
        }

        // 得到读消息线程
        public SClientInputThreadTM getIn() {
            return in;
        }

        // 得到写消息线程
        public SClientOutputThreadTM getOut() {
            return out;
        }
    }

这里是开启码流链路的线程

  server=new ServerSocketThreadTM(serverSocket,port_server, new MessageListener() {
            @Override
            public void Message(String msg) {

                if(msg.equals("outOline")){//流媒体链路断开
                    Log.i(TAG,"@@@server connected "+"流媒体链路断开");
                 }
            }
        }, new ConnectedState() {
            @Override
            public void IsConnected(boolean conn) {
                Log.i(TAG,"@@@server connected "+conn);
                if (conn==false) {
                    stopvideo();
                    showtip("网络异常");
                }

//                if (!conn){
//                    startServer();
//                }
            }
        });
        server.start();

Client中这两个线程用于收发数据
SClientInputThreadTM in;
SClientOutputThreadTM out;

重点:本项目建立码流的过程,和文章开篇的那个过程相互对应。(注释:实际情况下会添加各种处理,比如一些音频播放的一些初始化。是否别的摄像头正在请求开启终端视频的判断,这些暂时不做考虑,只是先有个流程)

1、Activity文件 PlayRealAV.java
2、播放器(一个自定义的控件,包含开始暂停、恢复、拖动、快进快退等功能)MySurfaceView.java
3、播放器控件对应的操作类 MyVideoOperate.java
4、信令链路TCP线程(SocketThread.java(开启)、ClientInputThread.java(输入线程)、ClientOutputThread.java(输出线程))
5、码流链路RTP线程(ServerSocketThread.java(开启码流),SClientInputThread.java(输入线程),SClientOutputThread.java(输出线程))。

1、Activity加载几个SurfaceView(本项目有多个摄像头)

      one_mysurfaceview = (MySurfaceViewTM)findViewById(R.id.one_mysurfaceview);
	two_mysurfaceview = (MySurfaceViewTM)findViewById(R.id.two_mysurfaceview);
	......

APP上显示的四个播放器
当点击播放按钮,
会建立TCP连接,同时主界面会有tcp连接状态的监听,当然如果TCP连接已经存在了就会直接开始请求实时视频了。
MySurfaceView----->VideoOperateTM------->PlayRealAV

PlayRealAV
{
    public void TCPConnect() {
        // 初始化
        android.util.Log.i(TAG,"ip:"+ip+"--port:"+port);
        client = new SocketThreadTM(ip,port, new MessageListener() {
            // 收到消息后调用此方法
            @Override
            public void Message(String msg) {
                // TODO Auto-generated method stub
                // tvMessage.append(msg);
                if (msg.equals("2424")) {
//                if (msg.equals(sendmsg)){
                    android.util.Log.i(TAG,"@@@::request success");
                    myHandler.sendEmptyMessage(MESSAGE_SUCCESS);
                } else if (msg.equals("0000")) {
                    myHandler.sendEmptyMessage(MESSAGE_FAILED);
                } else if (msg.equals("outTime")) {
                    myHandler.sendEmptyMessage(OUT_TIME);
                } 
            }
        }, new ConnectedState() {

            @Override
            public void IsConnected(boolean conn) {

                if (conn) {
                    myHandler.sendEmptyMessage(CONN_SUCCESS);
                    android.util.Log.i(TAG,"@@@:conn succs");
                } else {
                    android.util.Log.i(TAG,"@@@a:conn faild");
                    myHandler.sendEmptyMessage(CONN_FAIL);
                }
            }
        });
        // 正式启动线程
        client.start();
    }
}

把监听的信息传给了Activity,通过Handler了告知用户。

TCP连接上了根据协议发一条16进制的的数据,告知终端,app在请求实时视频了。
这部分代码是在VideoOperate.java类中

VideoOperate
{
byte[] data = comunication.reqRealVandAudio(channel,mContext);
client.sendMsg(data);//这个client是在界面文件实例化的tcp链路控制者
}

发生成功后,终端会返回一串数据给app。在Activity里的client线程会监听她,最终的处理回到了Operate类。就是会开启服务端程序,在这篇文章的整体介绍时已经说明了。

到此为止,码流链路建立完毕,接下来的重点就是app的解析了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值