找传奇、传世资源到传世资源站!

Android手机间的实时传输视频

8.5玩家评分(1人评分)
下载后可评
介绍 评论 失效链接反馈

from clipboardpackage 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{@Overridepublic 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);//定义负载类型,视频为2rtp_packet.setMarker(i==packetNum-1?true:false); //是否是最后一个RTP包rtp_packet.setSequenceNumber(sequence ); //序列号依次加1rtp_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(){@Overridepublic 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(){@Overridepublic 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 ); } }

评论

发表评论必须先登陆, 您可以 登陆 或者 注册新账号 !


在线咨询: 问题反馈
客服QQ:174666394

有问题请留言,看到后及时答复