实例介绍
【实例简介】
【实例截图】
【核心代码】
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 ); } }
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论