JAVA视频通信的优化

本文探讨了Java视频通信的优化策略,包括通过将二维数组整合为一维byte数组以减少传输次数,使用线程同步避免数据交错问题,以及在服务器端采用双缓存画布提高接收效率。详细介绍了实现这些优化的步骤和方法。
摘要由CSDN通过智能技术生成

传输优化

按之前的发送图片时一张图片假如一个一个遍历发送则要分开发送很多次,若一张图片是400,400,则要进行160000次的dout.writeInt(),这个过程十分耗费时间,效率极低,故可将这个二维数组化成一个一维的byte类型数组,则只需要进行一次从客户端到服务端的过程。同样服务器也只需要接受一次。
这里我是自己写了一个int[][]转成byte[]的方法,但这个方法应该不是最优

我们知道了图片长度,即可知道byte数组的长度应是image.getWidth() * image.getHeight() * 4, 故我们先创建一个这个长度的数组

//创建发送的byte[]数组
		    byte[] send = new byte[image.getWidth() * image.getHeight() * 4];

然后将每个像素点的int型数组转换成byte[4]后加入到这个提前创建的数组

1、将一个int转换成byte[4]

//将int类型数据转换为byte数组
	public static byte[] intToByteArray(int i) {
		byte[] result = new byte[4];
		// 由高位到低位
		result[0] = (byte) ((i >> 24) & 0xFF);
		result[1] = (byte) ((i >> 16) & 0xFF);
		result[2] = (byte) ((i >> 8) & 0xFF);
		result[3] = (byte) (i & 0xFF);
		return result;
	}

2、将int[i][j]这个数据转成的byte数组添加到send数组中

public void addToArray(byte[] send,byte[] b,int i,int j,int Height) {
	   for (int k=0; k<4; k++) {
		   int index = i * Height + j ;
		   index = index * 4 ;
		   send[index + k] = b[k];		   
	   }
   }


总的代码如下

```java
public void sendVideo(BufferedImage image) {
		    
		    //创建发送的byte[]数组
		    byte[] send = new byte[image.getWidth() * image.getHeight() * 4];
			//用int发送视频
			
				try {
					synchronized(dout){
					//先发报头,视频的报头是2
					dout.writeInt('2');
					//先发送长度,再发数据
					dout.writeInt(image.getWidth());
					dout.writeInt(image.getHeight());
					
					for(int i=0 ; i<image.getWidth();i++) {
						for(int j=0 ; j<image.getHeight();j++) {
							byte[] b = intToByteArray(image.getRGB(i, j));
							addToArray(send,b,i,j,image.getHeight());
						}	
					}
														
					dout.write(send);
										
					dout.flush();
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
										
	}
	
	//将int类型数据转换为byte数组
	public static byte[] intToByteArray(int i) {
		byte[] result = new byte[4];
		// 由高位到低位
		result[0] = (byte) ((i >> 24) & 0xFF);
		result[1] = (byte) ((i >> 16) & 0xFF);
		result[2] = (byte) ((i >> 8) & 0xFF);
		result[3] = (byte) (i & 0xFF);
		return result;
	}
   //将每一个int转换的byte数组添加到总的数组中
   public void addToArray(byte[] send,byte[] b,int i,int j,int Height) {
	   for (int k=0; k<4; k++) {
		   int index = i * Height + j ;
		   index = index * 4 ;
		   send[index + k] = b[k];
		   
	   }
   }

服务端也是同样类似的操作

线程同步

若需要加入不同的功能,如视频的同时在客户端画一笔线,这个线也在服务器端显示出来。此时用监听器发送数据时,若用同一个输出流,则视频传的字节和画线传的字节相当于同时向杯子倒水,这时候服务器端接受时本来在接受视频数据,下一个可能参杂了画线数据,一个字节乱了后面就都乱了。
所以我们用线程同步关键字synchronized(要锁住的对象){要锁住的东西} 这个时候,将某一对象锁住时,若有多个不同的进程要使用这个对象,则必须要等这个{}中要锁住的东西执行完后才能进行

try {
					synchronized(dout){
					//先发报头,视频的报头是2
					dout.writeInt('2');
					//先发送长度,再发数据
					dout.writeInt(image.getWidth());
					dout.writeInt(image.getHeight());
					
					for(int i=0 ; i<image.getWidth();i++) {
						for(int j=0 ; j<image.getHeight();j++) {
							byte[] b = intToByteArray(image.getRGB(i, j));
							addToArray(send,b,i,j,image.getHeight());
						}	
					}
														
					dout.write(send);
										
					dout.flush();
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

双缓存画布

在服务器接受时使用双缓存画布,否则速度非常慢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值