在好例子网,分享、交流、成长!
您当前所在位置:首页Java 开发实例Android平台开发 → Android手机间的实时传输视频

Android手机间的实时传输视频

Android平台开发

下载此实例
  • 开发语言:Java
  • 实例大小:1.77M
  • 下载次数:38
  • 浏览次数:338
  • 发布时间:2019-05-31
  • 实例类别:Android平台开发
  • 发 布 人:crazycode
  • 文件格式:.rar
  • 所需积分:2
 相关标签: Android 视频传输

实例介绍

【实例简介】

【实例截图】

from clipboard

【核心代码】

package com.nercms.send;

/*import java.io.File;*/
import java.io.IOException;
/*import java.io.RandomAccessFile;*/
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;

import org.sipdroid.net.RtpPacket;
import org.sipdroid.net.RtpSocket;
import org.sipdroid.net.SipdroidSocket;

import android.app.Activity;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class Send extends Activity 
{
	//包含库文件
	static 
	{
		System.loadLibrary("VideoEncoder");
	}
	
	//接口函数
	private native long CreateEncoder(int width,int height); //底层创建编码器,返回编码器
	//编码一帧图像,返回包的数目
	//type=编码帧的类型,frame=原始yuv图像,stream=原始图像码流,packetSize=包的尺寸
	private native int EncoderOneFrame(long encoder, int type, byte[] frame, byte[] stream, int[] packetSize);
	private native int DestroyEncoder(long encoder); //销毁编码器,释放资源
	
	private long encoder = -1; //创建编码器的句柄
	private int [] packetSize = new int[200]; //包的尺寸
	private byte[] stream = new byte[65536]; //码流
	private int packetNum=0; //包的数目
	
	private Camera mCamera = null; //创建摄像头处理类
	private SurfaceHolder holder = null; //创建界面句柄,显示视频的窗口句柄
	
	private RtpSocket rtp_socket = null; //创建RTP套接字 
	private RtpPacket rtp_packet = null; //创建RTP包
	private byte[] socketBuffer =new byte[65536]; //缓存 stream->socketBuffer->rtp_socket
	
	/*private RandomAccessFile raf=null;*/
	
	//建立回调的类
	class Callback implements Camera.PreviewCallback
	{
		@Override
		public void onPreviewFrame(byte[] frame, Camera camera) 
		{
			if (encoder != -1)
			{
				//底层函数,返回包的数目,返回包的大小存储在数组packetSize中,返回码流在stream中
				packetNum = EncoderOneFrame( encoder,-1,frame, stream, packetSize); 
				if(packetNum>0)
				{
					
					//通过RTP协议发送帧
					int pos = 0; //从码流头部开始取
					long timestamp = System.currentTimeMillis(); //设定时间戳
					int sequence = 0; //初始化序列号
					for (int i=0;i<packetNum;i  )
					{
						rtp_packet.setPayloadType(2);//定义负载类型,视频为2
						rtp_packet.setMarker(i==packetNum-1?true:false); //是否是最后一个RTP包
						rtp_packet.setSequenceNumber(sequence  ); //序列号依次加1
						rtp_packet.setTimestamp(timestamp); //时间戳
						rtp_packet.setPayloadLength(packetSize[i]); //包的长度,packetSize[i] 头文件
						//从码流stream的pos处开始复制,从socketBuffer的第12个字节开始粘贴,packetSize为粘贴的长度
						System.arraycopy(stream, pos, socketBuffer, 12, packetSize[i]); //把一个包存在socketBuffer中
						pos =packetSize[i]; //重定义下次开始复制的位置
						//rtp_packet.setPayload(socketBuffer, rtp_packet.getLength());
						try 
						{
							rtp_socket.send(rtp_packet);
						} 
						catch (IOException e)
						{
							e.printStackTrace();
						}
					}
				}
			}
		}
	}
	
	
	public void close()
	{
		/*if(null != raf)
    	{
    		try 
    		{
				raf.close();
			} catch (IOException e) {
			
				e.printStackTrace();
			}
			raf =null;
    	}*/
		
		//释放摄像头资源
		if (mCamera != null)
    	{
			mCamera.stopPreview(); //停止预览
			mCamera.setPreviewCallback(null); //停止回调函数
			mCamera.release(); //释放资源
    		mCamera = null; //重新初始化
    	}
		
		//释放编码器资源
		if(encoder != -1) 
		{
			DestroyEncoder(encoder); //底层函数,销毁编码器
			encoder = -1; //重新初始化
		}
		
		//释放rtp资源
		if (rtp_socket != null)
    	{
    		rtp_socket.close();
    		rtp_socket = null; //重新初始化
    	}
	}
	
	private TextView tvMsg;
	private EditText txtIP, txtPort;
	private Button btnSend,btnStop;
	
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        tvMsg = (TextView)findViewById(R.id.tvMsg);
        
		txtIP = (EditText)findViewById(R.id.txtIP);
		txtPort = (EditText)findViewById(R.id.txtPort);
		tvMsg.setText("本机IP:"   GetIpAddress()   " 监听端口:"   txtPort.getText().toString());
		btnSend = (Button)findViewById(R.id.btnSend);
		btnStop = (Button)findViewById(R.id.btnStop);
		btnSend.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) {
				if (encoder == -1) 
					encoder=CreateEncoder(352,288); //调用底层函数,创建编码器
				if (rtp_socket == null)
	        	{
					try 
					{
						//RTP在1025到65535之间选择一个未使用的偶数端口号,而在同一次会话中的RTCP则使用下一个奇数
						//20000为接收端口号,1234发送端口号?
						//设定套接字
						rtp_socket = new RtpSocket(new SipdroidSocket(1234),InetAddress.getByName(txtIP.getText().toString()),Integer.parseInt(txtPort.getText().toString()));
					} 
					catch (SocketException e)
					{
						e.printStackTrace();
					} 
					catch (UnknownHostException e) 
					{
						e.printStackTrace();
					}
	        		rtp_packet = new RtpPacket(socketBuffer,0); //初始化 ,socketBuffer改变时rtp_Packet也跟着改变
	        	}
				if(mCamera == null)
				{
					
					//摄像头设置,预览视频
					mCamera = Camera.open(); //实例化摄像头类对象
					Camera.Parameters p = mCamera.getParameters(); //将摄像头参数传入p中
					p.setPreviewFormat(PixelFormat.YCbCr_420_SP); //设置预览视频的格式
	        		p.setPreviewSize(352,288); //设置预览视频的尺寸,CIF格式352×288
	        		p.setPreviewFrameRate(15); //设置预览的帧率,15帧/秒
	        		mCamera.setParameters(p); //设置参数
	        		mCamera.setDisplayOrientation(90); //视频旋转90度
	        		try 
	        		{
						mCamera.setPreviewDisplay(holder); //预览的视频显示到指定窗口
					}
	        		catch (IOException e)
	        		{
						e.printStackTrace();
					}
	        		mCamera.startPreview(); //开始预览
	        		
	        		//获取帧
	        		//预览的回调函数在开始预览的时候以中断方式被调用,每秒调用15次,回调函数在预览的同时调出正在播放的帧
	        		Callback a=new Callback();
	        		mCamera.setPreviewCallback(a); 
				}
			}
		});
		btnStop.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View v) {
				close();	
				finish(); //退回初始界面		
			}
		});
        
        SurfaceView mSurfaceView = (SurfaceView) this.findViewById(R.id.camera_preview);
        holder = mSurfaceView.getHolder();
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }
    
    @Override
    public void finalize() //在退出界面的时候自动调用
    {
    	try 
    	{
			super.finalize();
		}
    	catch (Throwable e) 
    	{
			e.printStackTrace();
		}
    	close();
    }
    public String GetIpAddress() {     
	    WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);     
	    WifiInfo wifiInfo = wifiManager.getConnectionInfo();     
	    int i = wifiInfo.getIpAddress();
	    return (i & 0xFF)   "."       
	    	   ((i >> 8 ) & 0xFF)   "."       
	    	   ((i >> 16 ) & 0xFF)  "."       
	           ((i >> 24 ) & 0xFF );     
	}    
}

标签: Android 视频传输

实例下载地址

Android手机间的实时传输视频

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警