猿问

有关安卓视频传输的问题,求大神解答!!!

各位大神,我在做一个基于安卓运用socket实现视频通信的软件,拿到了一段关于视频线程实现的源码,看完后有以下几个问题求大神解答,1)为什么图片大小要小于14000?
              2)大神是否可以简述一下这个实现过程,指点下运用了什么知识什么原理,方便我入门学习
              
              以下为代码:
	class ImageThread implements Runnable{  
		@Override
		public void run(){
			int image_size;
		    int image_one_size=1024;
			byte image_size_array[]=new byte[4]; //该数组用来接收图片数据大小,尺寸数据为int,所以需要4个字节 
			byte image_data_array[];             //未知大小,所以先不进行初始化
			byte final_image_data_buf[];         //最终图片数据存储区
			int numbytes=0;                      //从socket读入的字节数
			int donesize=0;                      //已经写入数组的字节数  
			int restsize=0;                      //未接收完的剩余数据 
			byte end[]={'e','n','d','\0'};       //每副图片的结束符
			//int cnt=0;
			try
			 { 
				while(!exit_var){
					donesize=0;
					restsize=0; 
					//cnt++; 
					//第一步----图片接收线程正常打开,向server发送ok信息
					image_out.println("ok!");   
					Log.d(DEBUG_TAG, "图片传送请求已发出");
					if(image_socket.isConnected()){ 
						 if(!image_socket.isInputShutdown()){ 
							//第二步----获得图片大小
							image_in.read(image_size_array, 0, 4);   //从socket中读数据存入数组中 每次读4个
							//Log.d(DEBUG_TAG, "image size array未越界");
//					通过拿到的4个数,就能知道图片的大小有多少
							image_size=(image_size_array[0] & 0xff) | ((image_size_array[1] << 8) & 0xff00)   // | 表示安位或 
					    			| ((image_size_array[2] << 24) >>> 8) | (image_size_array[3] << 24);  //把图片尺寸转成int型数据
							
							//第三步,接收图片数据
//							OutputStream 是一种管道  ByteArrayOutputStream也是一种管道,但是是一组一组数据的传输
							ByteArrayOutputStream imagestream = new ByteArrayOutputStream();
							
							if(image_size>14000){   
								break;
							} 
							else{   
								image_data_array=new byte[image_size];   //由于已经获得图片大小,所以此处进行初始化
								//Log.d(DEBUG_TAG, "image data array未越界");
								//按每组1024个数据读取  加入image_size 1025 1025/1024 读取2次
								for(int i=0;i<(image_size/image_one_size);i++)
								{
//									byte数组 名字叫 image_data_array、
//									numbytes 用来判断有多少数据被传过来了
									numbytes=image_in.read(image_data_array, donesize, 1024);
									if(numbytes==0) break;
									donesize=donesize+numbytes;
									
//									检测是否丢包 如果丢包就重写再传输
									if((image_one_size-numbytes)!=0){//读onesize数据出错
						 				restsize=image_one_size-numbytes;
									 	numbytes=image_in.read(image_data_array,donesize, restsize);
										if(numbytes==0) break;
										donesize=donesize+numbytes;
									}
								}
								
								//非1024格式数据的读取 
								
							 	if((image_size%image_one_size)!=0){ 
									restsize=image_size-donesize;
									numbytes=image_in.read(image_data_array, donesize, restsize); 
									if(numbytes==0) break;
									donesize=donesize+numbytes; 
								}
							}
							/*if((image_data_array[image_size-4]!=end[0])||(image_data_array[image_size-3]!=end[1])
									||(image_data_array[image_size-2]!=end[2])||(image_data_array[image_size-1]!=end[3]))
							{
								restsize=image_size-donesize;
								numbytes=image_in.read(image_data_array, donesize, restsize); 
								if(numbytes==0) break;
								donesize=donesize+numbytes;
							}*/
							
							/*
							image_data_array[] = byte [image_size]
							10
							image_data_array 0 1 2......5 6 7 8 9 
							
							'e','n','d','\0'
							
							*
							*/
//							判断穿过来的数组是否是图片,是图片的标志是数组以 'e','n','d','\0' 结尾
							if((image_data_array[image_size-4]==end[0])&&(image_data_array[image_size-3]==end[1])
									&&(image_data_array[image_size-2]==end[2])&&(image_data_array[image_size-1]==end[3]))
							{
								
//								将image_data_array 从0 到倒数第五个放到imagestream中
							imagestream.write(image_data_array, 0, (image_data_array.length-4 )); //把图片数据写到数据流中进行包装,防止乱码
//							将imagestream的数据放到final_image_data_buf 数组中
							final_image_data_buf=imagestream.toByteArray();  
							//Log.d(DEBUG_TAG, "final image data array未越界");  
							imagestream.flush(); 
							imagestream.close(); 
							 
							//第四步,显示图片 
//							将数组转化成图片 mbitmap
						 	final Bitmap mbitmap=BitmapFactory.decodeByteArray(final_image_data_buf, 0, final_image_data_buf.length);
							
							MonitorVideoActivity.this.runOnUiThread(new Runnable(){ //刷新了整个activity 更新UI
								@Override 
								public void run(){
									mimageview.setImageBitmap(mbitmap);     
									mimageview.refreshDrawableState(); 
								}
							});   
						
							}
							
							image_data_array=null; 
							final_image_data_buf=null;   
						  	System.gc();   
						} 
//						 线程休息500ms 然后唤醒
						Thread.sleep(100);   //500ms刷新一次图像线程    
						Thread.yield();      
					}     
				} 
			}  
			catch (Exception e)   
			{
			
				Log.e(DEBUG_TAG,e.toString());
				
			} 
			finally 
			{
				try{
				if(exit_var){
					Log.d(DEBUG_TAG, "socket未关闭");    
					image_out.close();
					image_in.close();
					ctrl_out.close();
					ctrl_socket.close();       //退出时先关socket  
					image_socket.close();
					Log.d(DEBUG_TAG, "socket已关闭");
					//MonitorVideoActivity.this.finish();
					return;                    //跳出run方法,结束线程     
					
				}   
				}
				catch (Exception e)  
				{
					Log.e(DEBUG_TAG,e.toString()); 
				}
			}
		}
	}
	
	
	
	
	
	
	public void send_btn_message(){  
		try{
		switch (button_fig){
		case 1:  
//			通过DataOutputStream 这个管道 将 “1”传送出去
			ctrl_out.writeByte(1);  
//			flush 确保他完全传送 强制传送一次
			ctrl_out.flush();
			break;
		case 2:
			ctrl_out.writeByte(2);
			ctrl_out.flush(); 
			break;
		case 3:
			ctrl_out.writeByte(3);
			ctrl_out.flush();
			break;
		case 4: 
			ctrl_out.writeByte(4); 
			ctrl_out.flush();
			break;
		case 5:
			ctrl_out.writeByte(5); 
			ctrl_out.flush();
			break;
		}
		} 
		catch(Exception e)
		{
			Log.e(DEBUG_TAG,e.toString()); 
		} 
			
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.monitor_video, menu);
		return true;  
	}

}


An7_0
浏览 1396回答 0
0回答
随时随地看视频慕课网APP

相关分类

Android
Java
我要回答