实例介绍
【实例简介】
【实例截图】
【核心代码】
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小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论